1

如果使用过afl会发现在output中存在Crashes文件夹,里面是许多类似于id:00000:xxxxxxx命名的文件,这些文件就是使得afl发生崩溃的用例,重新运行这些crash文件即可看到fuzz过程中出现的报错和调用信息,从而确定跑出来的crash究竟是不是我们想要的报错点,还是一些其他的报错甚至是新的未发现的crash,这里需要使用到ASAN。

2

具体如何重现Crash呢,首先重现crash使用的可执行文件不是之前进行fuzz时使用的可执行文件,因为之前在对程序编译时使用的语句可能如下:

CFLAGS=""  CXXFLAGS="" ../configure --disable-shared --prefix=`pwd`

这一次的编译过程需要使用到

-fsanitize=address

可以考虑用-fsanitize=address选项编译和链接
用-fno-omit-frame-pointer编译,以在错误消息中添加堆栈跟踪
用-O1获得更好的性能
以及如果只需要检测内存泄漏,只需要-fsanitize=leak,而不需要-fsanitize=address,若对内存泄露不感兴趣需要使用export ASAN_OPTIONS=detect_leaks=0 来将其禁用

ASAN全称Address Sanitizer,集成到gcc,为一个内存检测工具,我们用它来显示程序遇到的异常状况。重新编译生成可执行文件后,我们就可以使用它运行之前获得的crash

./ASANbin  crashes/id:000001:xxxxxxxx

如果报错可能是运行程序缺少动态链接库,直接运行程序./ASANbin看看输出中有没有提示缺少文件,比如

error while loading shared libraries:libpng16.so.16:cannot open shared object file:No such file or directory

此时使用ldd ASANbin查看可执行文件需要的库
在这里插入图片描述
可见没有这个库,这时可以使用ldconfig -p | grep libpng
查看libpng有无,可以看到
在这里插入图片描述也就是说存在libpng12.so但是没有16,使用apt-get install libpng16-dev下载
之后如果ASANbin运行没有问题了
在这里插入图片描述

即可继续使用./ASANbin crashes/id:000001:xxxxxxxx运行crash
此时会显示类似于下图的输出
在这里插入图片描述但是我们期望看到的应该是某个文件的某一行出错,而不是0x4d194a这种,这是为什么呢

这里尝试使用gdb查看调用栈信息

gdb -q ASANbin

然后

(gdb)  run < /id:000000:xxxxx

此时显示如下图
在这里插入图片描述要想使用gdb调试功能,需要在gcc编译时添加-g参数,对于几个gdb命令简要介绍下:
1、gdb -q +${exe} :对可执行文件调试,不打印gdb版本信息
2、break或b :对函数或代码行打断点,使用info breakpoints查看当前所有的断点
3、run或r:运行程序,运行到第一个断点
4、continue或c:继续运行程序到下一个断点
5、next或n:单步跳过,执行一步程序,若遇到函数直接完成函数而不会进入函数
6、step或s:单步进入,执行一步,若遇到函数会进入函数
7、quit或q:退出gdb
8、bt(backtrace)
获取当前线程的函数调用栈信息,当前线程中函数调用的序列,从当前位置回溯到程序的入口,查看程序执行的路径。
9、info stack
info stack 显示当前线程比 bt 更详细的调用栈信息,包括局部变量和寄存器值。

设置断点或者直接运行程序,当程序暂停时,可以使用 bt来查看栈信息,但是在我们这次尝试中失败了,我们并不能看到行号。
查看HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc),我们得知LeakSanitizer 在内部使用 ptrace,可能会挂起所有线程,以扫描泄漏而不会出现误报,如果在 gdb 或 strace 下运行应用程序,则 LeakSanitizer 将无法通过 ptrace 附加。

可见LeakSanitizer无法和gdb一起工作,在gdb下使用时需要通过设置ASAN_OPTIONS=detect_leaks=0来将其禁用。

这里可能的一个解决方案是使用sudo,由于在服务器上没有sudo权限,这里使用docker进行尝试,注意docker run 命令还要增加–privileged,否则 LeakSanitizer 仍然会报错,其他步骤都相同,最后可以看到现在的报错:
在这里插入图片描述终于能看到行号,从而判断当前crash是不是我们期望的发生崩溃的例子。

Jarvis 24.3.17

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