AngoraFuzzer / Angora

Angora is a mutation-based fuzzer. The main goal of Angora is to increase branch coverage by solving path constraints without symbolic execution.
Apache License 2.0
916 stars 166 forks source link

ASAN support for "fast variant" of the target #26

Closed neuracr closed 5 years ago

neuracr commented 5 years ago

Hi, Thanks for releasing your code. Does angora-clang support address sanitizer ?
I tried to build the 'FAST version' of a test program with the ANGORA_USE_ASAN=1 variable set (and the TRACK version without ASAN since it seems not recommended to mix dfsan and asan). The "fast" is running properly when I execute it manually, but it makes angora-fuzz to hang:
Compiling TRACK variant USE_TRACK=1 /home/user/sources/Angora/bin/angora-clang test.c -o test.track
Compiling FAST variant with ASAN
ANGORA_USE_ASAN=1 USE_FAST=1 /home/user/sources/Angora/bin/angora-clang test.c -o test.fast.asan
And when fuzzing:

$ ../Angora/angora_fuzzer -M none -i in -o out2 -t ./test.track -- ./test.fast.asan @@
 INFO  angora::fuzz_main > depot: DepotDir { inputs_dir: "out2/queue", hangs_dir: "out2/hangs", crashes_dir: "out2/crashes", seeds_dir: "in" }
 INFO  angora::fuzz_main > CommandOpt { id: 0, main: ("./test.fast.asan", ["@@"]), track: ("./test.track", ["@@"]), tmp_dir: "out2/tmp", out_file: "out2/tmp/cur_input", forksrv_socket_path: "out2/tmp/forksrv_socket", track_path: "out2/tmp/track", is_stdin: false, search_method: Gd, mem_limit: 200, time_limit: 1, is_raw: true, ld_library: "$LD_LIBRARY_PATH:/opt/llvm-4.0/lib", enable_afl: true, enable_exploitation: true }

hang and even ctrl-C does not kill the process.

When testing manually the binary for a bug, there's no problem:

user@machine:~/sources/angora_test$ ./test.fast.asan out/queue/id\:000004
=================================================================
==26459==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffbe17ef21 at pc 0x55b285ef3345 bp 0x7fffbe17eaf0 sp 0x7fffbe17eae8
WRITE of size 1 at 0x7fffbe17ef21 thread T0
    #0 0x55b285ef3344 in main /home/user/sources/angora_test/test.c:23:18
    #1 0x7f8a322d2b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #2 0x55b285e21869 in _start (/home/user/sources/angora_test/test.fast.asan+0x20869)

Address 0x7fffbe17ef21 is located in stack of thread T0 at offset 1057 in frame
    #0 0x55b285ef2a2f in main /home/user/sources/angora_test/test.c:4

  This frame has 1 object(s):
    [32, 1056) 'content' <== Memory access at offset 1057 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/user/sources/angora_test/test.c:23:18 in main
Shadow bytes around the buggy address:
  0x100077c27d90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077c27da0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077c27db0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077c27dc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077c27dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100077c27de0: 00 00 00 00[f3]f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3
  0x100077c27df0: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077c27e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077c27e10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077c27e20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077c27e30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==26459==ABORTING
spinpx commented 5 years ago

Try

 $ ../Angora/angora_fuzzer -M 0 -i in -o out2 -t ./test.track -- ./test.fast.asan @@

Angora does not support the keywork "none" for memory limitation, so the option parsing fails. The memory limitation still is 200MB in your setting.

 INFO  angora::fuzz_main > CommandOpt { id: 0, main: ("./test.fast.asan", ["@@"]), track: ("./test.track", ["@@"]), tmp_dir: "out2/tmp", out_file: "out2/tmp/cur_input", forksrv_socket_path: "out2/tmp/forksrv_socket", track_path: "out2/tmp/track", is_stdin: false, search_method: Gd, mem_limit: 200, time_limit: 1, is_raw: true, ld_library: "$LD_LIBRARY_PATH:/opt/llvm-4.0/lib", enable_afl: true, enable_exploitation: true }
neuracr commented 5 years ago

Thanks, that worked. But still, the angora-fuzz does not detect the crash. The fuzzer "solves" all the possible paths in my test program including the one that triggers the buffer overflow but it puts it in the queue directory and it does not increase the crash counter. When I replay the sample in the queue, I get the crash and asan report.

Here is the (dummy) test program I use:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]){
    char content[1024];
    if (argc < 2){
        printf("usage: test input_sample\n");
        return -1;
    }
    FILE *file = fopen(argv[1], "r");
    size_t n_read = fread(content, 1, 1024, file);
    if (n_read < 1000){
        printf("sample too short\n");
        fclose(file);
        return -1;
    }
    if (content[0] == 'h' && content[1] == 'e'){
        if (content[2] >75){
            if (content[3] < 80)
                printf("well done!");
        }
        else if(content[2] == 74){
            //triggers a crash          
            *(content+1025*sizeof(char)) = 'r';
        }
    }
    fclose(file);
    return 0;
}
spinpx commented 5 years ago

If you want to set your own options, be sure to include abort_on_error=1 - otherwise, the fuzzer will not be able to detect crashes in the tested app. Similarly, include symbolize=0, since without it, AFL may have difficulty telling crashes and hangs apart.

https://github.com/mirrorer/afl/blob/master/docs/env_variables.txt

I will add these to Angora soon

spinpx commented 5 years ago

Done, please check https://github.com/AngoraFuzzer/Angora/commit/4e6f4cf36087ba77760229976262bdf9980f1c99

Thanks.

neuracr commented 5 years ago

It works. Thanks!