kAFL icon indicating copy to clipboard operation
kAFL copied to clipboard

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

Open Wenzel opened this issue 2 years ago • 8 comments
trafficstars

          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

Wenzel avatar Jul 23 '23 22:07 Wenzel