IntelLabs / kAFL

A fuzzer for full VM kernel/driver targets
https://intellabs.github.io/kAFL/
MIT License
639 stars 85 forks source link

Redqueen doesn't handle strcmp() calls on linux userspace target #212

Open Wenzel opened 1 year ago

Wenzel commented 1 year ago
          Greetings!

I reach some troubles with redqueen feature: it doesn't handle strcmp() calls on linux userspace target.

Launch command:

kafl fuzz \
        --kernel /boot/vmlinuz-$(uname -r) \
        --initrd forkserver.cpio.gz \
        --memory 512 \
        --sharedir $PWD \
        --purge -t 2 -ts 1 --log-hprintf --log-crashes \
        --append "nokaslr oops=panic nopti mitigations=off console=ttyS0 hprintf=7" \
        -ip0 0x401000-0x4af000 \
        --redqueen --redqueen-hammer --redqueen-simple --redqueen-hashes --grimoire --radamsa \
        -p 1 --qemu-path /usr/src/QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64

Some debugging of qemu-nyx approve, that redqueen strcmp() hooks are reached and works as expected, or, at least, see strcmp() calls is target and could access guest args.

The target, as always, is simple, statically built, small harness with several branches to test integers and strings extractions.

In file: /usr/src/QEMU-Nyx/nyx/redqueen.c
   948 static void format_strcmp(uint8_t *buf1, uint8_t *buf2)
   949 {
   950     char  out_buf[REDQUEEN_MAX_STRCMP_LEN * 4 + 2];
   951     char *tmp_hex_buf = &out_buf[0];
   952     for (int i = 0; i < REDQUEEN_MAX_STRCMP_LEN; i++) {
 ► 953         tmp_hex_buf += sprintf(tmp_hex_buf, "%02X", (uint8_t)buf1[i]);
   954     }
   955     *tmp_hex_buf++ = '-';
   956     for (int i = 0; i < REDQUEEN_MAX_STRCMP_LEN; i++) {
   957         tmp_hex_buf += sprintf(tmp_hex_buf, "%02X", (uint8_t)buf2[i]);
   958     }

pwndbg> p tmp_hex_buf 
$5 = 0x7fffeb000310 "C9"
pwndbg> p buf2
$6 = (uint8_t *) 0x7fffeb0004a0 "PWNED!!!"
pwndbg> p buf1
$7 = (uint8_t *) 0x7fffeb000460 "ɵ\032<\237b22\032\062\062\016\020g\022UUU"

full backtrace:

pwndbg> bt full
#0  0x0000555555c0f3a4 in format_strcmp (buf1=buf1@entry=0x7fffeb000460 "ɵ\032<\237b22\032\062\062\016\020g\022UUU", buf2=buf2@entry=0x7fffeb0004a0 "PWNED!!!") at /usr/src/QEMU-Nyx/nyx/redqueen.c:953
        i = <optimized out>
        out_buf = "C9\000\000\000\000\000\000 p\034\334\377\177\000\000\000\000\000\000\000\000\000\000@\244\210\004\000\000\000\000@s\311VUU\000\000\000\003홨\"\261\065`\003\000\353\377\177\000\000\b\000\000\000\000\000\000\000@\244\210\004\000\000\000\000\360\003\000\353\377\177\000\000h\376\377\377\377\377\377\377 p\034\334\377\177\000\000\016p\375\367\377\177\000\000S+\254UUU\000\000\b\000\000\000\000\000\000\000\260\"\265VUU\000\000\340\353\377\377\377\177\000\000\b\000\000\000\000\000\000\000@\244\210\004\000\000\000\000\000\003홨\"\261\065\357\200H", '\000' <repeats 13 times>, "\360\003\000\353\377\177\000\000\000\360\377\377\377\377\017\000\357\200H\000\000\000\000\000\210K\300UUU"...
        tmp_hex_buf = 0x7fffeb000310 "C9"
        res = 0x555555ac21c7 <flatview_read_continue+119> "L\001\365M\001\364L)\363\017\204Q\001"
        env = <optimized out>
        __func__ = "format_strcmp"
        rip = <optimized out>
        __PRETTY_FUNCTION__ = "format_strcmp"
#1  0x0000555555c0f948 in test_strcmp (arg1=140737136034976, arg1@entry=140737353969678, arg2=arg2@entry=4751599) at /usr/src/QEMU-Nyx/nyx/redqueen.c:1002
        cpu = 0x555556c97340
        buf1 = "ɵ\032<\237b22\032\062\062\016\020g\022UUU\000YXᆳ\300\000\000\000\357\276ޭ\276", '\363' <repeats 23 times>, "\255\336쭾\357\256", <incomplete sequence \374>
        buf2 = "PWNED!!!\000Something went wrong\n\000This should never happen :)\n\000xeon"
        __PRETTY_FUNCTION__ = "test_strcmp"
#2  0x0000555555c10024 in test_strcmp_sys_v () at /usr/src/QEMU-Nyx/nyx/redqueen.c:1035
        env = <optimized out>
        arg1 = 140737353969678
        arg2 = 4751599
        __func__ = "test_strcmp_sys_v"
        mode = 1
        cpu = <optimized out>
        env = <optimized out>
        insn = 0x7fffdc1e3d00
        ins_size = 5 '\005'
        ip = <optimized out>
        code = 4202854
        failed_page = 18446744073709551615
        __func__ = "handle_hook_breakpoint"
        __PRETTY_FUNCTION__ = "handle_hook_breakpoint"
#3  extract_call_params () at /usr/src/QEMU-Nyx/nyx/redqueen.c:1043
        mode = 1
        cpu = <optimized out>
        env = <optimized out>
        insn = 0x7fffdc1e3d00
        ins_size = 5 '\005'
        ip = <optimized out>
        code = 4202854
        failed_page = 18446744073709551615
        __func__ = "handle_hook_breakpoint"
        __PRETTY_FUNCTION__ = "handle_hook_breakpoint"
#4  handle_hook_redqueen_light (self=<optimized out>, ip=<optimized out>, insn=0x7fffdc1e3d00) at /usr/src/QEMU-Nyx/nyx/redqueen.c:1058
        mode = 1
        cpu = <optimized out>
        env = <optimized out>
        insn = 0x7fffdc1e3d00
        ins_size = 5 '\005'
        ip = <optimized out>
        code = 4202854
        failed_page = 18446744073709551615
        __func__ = "handle_hook_breakpoint"
        __PRETTY_FUNCTION__ = "handle_hook_breakpoint"
#5  handle_hook_breakpoint (self=<optimized out>, write_data=true) at /usr/src/QEMU-Nyx/nyx/redqueen.c:1105
        mode = 1
        cpu = <optimized out>
        env = <optimized out>
        insn = 0x7fffdc1e3d00
        ins_size = 5 '\005'
        ip = <optimized out>
        code = 4202854
        failed_page = 18446744073709551615
        __func__ = "handle_hook_breakpoint"
        __PRETTY_FUNCTION__ = "handle_hook_breakpoint"
#6  0x0000555555c1203c in handle_hook (self=0x555557a6a790) at /usr/src/QEMU-Nyx/nyx/redqueen.c:1142
        cpu = <optimized out>
        __func__ = "handle_hook"
        env = <optimized out>
#7  0x0000555555c1cef4 in handle_hypercall_kafl_hook (run=run@entry=0x7ffff7fc9000, cpu=cpu@entry=0x555556c97340, hypercall_arg=<optimized out>) at /usr/src/QEMU-Nyx/nyx/hypercall/hypercall.c:664
        i = <optimized out>
        cpux86 = <optimized out>
        __func__ = "handle_hypercall_kafl_hook"
        env = <optimized out>
#8  0x0000555555b3c737 in kvm_cpu_exec (cpu=cpu@entry=0x555556c97340) at /usr/src/QEMU-Nyx/accel/kvm/kvm-all.c:2682
        attrs = {
          unspecified = <optimized out>,
          secure = <optimized out>,
          user = <optimized out>,
          requester_id = <optimized out>,
          byte_swap = <optimized out>,
          target_tlb_bit0 = <optimized out>,
          target_tlb_bit1 = <optimized out>,
          target_tlb_bit2 = <optimized out>
        }
        run = <optimized out>
        ret = <optimized out>
        run_ret = <optimized out>
        timeout_reload_pending = false
        __PRETTY_FUNCTION__ = "kvm_cpu_exec"
        __func__ = "kvm_cpu_exec"
#9  0x0000555555b14b0c in qemu_kvm_cpu_thread_fn (arg=0x555556c97340) at /usr/src/QEMU-Nyx/cpus.c:1318
        r = <optimized out>
        cpu = 0x555556c97340
        r = <optimized out>
#10 qemu_kvm_cpu_thread_fn (arg=arg@entry=0x555556c97340) at /usr/src/QEMU-Nyx/cpus.c:1290
        cpu = 0x555556c97340
        r = <optimized out>
#11 0x0000555556054a73 in qemu_thread_start (args=0x7fffeb0006b0) at util/qemu-thread-posix.c:519
        __cancel_buf = {
          __cancel_jmp_buf = {{
              __cancel_jmp_buf = {0, -6175150794332906818, 140737488343454, 140737488343455, 140737136035840, 8396800, -65286209092396354, -6175151406121821506},
              __mask_was_saved = 0
            }},
          __pad = {0x7fffeb000750, 0x0, 0x0, 0x0}
        }
        __cancel_routine = 0x555556054ad0 <qemu_thread_atexit_notify>
        __not_first_call = <optimized out>
        start_routine = 0x555555b14a10 <qemu_kvm_cpu_thread_fn>
        arg = 0x555556c97340
        r = <optimized out>
#12 0x00007ffff6a24ea7 in start_thread (arg=<optimized out>) at pthread_create.c:477
        ret = <optimized out>
        pd = <optimized out>
        unwind_buf = {
          cancel_jmp_buf = {{
              jmp_buf = {140737136056064, 65258806425213630, 140737488343454, 140737488343455, 140737136035840, 8396800, -65286209098687810, -65243037933315394},
              mask_was_saved = 0
            }},
          priv = {
            pad = {0x0, 0x0, 0x0, 0x0},
            data = {
              prev = 0x0,
              cleanup = 0x0,
              canceltype = 0
            }
          }
        }
        not_first_call = 0
#13 0x00007ffff6944a2f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
pwndbg> 

But kafl doesn't insert findings to corpus.

---upd--- After some time fuzz session log next in stdout:

Worker-00 RQ-Dict: attempting b'PWNED!!!\x00Somethi'
Worker-00 RedQ-Dict: Have performed 0 iters
Received new input (exit=crash): b'!NYX\xef\xbe\xad\xde'ndings: <0, 0, 0>
00:02:58: Got    8 from    6: exit=C,  9/ 0 bits,  0 favs, 0.13msec, 0.0KB (afl_splice)
Worker-00 HAVOC times: afl: 6.0, splice: 14.7, grim: 0.0, rdmsa: 0.00, 0>

So, the magic string was found and successfully injected to input, the harness react by crashing, as expected, and kAFL log this. But not new path in corpus/regular neither correct (crashing) payloads in corpus/crashes are present.

(.venv) |root@w00t|:{/usr/src/kAFL/kafl/examples/linux-user/forkserver} #_ hexyl /dev/shm/kafl_root/corpus/crash/payload_00008 
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 21 4e 59 58 ef be ad de ┊                         │!NYX××××┊        │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
(.venv) |root@w00t|:{/usr/src/kAFL/kafl/examples/linux-user/forkserver} #_ hexyl /dev/shm/kafl_root/corpus/
crash/   kasan/   regular/ timeout/ 
(.venv) |root@w00t|:{/usr/src/kAFL/kafl/examples/linux-user/forkserver} #_ hexyl /dev/shm/kafl_root/corpus/regular/payload_0000
payload_00001  payload_00002  payload_00003  payload_00004  payload_00005  payload_00006  payload_00007  
(.venv) |root@w00t|:{/usr/src/kAFL/kafl/examples/linux-user/forkserver} #_ hexyl /dev/shm/kafl_root/corpus/regular/payload_00007 
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 21 4e 59 58 ef be ad de ┊                         │!NYX××××┊        │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘

Any advices? Thanks.

Originally posted by @kotee4ko in https://github.com/IntelLabs/kAFL/issues/12#issuecomment-1646964469

kotee4ko commented 1 year ago

---upd---

It seems, that if there are unused-bytes in payload data before place WHERE redq-dict C-string must be put -- kAFL can't save such testcase to corpus correct. In next harness between 0xdeadbeef constant and C-String "PWNED!!!" two unused bytes present.

  94   │     if (len >= 4) {
  95   │ 
  96   │       /* set a byte in the bitmap to guide your fuzzer */
  97   │       //((uint8_t *)trace_buffer)[0] = 0x1;
  98   │       if (payload_buffer->data[0] == '!') {
  99   │ 
 100   │         //((uint8_t *)trace_buffer)[1] = 0x1;
 101   │         if (payload_buffer->data[1] == 'N') {
 102   │ 
 103   │           //((uint8_t *)trace_buffer)[2] = 0x1;
 104   │           if (payload_buffer->data[2] == 'Y') {
 105   │ 
 106   │             //((uint8_t *)trace_buffer)[3] = 0x1;
 107   │             if (payload_buffer->data[3] == 'X') {
 108   │ 
 109   │               //((uint8_t *)trace_buffer)[4] = 0x1;
 110   │               /* Notifiy the hypervisor and the fuzzer that a "crash" has
 111   │                * occured. Also a string is passed by this hypercall (this is
 112   │                * currently not supported by AFL++-Nyx) */
 113   │               if (*(int*)&(payload_buffer->data[4]) == 0xdeadbeef) {
 114   │             if (!strcmp(&(payload_buffer->data[10]), "PWNED!!!")) {
 115   │             hprintf("PWNED\n");
 116   │             char *magic;
 117   │             magic = &(payload_buffer->data[20]);
 118   │             if (!memcmp(magic, "RedQueen", sizeof("RedQueen"))) {
 119   │                 void **crash = 0xdeadbeef;
 120   │                 *crash = 0xcafefeed;
 121   │                           kAFL_hypercall(HYPERCALL_KAFL_PANIC_EXTENDED,
 122   │                                  (uintptr_t) "Something went wrong\n");
 123   │             }
 124   │             }
 125   │               }
 126   │             }
 127   │ 
 128   │           }
 129   │ 
 130   │         }
 131   │ 
 132   │       }
 133   │ 
 134   │     }

Backend pass that code and increase edges count up to 59, but:

(.venv) |root@w00t|:{/usr/src/kAFL/kafl/examples/linux-user/forkserver} #_ hexyl /dev/shm/kafl_root/corpus/regular/payload_00007
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 21 4e 59 58 ef be ad de ┊                         │!NYX××××┊        │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘
(.venv) |root@w00t|:{/usr/src/kAFL/kafl/examples/linux-user/forkserver} #_ hexyl /dev/shm/kafl_root/corpus/regular/payload_00008
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 21 4e 59 58 ef be ad de ┊                         │!NYX××××┊        │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘

In case of next branches:

 113   │               if (*(int*)&(payload_buffer->data[4]) == 0xdeadbeef) {
 114   │             if (!strcmp(&(payload_buffer->data[8]), "PWNED!!!")) {

all works as expected

(.venv) |root@w00t|:{/usr/src/kAFL/kafl/examples/linux-user/forkserver} #_ hexyl /dev/shm/kafl_root/corpus/regular/payload_00008
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 21 4e 59 58 ef be ad de ┊ 50 57 4e 45 44 21 21 21 │!NYX××××┊PWNED!!!│
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘

I have some experience with AFL's cmplog backend stuff, in qemu userspace. But such sort of behaviour is highly discouraged, so i think i need some help. Thanks.

kotee4ko commented 1 year ago

Please, can anybody test this behaviour and discard or approve it? In my setup it seems that when any space between parts of payload present -- it became unpassable constrain for kAFL.

Wenzel commented 1 year ago

poke @il-steffen any chance you can have a quick at this redqueen issue ? thanks !

il-steffen commented 1 year ago

So, the magic string was found and successfully injected to input, the harness react by crashing, as expected, and kAFL log this. But not new path in corpus/regular neither correct (crashing) payloads in corpus/crashes are present.

Thanks for debugging this. Can you check the logic on frontend side as well? :-)

The Redqueen analysis + first mutation stage is here: https://github.com/IntelLabs/kafl.fuzzer/blob/master/kafl_fuzzer/worker/state_logic.py#L346

The "state logic" implements the mutation pipeline of the workers. For the Redqueen stage, it first performs coloring + tracing using execute_redqueen(), which skips the crash + feedback analysis disabled (using execute_naked() function). Qemu writes the relevant traces as files in the workdir/redqueeen-something/ folder where they are picked up by the frontend (Redqueen "InfoGatherer" stuff). It then runs the proposals using the normal "execute()" call where crashes + new coverage is analyzed normally. There is also a "havoc" variant of this, called as part of the havoc stage, where it simply uses tokens found by Redqueen as a dictionary: https://github.com/IntelLabs/kafl.fuzzer/blob/master/kafl_fuzzer/worker/state_logic.py#L473

I am not sure if the initial stage should have found the input already, but in principle the colorizer will first do some input expansion so the unused bytes should have been passed. If the trace logic found the compare, you should be able to see it written to the traces, where it is picked up by the InfoGatherer stuff.

Your log indicates that the input was eventually found in the later havoc stage using the RQ-dictionary:

Worker-00 RQ-Dict: attempting b'PWNED!!!\x00Somethi' Worker-00 RedQ-Dict: Have performed 0 iters (???????) Received new input (exit=crash): b'!NYX\xef\xbe\xad\xde'ndings: <0, 0, 0>

However, the supposedly crashing payload also seems wrong here. This "received new input" is what the worker eventually hands off to the manager process as the crashing input, and the manager will store it after checking that the bitmap is unique. But it seems that even the worker/self.execute() got the wrong input here, so maybe the execution is out of sync somehow?

I suspect your issue is related to how the redqueen mutator handles the strings. This was python2 code once which has a messed up way of handling strings, and we didn't really have a lot of tests for migrating to python3 except that it still seemed to work.

kotee4ko commented 1 year ago

Kindly appreciated for reply, guys.

I was able to move on a bit with strings.

|root@w00t|:{/usr/src/kAFL} #_ find /dev/shm/kafl_root/corpus/regular/
/dev/shm/kafl_root/corpus/regular/
/dev/shm/kafl_root/corpus/regular/payload_00008
/dev/shm/kafl_root/corpus/regular/payload_00007
/dev/shm/kafl_root/corpus/regular/payload_00006
/dev/shm/kafl_root/corpus/regular/payload_00005
/dev/shm/kafl_root/corpus/regular/payload_00004
/dev/shm/kafl_root/corpus/regular/payload_00001
/dev/shm/kafl_root/corpus/regular/payload_00002
/dev/shm/kafl_root/corpus/regular/payload_00003
|root@w00t|:{/usr/src/kAFL} #_ hexyl /dev/shm/kafl_root/corpus/regular/payload_00008
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 21 4e 59 58 ef be ad de ┊ 00 00 50 57 4e 45 44 21 │!NYX××××┊00PWNED!│
│00000010│ 21 21 00 50             ┊                         │!!0P    ┊        │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘

There were several issues, at least. 0) https://github.com/IntelLabs/kafl.fuzzer/blob/82c87450bc6812773be8b051b465ec010aaf8710/kafl_fuzzer/worker/state_logic.py#L477C13-L477C13 why limitation of 256? 1) Redqueen's data was append to the dict with junky null bytes in front and in tail. https://github.com/IntelLabs/kafl.fuzzer/blob/82c87450bc6812773be8b051b465ec010aaf8710/kafl_fuzzer/technique/redqueen/cmp.py#L193 Should we .strip(b'\x00') before processing?

2) Sometimes even just zero-bytes were append to the dict. https://github.com/IntelLabs/kafl.fuzzer/blob/82c87450bc6812773be8b051b465ec010aaf8710/kafl_fuzzer/technique/havoc_handler.py#L284 should we check len(.strip(b'\x00')) > 0 here?

