Kiprey / Kiprey.github.io

This is Kiprey‘s Blog.
https://kiprey.github.io/
4 stars 3 forks source link

使用 protobuf & AFLplusplus 进行简易 CTF 自动化 fuzz | Kiprey's Blog #70

Open Kiprey opened 3 years ago

Kiprey commented 3 years ago

https://kiprey.github.io/2021/09/protobuf_ctf_fuzz/

P4nda0s commented 3 years ago

afl++可以直接输入到stdin,为啥要写中转程序?

Kiprey commented 3 years ago

@P4nda0s afl++可以直接输入到stdin,为啥要写中转程序?

抱歉,之前对 AFL 不太熟,后来意识到了但忘记更新文章了...... 请刷新一下当前页面即可。

WhereIsOops commented 2 years ago

我在alf++3.15 ,protobuf 3.17.3上按照up的方法,跑不出crash,始终只有一条路径,这是怎么回事啊

Kiprey commented 2 years ago

@WhereIsOops 我在alf++3.15 ,protobuf 3.17.3上按照up的方法,跑不出crash,始终只有一条路径,这是怎么回事啊

只有一条路径的话,尝试直接通过 qemu-trace 来运行目标程序看看能否正常运行。

除此之外还有一个坑点我忘记在文章里标注了,qemu-trace 在这题 babyheap 中,无法正确处理特定地址的 mmap 函数调用,因此会直接 exit 掉。如果只是想测试一下 fuzz 效果,那就直接在二进制层面上将 babyheap 的 exit 调用 nop 掉再重新试试。

WhereIsOops commented 2 years ago

我在afl_custom_post_process函数传递给target用例的地方添加了一个打印函数, std::ofstream writefile;

writefile.open("process.txt", std::ios::app);
writefile << new_buf << std::endl;
writefile.close();

显示内容如下 1 12 [menuctf::AllocChoice] 2 2 20 [menuctf::UpdateChoice] 3 3 4 4

我认为是传递的参数格式有问题,视乎不应该有[menuctf::****]字段

Kiprey commented 2 years ago

@WhereIsOops 我在afl_custom_post_process函数传递给target用例的地方添加了一个打印函数, std::ofstream writefile;

writefile.open("process.txt", std::ios::app);
writefile << new_buf << std::endl;
writefile.close();

显示内容如下 1 12 [menuctf::AllocChoice] 2 2 20 [menuctf::UpdateChoice] 3 3 4 4

我认为是传递的参数格式有问题,视乎不应该有[menuctf::****]字段

这里的 [menuctf::****] 内容,只是我在准备语料时随手输入的数据......

看看 dumper.cc 中的这些代码,[menuctf::****] 只是这里设置的 content

    // alloc 12 "[menuctf::AllocChoice]"
    {
      auto choice = new menuctf::AllocChoice();
      choice->set_size(12);
      choice->set_content("[menuctf::AllocChoice]");        // **1**

      msg.add_choice()->set_allocated_alloc_choice(choice);
    }

    // update 2 20 "[menuctf::UpdateChoice]"
    {
      auto choice = new menuctf::UpdateChoice();
      choice->set_idx(2);
      choice->set_size(20);
      choice->set_content("[menuctf::UpdateChoice]");     // **2**

      msg.add_choice()->set_allocated_update_choice(choice);
    }
    [...]
WhereIsOops commented 2 years ago

这只是content的内容啊,理解错了,那就是说生成的输入是没有问题的。我还是不清楚为什么我的路径始终为1( ╯□╰ )

Kiprey commented 2 years ago

就是说语料库中要删除[menuctf::****]字段吗O(∩_∩)O

我觉得这和 AFL 只有一条路径没有必然的联系。AFL 只有一条路径,那肯定不是 protobuf 出的问题,可能需要检查一下 afl-qemu-trace 能否正常启动目标程序。

WhereIsOops commented 2 years ago

多谢指教,我试了下直接使用afl-qemu-trace打开babyheap,没有停留直接退出了

Kiprey commented 2 years ago

@WhereIsOops 我在alf++3.15 ,protobuf 3.17.3上按照up的方法,跑不出crash,始终只有一条路径,这是怎么回事啊

只有一条路径的话,尝试直接通过 qemu-trace 来运行目标程序看看能否正常运行。

除此之外还有一个坑点我忘记在文章里标注了,qemu-trace 在这题 babyheap 中,无法正确处理特定地址的 mmap 函数调用,因此会直接 exit 掉。如果只是想测试一下 fuzz 效果,那就直接在二进制层面上将 babyheap 的 exit 调用 nop 掉再重新试试。

那大概率是我之前说的这个坑点,需要手动对二进制程序中的 exit 打上 patch,因为qemu 无法正确处理特定地址的 mmap 函数调用。

WhereIsOops commented 2 years ago

