AFLplusplus / Grammar-Mutator

A grammar-based custom mutator for AFL++
Apache License 2.0
215 stars 18 forks source link

Segmentation fault when dealing with hex-ANSII conversion #37

Closed xuesong-bai closed 2 years ago

xuesong-bai commented 2 years ago

Hi, I run into some problems when trying to generate a hex corpus and use that in a fuzz.

The version I use is AFL++ 4.01a release version and the latest of Grammar-Mutator in the stable branch. The fuzz target is compiled using afl-gcc-fast.

I'm trying to generate seeds based on the grammar shown below, following the solution in issue #29.

{
    "<start>": [["hex: ", "<hex>", "<hex2>"]],
    "<hex>": [["\u0087"], ["\u005a"]], 
    "<hex2>":[["\u0000"], ["\u0001"], ["\u0002"], ["\u0003"], ["\u0004"], ["\u0005"], ["\u0006"], ["\u0007"],
              ["\u0008"], ["\u0009"], ["\u000a"], ["\u000b"], ["\u000c"], ["\u000d"], ["\u000e"], ["\u000f"],
              ["\u0010"], ["\u0011"], ["\u0012"], ["\u0013"], ["\u0014"], ["\u0015"], ["\u0016"], ["\u0017"],
              ["\u0018"], ["\u0019"], ["\u001a"], ["\u001b"], ["\u001c"], ["\u001d"], ["\u001e"], ["\u001f"]]
}

I can successfully build the grammar mutator without any error.

Seeds can be generated using the grammar generator. I tested a few of them and they seem to be what I expected.

But when running afl-fuzz for the target, it will cause a segmentation fault before going into the fuzzing interface.

[*] Attempting dry run with 'id:000099,time:0,execs:0,orig:0'...
    len = 7, map size = 172, exec speed = 25 us
[!] WARNING: No new instrumentation output, test case may be useless.
[+] All test cases processed.
[!] WARNING: Some test cases look useless. Consider using a smaller set.
[!] WARNING: You have lots of input files; try starting small.
[+] Here are some useful stats:

    Test case count : 1 favored, 1 variable, 98 ignored, 100 total
       Bitmap range : 172 to 172 bits (average: 172.00 bits)
        Exec timing : 31 to 112 us (average: 28 us)

[*] No -t option specified, so I'll use an exec timeout of 20 ms.
[+] All set and ready to roll!
Segmentation fault

When I replaced "<hex>": [["\u0087"], ["\u005a"]], with "": [["\u001f"], ["\u001f"]] (some smaller numbers) in the grammar, the fuzzer is working fine.

Can someone help me with this problem? Any help is much appreciated.

Let me know if any other information is needed.

h1994st commented 2 years ago

Any backtraces for the segmentation fault? You can obtain the backtrace in GDB.

I can take a look at this issue later this week.

xuesong-bai commented 2 years ago

The backtrace in GDB is shown below.