3) As was told here https://github.com/IntelLabs/kafl.fuzzer/blob/82c87450bc6812773be8b051b465ec010aaf8710/kafl_fuzzer/technique/havoc_handler.py#L297C1-L297C83 variable and out-of-bound offsets -- very good idea, because without them we couldn't discover that the target has/need more large payload, etc.

Btw, in CMPLOG impl of qemuafl there was very cool stuff, which split ints to bytes. I don't sure if it possible to do that trick with intel-pt (but think it should), if it isn't done yet?

4) https://github.com/IntelLabs/kafl.fuzzer/blob/82c87450bc6812773be8b051b465ec010aaf8710/kafl_fuzzer/technique/havoc_handler.py#L318 if we got static dict we would never use rq?

5) https://github.com/IntelLabs/kafl.fuzzer/blob/82c87450bc6812773be8b051b465ec010aaf8710/kafl_fuzzer/technique/havoc_handler.py#L284C2-L284C2 What about uint16_t ? two bytes? And what about integers (with nullbytes) at all? If i understand right the dict is one for all types of rq findings?

Atm it pass first strcmp() and totally stacked on second memcmp().

 124   │         if (*(int*)&(payload_buffer->data[4]) == 0xdeadbeef) {
 125   │           if (!strcmp(&(payload_buffer->data[10]), "PWNED!!!")) {
 126   │             hprintf("PWNED\n");
 127   │             char *magic;
 128   │             magic = &(payload_buffer->data[20]);
 129   │             if (!memcmp(magic, "RedQueen", sizeof("RedQueen"))) {
 130   │                 void **crash = 0xdeadbeef;
 131   │                 *crash = 0xcafefeed;
 132   │                           kAFL_hypercall(HYPERCALL_KAFL_PANIC_EXTENDED,
 133   │                                  (uintptr_t) "Something went wrong\n");
 134   │             }
 135   │           }
 136   │         }
 137   │       }
 138   │ 

