Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tfuzz did not consider cannot-renamed programs #14

Open
zjuchenyuan opened this issue May 7, 2019 · 4 comments
Open

tfuzz did not consider cannot-renamed programs #14

zjuchenyuan opened this issue May 7, 2019 · 4 comments

Comments

@zjuchenyuan
Copy link

There is a type of programs whose behaviour depend to which name they are. busybox is a good example, only one file is real ELF file and others are just symlink to it.

In this scenario, it's important for fuzzer to keep the original ELF filename, otherwise desired program behaviour will not be triggered and fuzzed.

I want to fuzz infotocap, which is a symlink to tic

But tfuzz actually runs: (which means it has been renamed to infotocap_tfuzz)

 /usr/bin/afl-unix/afl-fuzz -i /d/output/reruninfotocap_tfuzz6_1/fuzzing_infotocap_tfuzz/infotocap_tfuzz/input -o /d/output/reruninfotocap_tfuzz6_1/fuzzing_infotocap_tfuzz/infotocap_tfuzz/sync -m 8G -M fuzzer-master -x /d/output/reruninfotocap_tfuzz6_1/infotocap.dict -- /d/output/reruninfotocap_tfuzz6_1/infotocap_tfuzz/infotocap_tfuzz -o /dev/null @@

Could you consider this type of program? Thanks~

@gannimo
Copy link
Member

gannimo commented May 7, 2019

When preparing the fuzzing environment, why don't you rename the binary to tic, solving the problem by setting up the environment instead of changing tfuzz?

(Changing tfuzz to observe and keep the filename is somewhat harder, it would be easier to simply rename the binaries during setup. Another option is to fudge the arguments as they are passed to main).

Let me know if any of these work for you.

@benquike
Copy link
Collaborator

benquike commented May 7, 2019

@zjuchenyuan let me clarify a little bit.
So your problem is that the target program you are running is a symbolic link to another file.
When T-Fuzz generates modified (transformed) program, it does not handle symbolic links properly and only handles the link file, not the target file the link file points to.

Am I correct? If yes, the quick way to solve it is to use the target binary directly during fuzzing.

@zjuchenyuan
Copy link
Author

zjuchenyuan commented May 21, 2019

Thanks for your reply, let me clarify the problem. @gannimo @benquike

The target program need to be named as infotocap exactly, and cannot be changed during the fuzzing process.

The behaviour of this program depends to what the name is it, different name leads to different behaviour:

# echo "123456">/tmp/a.txt
# cp infotocap x
# cp infotocap tic
# ./infotocap /tmp/a.txt
123456:\
        :bl=^G:cr=\r:do=\n:kb=^H:kd=\n:kl=^H:nw=\r\n:sf=\n:ta=^I:
# ./tic /tmp/a.txt
# ./x /tmp/a.txt

I want to fuzz infotocap, and compiled the tic ELF binary, and renamed it to infotocap, no symlink is involved here.

I want fuzzer to keep the original ELF name rather than renaming it before fuzzing.


More detailed strace output: infotocap just read the file, but tic write an output file.