(gdb) run            
Starting program: /usr/local/bin/afl-fuzz -m 1000 -i ./seeds/ -o out ./test_message_parse
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so1".
[+] Loaded environment variable AFL_CUSTOM_MUTATOR_ONLY with value 1
[+] Loaded environment variable AFL_SKIP_CPUFREQ with value 1
[+] Loaded environment variable AFL_CUSTOM_MUTATOR_LIBRARY with value /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
[+] Loaded environment variable AFL_NO_AFFINITY with value 1 
afl-fuzz++4.01a based on afl by Michal Zalewski and a large online community  
[+] afl++ is maintained by Marc "van Hauser" Heuse, Heiko "hexcoder" Eißfeldt, Andrea Fioraldi and Dominik Maier
[+] afl++ is open source, get it at https://github.com/AFLplusplus/AFLplusplus      
[+] NOTE: This is v3.x which changes defaults and behaviours - see README.md
[+] No -M/-S set, autoconfiguring for "-S default"
[*] Getting to work...
[+] Using exponential power schedule (FAST)
[+] Enabled testcache with 50 MB
[+] Generating fuzz data with a a length of min=1 max=1048576    
[*] Checking core_pattern...                     
[+] You have 32 CPU cores and 8 runnable tasks (utilization: 25%).    
[+] Try parallel jobs - see /usr/local/share/doc/afl/parallel_fuzzing.md.      
[*] Setting up output directories...                                           
[+] Output directory exists but deemed OK to reuse.                            
[*] Deleting old session data...                                               
[+] Output dir cleanup successful.                                             
[!] WARNING: Not binding to a CPU core (AFL_NO_AFFINITY set).                  
[*] Loading custom mutator library from '/home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so'...                                
[*] optional symbol 'afl_custom_post_process' not found.                       
[*] optional symbol 'afl_custom_havoc_mutation' not found.                     
[*] optional symbol 'afl_custom_havoc_mutation_probability' not found.         
[*] Symbol 'afl_custom_describe' not found.                                    
[+] Custom mutator '/home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so' installed successfully.                                
[*] Scanning './seeds/'...                                                     
[+] Loaded a total of 100 seeds.                                               
[*] Creating hard links for all input files...                                 
[*] Validating target binary...                                                
[+] Persistent mode binary detected.                                           
[*] Spinning up the fork server...                                             
[Detaching after fork from child process 3670243]                              
[+] All right - fork server is up.                                             
[*] Target map size: 65536                                                     
[*] No auto-generated dictionary tokens to reuse.                              
[*] Attempting dry run with 'id:000000,time:0,execs:0,orig:99'...              
[!] WARNING: instability detected during calibration                           
    len = 7, map size = 172, exec speed = 113 us                               
[!] WARNING: Instrumentation output varies across runs.                        
[*] Attempting dry run with 'id:000001,time:0,execs:0,orig:98'...              
    len = 7, map size = 172, exec speed = 26 us                                
[!] WARNING: No new instrumentation output, test case may be useless.          
[*] Attempting dry run with 'id:000002,time:0,execs:0,orig:97'...              
    len = 7, map size = 172, exec speed = 25 us                                
[!] WARNING: No new instrumentation output, test case may be useless.
[*] Attempting dry run with 'id:000099,time:0,execs:0,orig:0'...
    len = 7, map size = 172, exec speed = 25 us
[!] WARNING: No new instrumentation output, test case may be useless.
[+] All test cases processed.
[!] WARNING: Some test cases look useless. Consider using a smaller set.
[!] WARNING: You have lots of input files; try starting small.
[+] Here are some useful stats:

    Test case count : 1 favored, 1 variable, 98 ignored, 100 total
       Bitmap range : 172 to 172 bits (average: 172.00 bits)
        Exec timing : 26 to 113 us (average: 28 us)

[*] No -t option specified, so I'll use an exec timeout of 20 ms.
[+] All set and ready to roll!

Program received signal SIGSEGV, Segmentation fault.
__memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:384
384     ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
(gdb) 
h1994st commented 2 years ago

Hi, can you type bt in the last line you showed to obtain the complete backtrace?

xuesong-bai commented 2 years ago

Thank you for your patience.

(gdb) bt
#0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:384
#1  0x00007fffeec9c4be in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#2  0x00007fffeec9c524 in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#3  0x00007fffeec9c524 in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#4  0x00007fffeec9c524 in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#5  0x00007fffeec9c524 in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#6  0x00007fffeec9a78a in gen_node_start () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#7  0x00007fffeec9d106 in subtree_trimming () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#8  0x00007fffeec9ad5c in afl_custom_trim () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#9  0x000055555556a644 in trim_case_custom (mutator=0x5555555de9a0, in_buf=0x55555560cf60 "hex: Z", q=<optimized out>, 
    afl=0x7ffff7559010) at src/afl-fuzz-mutators.c:393