and now we got:

|root@w00t|:{/usr/src/kAFL} #_ grep -rn PWNED /dev/shm/kafl_root/
/dev/shm/kafl_root/hprintf_03.log:1:PWNED
grep: /dev/shm/kafl_root/aux_buffer_9: binary file matches
grep: /dev/shm/kafl_root/aux_buffer_8: binary file matches
grep: /dev/shm/kafl_root/aux_buffer_7: binary file matches
grep: /dev/shm/kafl_root/aux_buffer_6: binary file matches
grep: /dev/shm/kafl_root/aux_buffer_5: binary file matches
grep: /dev/shm/kafl_root/aux_buffer_4: binary file matches
grep: /dev/shm/kafl_root/aux_buffer_2: binary file matches
grep: /dev/shm/kafl_root/aux_buffer_1: binary file matches
grep: /dev/shm/kafl_root/aux_buffer_0: binary file matches
grep: /dev/shm/kafl_root/payload_6: binary file matches
grep: /dev/shm/kafl_root/payload_1: binary file matches
grep: /dev/shm/kafl_root/snapshot/fast_snapshot.mem_dump: binary file matches
grep: /dev/shm/kafl_root/corpus/regular/payload_00008: binary file matches

|root@w00t|:{/usr/src/kAFL} #_ grep -arn RedQueen /dev/shm/kafl_root/
/dev/shm/kafl_root/snapshot/fast_snapshot.mem_dump:91177:RedQueenSomething went wrong