# strace ./infotocap /tmp/a.txt
execve("./infotocap", ["./infotocap", "/tmp/a.txt"], 0x7fffffffe638 /* 21 vars */) = 0
brk(NULL)                               = 0x712000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=42733, ...}) = 0
mmap(NULL, 42733, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fec000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fea000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff79e4000
mprotect(0x7ffff7bcb000, 2097152, PROT_NONE) = 0
mmap(0x7ffff7dcb000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7ffff7dcb000
mmap(0x7ffff7dd1000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff7dd1000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7feb540) = 0
mprotect(0x7ffff7dcb000, 16384, PROT_READ) = 0
mprotect(0x70f000, 4096, PROT_READ)     = 0
mprotect(0x7ffff7ffc000, 4096, PROT_READ) = 0
munmap(0x7ffff7fec000, 42733)           = 0
stat("/tmp/a.txt", {st_mode=S_IFREG|0644, st_size=7, ...}) = 0
brk(NULL)                               = 0x712000
brk(0x733000)                           = 0x733000
openat(AT_FDCWD, "/tmp/a.txt", O_RDONLY) = 3
lseek(3, 0, SEEK_CUR)                   = 0
lseek(3, 0, SEEK_CUR)                   = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=7, ...}) = 0
read(3, "123456\n", 4096)               = 7
lseek(3, 0, SEEK_CUR)                   = 7
lseek(3, 0, SEEK_CUR)                   = 7
read(3, "", 4096)                       = 0
lseek(3, 0, SEEK_SET)                   = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
write(1, "123456:\\\n", 9123456:\
)              = 9
write(1, "\t:bl=^G:cr=\\r:do=\\n:kb=^H:kd=\\n:"..., 59  :bl=^G:cr=\r:do=\n:kb=^H:kd=\n:kl=^H:nw=\r\n:sf=\n:ta=^I:
) = 59
lseek(3, 0, SEEK_SET)                   = 0
read(3, "123456\n", 4096)               = 7
read(3, "", 4096)                       = 0
close(3)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
# strace ./tic /tmp/a.txt
execve("./tic", ["./tic", "/tmp/a.txt"], 0x7fffffffe638 /* 21 vars */) = 0
brk(NULL)                               = 0x712000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=42733, ...}) = 0
mmap(NULL, 42733, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fec000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fea000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff79e4000
mprotect(0x7ffff7bcb000, 2097152, PROT_NONE) = 0
mmap(0x7ffff7dcb000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7ffff7dcb000
mmap(0x7ffff7dd1000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff7dd1000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7feb540) = 0
mprotect(0x7ffff7dcb000, 16384, PROT_READ) = 0
mprotect(0x70f000, 4096, PROT_READ)     = 0
mprotect(0x7ffff7ffc000, 4096, PROT_READ) = 0
munmap(0x7ffff7fec000, 42733)           = 0
stat("/tmp/a.txt", {st_mode=S_IFREG|0644, st_size=7, ...}) = 0
brk(NULL)                               = 0x712000
brk(0x733000)                           = 0x733000
openat(AT_FDCWD, "/tmp/a.txt", O_RDONLY) = 3
lseek(3, 0, SEEK_CUR)                   = 0
lseek(3, 0, SEEK_CUR)                   = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=7, ...}) = 0
read(3, "123456\n", 4096)               = 7
lseek(3, 0, SEEK_CUR)                   = 7
lseek(3, 0, SEEK_CUR)                   = 7
read(3, "", 4096)                       = 0
stat("/d/prog/6infotocap.afl/bin/share/terminfo", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
access("/d/prog/6infotocap.afl/bin/share/terminfo", R_OK|W_OK|X_OK) = 0
chdir("/d/prog/6infotocap.afl/bin/share/terminfo") = 0
getcwd("/d/prog/6infotocap.afl/bin/share/terminfo", 4096) = 42
stat("1", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
access("1", R_OK|W_OK|X_OK)             = 0
access("1/123456", W_OK)                = 0
openat(AT_FDCWD, "1/123456", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
write(4, "\32\1\7\0\0\0\0\0\207\0\23\000123456\0\0\377\377\0\0\2\0\377\377\377\377\377\377"..., 309) = 309
close(4)                                = 0
stat("1/123456", {st_mode=S_IFREG|0644, st_size=309, ...}) = 0
close(3)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

@zjuchenyuan
Copy link
Author

zjuchenyuan commented May 21, 2019

I would suggest change this 2 lines:

original_tprogram_path = os.path.join(original_tprogram_dir,
self.origin_binary_name + '_tfuzz')

change to:

        original_tprogram_path = os.path.join(original_tprogram_dir,
                                              self.origin_binary_name)

transformed_program_path = os.path.join(transformed_program_dir, transformed_program_name)

change to:

transformed_program_path = os.path.join(transformed_program_dir, self.origin_binary_name) 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants