模糊测试-AFL学习笔记之Java

目录

AFL简介

kelinci

下载

目录结构

原理

编译

使用举例 

simple

java-afl

下载

目录结构

参考


AFL简介

AFL(American Fuzzy Lop)是由安全研究员Michał Zalewski(@lcamtuf)开发的一款基于覆盖引导(Coverage-guided)的模糊测试工具,它通过记录输入样本的代码覆盖率,从而调整输入样本以提高覆盖率,增加发现漏洞的概率。其工作流程大致如下:

①从源码编译程序时进行插桩,以记录代码覆盖率(Code Coverage);

②选择一些输入文件,作为初始测试集加入输入队列(queue);

③将队列中的文件按一定的策略进行“突变”

④如果经过变异文件更新了覆盖范围,则将其保留添加到队列中;

⑤上述过程会一直循环进行,期间触发了crash的文件会被记录下来。

AFL原本是对C/C++程序进行插桩,文章模糊测试-AFL学习笔记之C/C++中有对AFL更详细的介绍。

AFL在2017年11月5日后不再更新...

kelinci

更新于2018年2月7日。

其中一位作者是来自Carnegie Mellon University Silicon Valley(卡内基梅隆大学硅谷),似乎是论文附带的研发工具,估计不会更新了。

下载

git clone https://github.com/isstac/kelinci.git

目录结构

项目结构
  •  docs 两个文档的目录
  • examples 三个例子的目录
  • fuzzerside c应用程序
  • instrumentor Java端组件

Java组件通过AFL样式管理为目标应用程序提供工具,并提供与C端通信的组件。以后执行检测程序时,这将设置一个TCP服务器,并针对每个传入请求在单独的线程中运行目标应用程序。它发送回退出代码(成功,超时,崩溃或队列已满),以及收集的路径信息。任何异常转义为main都被视为崩溃。

原理

下图是他们的poster,docs里面的ccs2017-poster-small.pdf

poster
设计

首先对于AFL来说,它并不知道自己在fuzz java程序,这是因为kelinci做了一个java程序的C版interface.c ,这个interface.c程序负责从AFL中接收变异数据,然后通过TCP传给java侧,java侧的程序叫做instrumentor,它负责把从interface传过来的变异数据真正的传递给java原始目标程序,然后再把java的运行结果反馈给interface.c,如此形成了一个fuzz的数据流闭环。

  • 在Java程序上运行AFL
  • 没有对AFL的修改
  • 易于并行化
  • 在JDK 6-9和Apache Commons Imaging中发现错误

对于模糊器生成的给定输入文件,C和Java端之间的交互如下:
1. interface.c接收来自AFL的派生请求。
2.派生的interface.c进程之一加载提供的输入文件,另一个继续运行派生的服务器。
3.前一个interface.c进程通过TCP连接将提供的输入文件发送到Kelinci服务器。
4. Kelinci服务器接收传入的请求并将其入队。
5. Kelinci服务器通过将输入的输入文件写入磁盘,启动一个新线程,在该线程中对提供的输入调用目标应用程序的主方法并对其进行监视,从而处理请求。如果线程抛出escapes main的异常,则将其视为错误。如果线程未在给定的超时时间内终止,则将其视为挂起。
6. Kelinci服务器将结果传递回C端。共享内存位图通过TCP连接以及状态(确定,错误或超时)发送。
7.在C端,将接收到的位图写入共享内存。
根据接收到的状态,程序会正常退出,中止或循环运行,直到AFL超时。

更多内容阅读ccs17-kersten.pdf,里面提到了另外两个模糊测试工具EvoSuite和Randoop

编译

进到 instrumentor目录

gradle build
编译插桩
编译成功后多出的build目录

进入fuzzerside目录

make
编译接口

使用举例 

simple

编译

mkdir bin
javac src/*.java -d bin

插桩

java -cp ../../instrumentor/build/libs/kelinci.jar edu.cmu.sv.kelinci.instrumentor.Instrumentor -i bin -o bin-instrumented
结果

警告可以不管,但是错误不能不管,由于非法反射操作,导致错误,以后的版本将会对非法访问进行拒绝。

issues

 issues中也有不少人对于这个问题进行了提问,部分问题作者没有给出解答,部分问题的解答是注释某些行。

创建输入字典

mkdir in_dir
echo "hello" > in_dir/example

测试字典

java -cp bin-instrumented SimpleBuggy in_dir/example

 出错如下:

ClassNotFoundException

未找到类,.class文件存在,java -version, javac均没有问题,未解决,有明白的朋友请下方评论,谢谢。

转战CentOS6,使用的是之前学大数据Hadoop的虚拟机,Java环境等都有安装,不做赘述。

 编译

编译

插桩

插桩

创建输入字典

mkdir in_dir
echo "hello" > in_dir/example

测试字典

Main done

 有Main done字样,没有问题了。

开启kelinci服务器

java -cp bin-instrumented edu.cmu.sv.kelinci.Kelinci SimpleBuggy @@
开启服务器

测试接口

../../fuzzerside/interface in_dir/example

 开始Fuzz

afl-fuzz -i in_dir -o out_dir ../../fuzzerside/interface @@
两个警告

 警告可能比较慢,需要优化。。。

运行15分钟

 结果分析

发现了两个crashes,我们就看一看是什么输入。

查看crashes

可以看到出错时输入是xello和nello。

验证

 SimpleBuggy.java中的代码有四个大的分支,当首字母的ASCII码减去字符0的ASCII码后对10取余结果为2时报错。我们简单写个程序,发现小写字母中d n x是符合的,而我们的crashes中的两个结果正好是其中的两个,如果运行时间长,应该会发现更多。

java-afl

下载

git clone https://github.com/Barro/java-afl.git
克隆

目录结构

结构

未完待续...

参考

Wikipedia(american fuzzy lop (fuzzer))

AFL漏洞挖掘技术漫谈(一):用AFL开始你的第一次Fuzzing

基于AFL的Java程序Fuzz工具:Kelinci

更多内容查看:网络安全-自学笔记

喜欢本文的请动动小手点个赞,收藏一下,有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。如果您感觉有所收获,自愿打赏,可选择支付宝18833895206(小于),您的支持是我不断更新的动力

猜你喜欢

转载自blog.csdn.net/lady_killer9/article/details/107173682