/dev/shm/kafl_root/snapshot/fast_snapshot.mem_dump is too big to perform strings | sort -u :-) Strange is that rq stop appending new vars in dict.

Worker-07 RedQ-Dict: Have performed 0 iters
Worker-06 HAVOC times: afl: 7.0, splice: 0.0, grim: 0.0, rdmsa: 0.0 0, 0>
perf updated for node 3: 0.12 => 0.24
Worker-06 __perform_rq_dictt: rq_dict len 2, [{4203020: {b'\xde\xad\xbe\xef'}, 4203045: {b'PWNED!!!\x00PWNED\n\x00'}}];
payload_array len 8, [b'!NYX\xef\xbe\xad\xde']

Worker-06 RedQ-Dict: Have performed 0 iters
Worker-00 HAVOC times: afl: 4.7, splice: 11.2, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 1: 0.13 => 0.54
Worker-00 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 4, [b'\xa2\x8a\xbaE']

Worker-00 RedQ-Dict: Have performed 0 iters
Worker-02 HAVOC times: afl: 4.3, splice: 10.6, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 2: 0.12 => 0.38
Worker-02 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 4, [b'!\x03\xf4F']

Worker-02 RedQ-Dict: Have performed 0 iters
Worker-04 HAVOC times: afl: 4.6, splice: 11.4, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 5: 0.12 => 0.38
Worker-04 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 4, [b'!NYt']