我试了下在nop掉exit语句,仍然直接退出,是mmap的地方也有问题吗,请教下你是具体怎么打的patch呢 .text:0000000000001579 48 83 E0 F0 and rax, 0FFFFFFFFFFFFFFF0h .text:000000000000157D 48 89 45 D0 mov [rbp+var_30], rax .text:0000000000001581 48 8B 45 C8 mov rax, [rbp+addr] .text:0000000000001585 41 B9 00 00 00 00 mov r9d, 0 ; offset .text:000000000000158B 41 B8 FF FF FF FF mov r8d, 0FFFFFFFFh ; fd .text:0000000000001591 B9 22 00 00 00 mov ecx, 22h ; '"' ; flags .text:0000000000001596 BA 03 00 00 00 mov edx, 3 ; prot .text:000000000000159B BE 00 10 00 00 mov esi, 1000h ; len .text:00000000000015A0 48 89 C7 mov rdi, rax ; addr .text:00000000000015A3 E8 C8 FA FF FF call _mmap .text:00000000000015A8 48 89 45 D8 mov [rbp+var_28], rax .text:00000000000015AC 48 8B 45 C8 mov rax, [rbp+addr] .text:00000000000015B0 48 39 45 D8 cmp [rbp+var_28], rax .text:00000000000015B4 74 0A jz short loc_15C0 .text:00000000000015B6 90 nop .text:00000000000015B7 90 nop .text:00000000000015B8 90 nop .text:00000000000015B9 90 nop .text:00000000000015BA 90 nop .text:00000000000015BB 90 nop .text:00000000000015BC 90 nop .text:00000000000015BD 90 nop .text:00000000000015BE 90 nop .text:00000000000015BF 90 nop

Kiprey commented 2 years ago

哦对了,mmap 下面还有一个函数也要 nop 掉 (捂脸) 那个函数我没细究是干什么的,但确实也会导致 qemu 退出。 这是我打的 patch:

image

这是打了 patch 后的运行效果: image

其实开个 gdb attach 上 qemu 单步跟一下估计会更快的发现这个问题(逃

Kiprey commented 2 years ago

所以实际上,我当时不应该选这个作为例子,因为坑点有点多。。。。 等到后面 proto 描述什么的都写好了,我才在测试里发现了这个问题,但是已经来不及换了.... (捂脸)

WhereIsOops commented 2 years ago

所以实际上,我当时不应该选这个作为例子,因为坑点有点多。。。。 等到后面 proto 描述什么的都写好了,我才在测试里发现了这个问题,但是已经来不及换了.... (捂脸)

非常感谢up的耐心讲解,笔芯哈哈 接下来又遇到了问题,初始语料库会导致AFL无法运行( ╯□╰ [] Symbol 'afl_custom_describe' not found. [+] Custom mutator './libmutator.so' installed successfully. [] Scanning './in'... [+] Loaded a total of 1 seeds. [] Creating hard links for all input files... [] Validating target binary... [] No auto-generated dictionary tokens to reuse. [] Attempting dry run with 'id:000000,time:0,orig:output.bin'... [] Spinning up the fork server... [+] All right - fork server is up. [] Target map size: 65536

[-] The program took more than 1000 ms to process one of the initial test cases. This is bad news; raising the limit with the -t option is possible, but will probably make the fuzzing process extremely slow.

If this test case is just a fluke, the other option is to just avoid it
altogether, and find one that is less of a CPU hog.

[-] PROGRAM ABORT : Test case 'id:000000,time:0,orig:output.bin' results in a timeout Location : perform_dry_run(), src/afl-fuzz-init.c:943

然后我尝试自己构造输入 echo -ne "1\n2\ntest\n" > case1 echo -ne "2\n2\ntest\n" > case2 然后运行直接导致afl abort.... [+] Custom mutator './libmutator.so' installed successfully. [] Scanning './in'... [+] Loaded a total of 2 seeds. [] Creating hard links for all input files... [] Validating target binary... [] No auto-generated dictionary tokens to reuse. [] Attempting dry run with 'id:000000,time:0,orig:case2'... [] Spinning up the fork server... [+] All right - fork server is up. [*] Target map size: 65536 ./ctf_run.sh: line 6: 22879 Aborted AFL_CUSTOM_MUTATOR_ONLY=1 AFL_USE_QASAN=1 AFL_CUSTOM_MUTATOR_LIBRARY=./libmutator.so /home/fuzz/afl++/AFLplusplus/afl-fuzz -i ./in -o ./out -Q -- ./babyheap

对afl还不是很熟悉,好多坑233

Kiprey commented 2 years ago

这个,还是建议先熟悉一下 AFL 的使用和原理吧(捂脸) testcase 是 protobuf message 的,必须由 dumper.cc 生成,不能手动 echo 生成,否则会因为格式不对被直接 abort 掉。 至于为什么 AFL 会 timeout ,这个我之前倒是没遇到过。试试将诸如 "1\n2\ntest\n" 等格式的输入,以管道形式直接喂给 afl-qemu-trace 跑跑看会不会卡住。 后续 AFL 的问题,因为每人遇到的问题大不相同(比如 timeout 我就没遇到过 -_-),大部分都只能自己通过 gdb 手动调试一下 AFL 才能找出来,所以强烈建议最好还是先熟悉一下 AFL 的用法和原理。 祝好运。

WhereIsOops commented 2 years ago

这个,还是建议先熟悉一下 AFL 的使用和原理吧(捂脸) testcase 是 protobuf message 的,必须由 dumper.cc 生成,不能手动 echo 生成,否则会因为格式不对被直接 abort 掉。 至于为什么 AFL 会 timeout ,这个我之前倒是没遇到过。试试将诸如 "1\n2\ntest\n" 等格式的输入,以管道形式直接喂给 afl-qemu-trace 跑跑看会不会卡住。 后续 AFL 的问题,因为每人遇到的问题大不相同(比如 timeout 我就没遇到过 -_-),大部分都只能自己通过 gdb 手动调试一下 AFL 才能找出来,所以强烈建议最好还是先熟悉一下 AFL 的用法和原理。 祝好运。

嗯嗯。我再研究下,多谢答复~·

Merlecmx commented 2 years ago

您好,请问,我在最后一步afl-fuzz -i了,但是报错 [] optional symbol 'afl_custom_fuzz_count' not found. [] optional symbol 'afl_custom_post_trim' not found. [] Custom mutator does not implement all three trim APIs, standard trimming will be used. [] optional symbol 'afl_custom_havoc_mutation' not found. [] optional symbol 'afl_custom_havoc_mutation_probability' not found. [] optional symbol 'afl_custom_queue_get' not found. [] optional symbol 'afl_custom_queue_new_entry' not found [] Symbol 'afl_custom_describe' not found. 请问,这种是因为什么原因呢

Kiprey commented 2 years ago

@Merlecmx 您好,请问,我在最后一步afl-fuzz -i了,但是报错 [] optional symbol 'afl_custom_fuzz_count' not found. [] optional symbol 'afl_custom_post_trim' not found. [] Custom mutator does not implement all three trim APIs, standard trimming will be used. [] optional symbol 'afl_custom_havoc_mutation' not found. [] optional symbol 'afl_custom_havoc_mutation_probability' not found. [] optional symbol 'afl_custom_queue_get' not found. [] optional symbol 'afl_custom_queue_new_entry' not found [] Symbol 'afl_custom_describe' not found. 请问,这种是因为什么原因呢

有可能是 AFL 版本问题,需要切换至 2021年8月份的 commit 。我刚刚在文章末尾加了一些新的内容,希望能够帮到你。

Merlecmx commented 2 years ago

@Kiprey

@Merlecmx 您好,请问,我在最后一步afl-fuzz -i了,但是报错 [] optional symbol 'afl_custom_fuzz_count' not found. [] optional symbol 'afl_custom_post_trim' not found. [] Custom mutator does not implement all three trim APIs, standard trimming will be used. [] optional symbol 'afl_custom_havoc_mutation' not found. [] optional symbol 'afl_custom_havoc_mutation_probability' not found. [] optional symbol 'afl_custom_queue_get' not found. [] optional symbol 'afl_custom_queue_new_entry' not found [] Symbol 'afl_custom_describe' not found. 请问,这种是因为什么原因呢

有可能是 AFL 版本问题,需要切换至 2021年8月份的 commit 。我刚刚在文章末尾加了一些新的内容,希望能够帮到你。

所以请问按照您github的README.md走下来是运行不通过的是吧

Kiprey commented 2 years ago

@Kiprey

@Merlecmx 您好,请问,我在最后一步afl-fuzz -i了,但是报错 [_] optional symbol 'afl_custom_fuzzcount' not found. [] optional symbol 'afl_custom_posttrim' not found. [] Custom mutator does not implement all three trim APIs, standard trimming will be used. [_] optional symbol 'afl_custom_havocmutation' not found. [] optional symbol 'afl_custom_havoc_mutationprobability' not found. [] optional symbol 'afl_custom_queueget' not found. [] optional symbol 'afl_custom_queue_newentry' not found [] Symbol 'afl_custom_describe' not found. 请问,这种是因为什么原因呢

有可能是 AFL 版本问题,需要切换至 2021年8月份的 commit 。我刚刚在文章末尾加了一些新的内容,希望能够帮到你。

所以请问按照您github的README.md走下来是运行不通过的是吧

仓库中的脚本我先前忘记指定 commit id 了,因此现在 clone 下来的 AFL 版本过高,需要手动调整一下版本。