#10 trim_case (afl=0x7ffff7559010, q=0x555555607ee0, in_buf=0x55555560cf60 "hex: Z") at src/afl-fuzz-run.c:795
#11 0x0000555555589637 in fuzz_one_original (afl=0x7ffff7559010) at src/afl-fuzz-one.c:509
#12 0x000055555555fcd0 in fuzz_one (afl=<optimized out>) at src/afl-fuzz-one.c:5583
#13 main (argc=<optimized out>, argv_orig=<optimized out>, envp=<optimized out>) at src/afl-fuzz.c:2455
domenukk commented 2 years ago

The backtrace would ideally include the locations where this was called from. Try to type bt In gdb

xuesong-bai commented 2 years ago

Thank you for your patience.

(gdb) bt
#0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:384
#1  0x00007fffeec9c4be in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#2  0x00007fffeec9c524 in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#3  0x00007fffeec9c524 in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#4  0x00007fffeec9c524 in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#5  0x00007fffeec9c524 in _node_deserialize () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#6  0x00007fffeec9a78a in gen_node_start () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#7  0x00007fffeec9d106 in subtree_trimming () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#8  0x00007fffeec9ad5c in afl_custom_trim () from /home/test/proj2/Grammar-Mutator/libgrammarmutator-test.so
#9  0x000055555556a644 in trim_case_custom (mutator=0x5555555de9a0, in_buf=0x55555560cf60 "hex: Z", q=<optimized out>, 
    afl=0x7ffff7559010) at src/afl-fuzz-mutators.c:393
#10 trim_case (afl=0x7ffff7559010, q=0x555555607ee0, in_buf=0x55555560cf60 "hex: Z") at src/afl-fuzz-run.c:795
#11 0x0000555555589637 in fuzz_one_original (afl=0x7ffff7559010) at src/afl-fuzz-one.c:509
#12 0x000055555555fcd0 in fuzz_one (afl=<optimized out>) at src/afl-fuzz-one.c:5583
#13 main (argc=<optimized out>, argv_orig=<optimized out>, envp=<optimized out>) at src/afl-fuzz.c:2455

Is this what you are looking for? @domenukk

domenukk commented 2 years ago

Thank you! :) Sorry didn't see your response.

h1994st commented 2 years ago

Hi @mrbaixg ,

This issue is caused by the limitation of the hex character workaround, which is discussed in https://github.com/AFLplusplus/Grammar-Mutator/issues/29.

However, the workaround only works for single-byte characters in the UTF-8 encoding (i.e., \u0000 \~ \u007f). \u0087 is out of the scope and is converted into 2 bytes (i.e., \xc2\x87) in the UTF-8 encoding. A minimal example for the wrong grammar file is added in c34493d5c2ce3268fea40a43e1abbb7ce179b9dd

For now, you may only use hex characters within \u0000 \~ \u007f, until I can figure out a better solution for it.

h1994st commented 2 years ago

Hi @mrbaixg ,

Please try the latest commit ff4e5a265daf5d88c4a636fb6a2c22b1d733db09. It should address your problem.

h1994st commented 2 years ago

I will close this issue, which should be resolved by the latest commit ff4e5a265daf5d88c4a636fb6a2c22b1d733db09.

@mrbaixg Please let me know if the latest commit works. Feel free to reopen this issue, if it is not resolved.

xuesong-bai commented 2 years ago

The commit ff4e5a2 seems working for me.

But I encountered a new situation where the program will be stuck in the initialization process right before entering the AFL fuzzing interface. This happens occasionally while I'm using the same configuration.

I will try to find out what's wrong and let you know the result.

h1994st commented 2 years ago

The stuck at the initialization phase may be expected (see README.md), if the parsing functionality is triggered. To avoid parsing at the initialization phase, you may want to refer to README.md and https://github.com/AFLplusplus/Grammar-Mutator/issues/36#issuecomment-1069695313

Please let me know if the stuck is caused by other reasons.