Worker-04 RedQ-Dict: Have performed 0 iters
Worker-01 HAVOC times: afl: 7.6, splice: 18.4, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 8: 0.23 => 0.33
Worker-01 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 2, [b'!\x03']

Worker-01 RedQ-Dict: Have performed 0 iters
Worker-06 HAVOC times: afl: 2.8, splice: 6.8, grim: 0.0, rdmsa: 0.0 0, 0>
perf updated for node 7: 0.14 => 0.60
Worker-06 __perform_rq_dictt: rq_dict len 2, [{4203020: {b'\xde\xad\xbe\xef'}, 4203045: {b'PWNED!!!\x00PWNED\n\x00'}}];
payload_array len 4, [b'!N4\xd4']

Worker-06 RedQ-Dict: Have performed 0 iters
Worker-05 HAVOC times: afl: 4.8, splice: 11.7, grim: 0.0, rdmsa: 0.0
perf updated for node 4: 0.13 => 0.34
Worker-05 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 4, [b'!NYX']

Worker-05 RedQ-Dict: Have performed 0 iters
Worker-07 HAVOC times: afl: 5.0, splice: 12.4, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 8: 0.23 => 0.33
Worker-07 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 20, [b'!NYX\xef\xbe\xad\xde\x00\x00PWNED!!!\x00P']

Worker-07 RedQ-Dict: Have performed 0 iters
Worker-08 HAVOC times: afl: 9.7, splice: 23.5, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 6: 0.13 => 0.26
Worker-08 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 8, [b'!NYX\xef\xbe\xad\xde']

Worker-08 RedQ-Dict: Have performed 0 iters
Worker-02 HAVOC times: afl: 4.3, splice: 10.5, grim: 0.0, rdmsa: 0.0
perf updated for node 2: 0.12 => 0.38
Worker-02 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 4, [b'\xa2\x8a\xbaE']

Worker-02 RedQ-Dict: Have performed 0 iters
Worker-01 HAVOC times: afl: 10.7, splice: 0.0, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 3: 0.12 => 0.24
Worker-01 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 4, [b'!\x03\xf4F']

Worker-01 RedQ-Dict: Have performed 0 iters
Worker-00 HAVOC times: afl: 4.7, splice: 11.4, grim: 0.0, rdmsa: 0.0
perf updated for node 1: 0.13 => 0.54
Worker-00 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 4, [b'!NYt']

Worker-00 RedQ-Dict: Have performed 0 iters
Worker-04 HAVOC times: afl: 4.6, splice: 11.4, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 5: 0.12 => 0.38
Worker-04 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 2, [b'!\x03']

