kAFL
kAFL copied to clipboard
Redqueen doesn't handle strcmp() calls on linux userspace target
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