Worker-04 RedQ-Dict: Have performed 0 iters
Worker-06 HAVOC times: afl: 4.8, splice: 11.9, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 4: 0.13 => 0.34
Worker-06 __perform_rq_dictt: rq_dict len 2, [{4203020: {b'\xde\xad\xbe\xef'}, 4203045: {b'PWNED!!!\x00PWNED\n\x00'}}];
payload_array len 4, [b'!N4\xd4']

Worker-06 RedQ-Dict: Have performed 0 iters
Worker-09 HAVOC times: afl: 9.6, splice: 23.7, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 6: 0.13 => 0.26
Worker-09 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 4, [b'!NYX']

Worker-09 RedQ-Dict: Have performed 0 iters
Worker-08 HAVOC times: afl: 4.2, splice: 10.3, grim: 0.0, rdmsa: 0.00, 0>
perf updated for node 7: 0.14 => 0.60
Worker-08 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 20, [b'!NYX\xef\xbe\xad\xde\x00\x00PWNED!!!\x00P']

Worker-08 RedQ-Dict: Have performed 0 iters
Worker-02 HAVOC times: afl: 3.0, splice: 7.4, grim: 0.0, rdmsa: 0.0 0, 0>
perf updated for node 1: 0.13 => 0.54
Worker-02 __perform_rq_dictt: rq_dict len 0, [{}];
payload_array len 8, [b'!NYX\xef\xbe\xad\xde']
il-steffen commented 1 year ago

Whew, thanks!

Suggestion @Wenzel: Lets collect/create a couple redqueen trace files that we load into RedqueenInfoGatherer() and call get_proposals() on. Then fix up some of this code to generate good inputs.

The kafl debug tool has some very old, very unlikely to work, code for this: https://github.com/IntelLabs/kafl.fuzzer/blob/master/kafl_fuzzer/debug/core.py#L321

kotee4ko commented 10 months ago

Hi guys, any upd on this? @il-steffen @Wenzel

Wenzel commented 10 months ago

Hi @kotee4ko,

this issue has been in my TODO list for a while, unfortunately it's not trivial to investigate and solve. On top of that i'm not familiar with RedQueen's internals and implementation details on kAFL. I can try to allocate some time on Friday, and estimate how much work is needed.

I'd like to point out that I really appreciate the quality of your bug report though, thank you for this.