首页
社区
课程
招聘
[原创](开源)Windows下测试用例自动生成工具--pingrind
发表于: 2012-5-5 15:14 27642

[原创](开源)Windows下测试用例自动生成工具--pingrind

2012-5-5 15:14
27642

Windows下测试用例自动生成工具—Pingind
原理:
Windows下二进制程序的漏洞挖掘主要还是通过fuzz测试,通过构造随机的输入使程序崩溃,再进行人工分析程序崩溃是否由漏洞引起。但是传统的黑盒fuzz效率非常低,因其无法达到理想中的覆盖率,其中很大部分的时间里都是在重复以前同样的路径,并不能有效地探测到新的路径。因此,路径覆盖的问题亟待解决。
微软的Sage提出白盒fuzz的方法,可以通过二进制的一次具体执行中收集到路径约束,然后取反求解而得到新的输入,使用新的输入再次执行二进制程序,通常又可得到新的路径,如此往复,可以达到较好的二进制代码覆盖率。Sage一贯继承微软的作风,并未开源。类似的实现还有DART、CUTE、Catchconv、Fuzzgrind,这些都是运行在linux平台下。其中CUTE与DART同宗,都是使用了CIL中间语言与lpsovler求解器,由Koushik与Patrice两人共同完成。而Catchconv与Fuzzgrind原理相同,都是使用Valgrind插装工具与STP求解器。其中Catchconv与Fuzzgrind现在仍然是开源的。
基于上述的基础,我实现了一种运行在Windows平台上的路径探测工具—Pingrind。
实现思路:实现Pin中的pintool,使用可以追踪指令,可方便获取当前线程执行上下文,可得知每个跳转是否taken等信息,可得到文件输入的地址,从而引入污点(这里的污点可看成是输入,从污点位置开始收集路径约束)。然后集成以Valgrind中的中间语言VEX IR,使给出任意地址即可把该地址的机器指令翻译成VEX IR。再借鉴fuzzgrind中的一部分代码来完成收集约束及污点传播过程。使用STP来求解生成新的输入用例。最后完成自动化过程,使整个过程不需要人工。
Pin是Intel公司开发的、对二进制代码执行监控的工具。使用插装的方式,可以监控二进制代码在用户模式下的一切行为,包括线程、寄存器、内存等信息。Pin可运行在Window与Linux平台下,Linux下工具一般都开源,且还有其它的程序分析工具如Valgrind、Temu等与其竞争,而Windows下与其竞争的开源框架极少。
Pin为PinVMM和Pintool开发者提供一个常规的编程环境,使用C++语言,包括流和标准模板库,C运行时库和一些Windows API。但是PinVMM和Pintools是应用进程的DLL,调用相同的运行时库可能会引起不想看到的Pin和应用程序的交互。如当程序调用malloc时,我们想插装它的整个执行直到系统调用级。Pintool可能需要使用malloc但它的执行不能被插装。而且,Pintools调用malloc可能作为对程序调用malloc插装的一部分,表示pintool在应用程序调用malloc完成之前调用malloc。系统库设计来支持使用锁和线程局部存储来支持并发执行,但是这些方法并不有效因为应用程序和插装可能在同一个线程内。
Pin为用户提供了很好的接口,可以实现各种Pintool,可基于Pin的基础上对二进制分析。在Pin源码中的ManualExample文件中有很多例子可以参考。Pin接口API文档化较差,需看include文件夹下的*.PH文件,根据函数名猜测其功能。
Valgrind也是二进制插装平台,可运行在Linux、MacOS等平台下,唯独对Windows不兼容,导致其虽然功能完善,但无法分析Windows程序,虽说出现了Wine+Valgrind的组合,但其兼容性有待考证。Valgrind中实现了一套中间语言--VEX IR,它可以将二进制转换为此IR,再进行插装,然后再把插装后的IR编译成二进制执行。Fuzzgrind为Valgrind平台上实现的一个插件,可以在插装VEX IR并收集路径约束,再用STP求解来生成新的输入用例。从Fuzzgrind的实现来看,它更适用于对文件读写的程序,可看成是一种文件类型的智能fuzz工具。Valgrind包括两个组件外加一个程序分析的工具。第一个组件是VEX库,把机器代码块转化为一种中间表示。第二个组件是Valgrind核,处理程序载入,与操作系统交互并即时翻译程序到VEX中间表示,插装,编译到机器代码。Valgrind以标准的Linux进程运行并作为一个程序加载器。Valgrind核把guest进程的每个基本块加载到VEX库。VEX库转化每个基本到一种表示并将其输入到特定的Valgrind工具中。该工具为基本块插装并把结果输入到Valgrind核,Valgrind核使用VEX编译其到机器代码。Valgrind保留一个编译后的插装块的缓存并管理它们的执行流。Valgrind可作为一个即时的插装编译器。VEX库转化机器码到一种平台无关的中间表示。
Pingrind的工作就是把Valgrind中的VEX集成在Pin中,使用Pin作为二进制代码的插装工具,使用VEX作为中间代码,在Pin中监控二进制代码的执行,使其转化成VEX后,并在每个分支收集其依赖于输入的路径约束。再使用STP求解,可得到新的输入。

实现:
        重用了Fuzzgrind中的部分python代码(在此严重感谢ESEC开发Fuzzgrind的作者)
        移植了VEX库到windows下,为方便直接合成到一个源文件vex_main.c(对这近4W行的代码修改还真是累)。
        SOURCE=grind.cpp, check.cpp
        grind.cpp就是pin的插件源码,用来插装二进制代码的动态执行
           check.cpp是先观察程序执行时要加载哪些模块,要create, read,map哪些文件的信息,有了这些信息才能给pingrind.py添加参数。

开发环境:
Pin主页上下载Pintools的源码,然后修改其中的NMakefile,把Source文件中的check.cpp 及grind.cpp添加进去编译即可。由于Pin的源码较大我就不一起上传了。

环境:
环境要求:Windows xp(32位) + Python2.7及以上版本
编译STP:
1)下载安装cgywin,并添加必要的开发组件(如gcc, g++, make等),还需添加bison, flex, svn;
2) svn co https://stp-fast-prover.svn.sourceforge.net/svnroot/stp-fast-prover/trunk/stp stp;
3)cd stp;
4)./scripts/configure –with-prefix=/path/to/stp/inst;
5)make & make install;
注意:编译过程中可能会出现getchar函数名问题,将其重命名即可
6)添加cygwin/bin与/path/to/stp/inst/bin到环境变量中

使用方法:
1)cmd中先运行“lm.py  <程序名>”
这一步完成后会在当前目录下生成一个_check_info的文件,其中包括了程序运行过程中加载的模块及其地址等信息,还有访问的文件信息。
(由于Pin只是对用户态级别的监控,所以内核层的任何动作它都无法得知)
2)有了模块及文件信息后,在cmd下执行以下命令:
   “pingrind.py  --ts=0x<模块开始地址> --te=0x<模块结束地址> --tf=<访问的文件名> --prog=<程序名>”

简单的例子:
现在在文件中包括了testC.exe和testRead.exe这两个最简单的例子可以测,它们中包括相同的代码:
        char buffer[5] = { 0 };
    int count = 0;
    FILE *fp = fopen("d:\\123.txt", "r");
   if(fp != NULL)
        {
                fread(buffer, 1, 4, fp);
        }
    if (buffer[0] == 'b') count++;
        if (buffer[1] == 'a') count++;
    if (buffer[2] == 'd') count++;
    if (buffer[3] == '!') count++;
    if (count == 4) {
        printf("\nbad!\n");
    }
        else{
                printf("\ngood\n");
        }
        fclose(fp);
先在d:下建一个文件123.txt,在这个文件中写入”good”,然后使用命令:”pingrind.py --ts=0x400000 --te=0x4FFFFF --tf=d:\\123.txt --prog=testC.exe”就可以开始测试。

作者声明:
Pingrind现在充其量算是一个原型,目前只能测一些非常小的例子,稍微大一点的程序完全没法测试(效率问题),如果要投入使用,需要以后不断的优化,完善。我开源的目的也就是为了有兴趣的朋友可以加入一起研究。

作者邮箱:majinxin2003@126.com
作者blog: http://hi.baidu.com/majinxin2003/blog(欢迎互粉)


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 6
支持
分享
最新回复 (16)
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
2
沙发沙发,支持一个
2012-5-5 15:27
0
雪    币: 220
活跃值: (721)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
白盒没有黑的好用啊
2012-5-5 15:51
0
雪    币: 163
活跃值: (75)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
其实这种跟传统意义的白盒还是有区别的,针对的还是二进制程序,不需要源码,它比传统黑盒还是有较明显的优势,可惜现在规模还是上不去
2012-5-6 10:58
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
如果要是做博士的话,就先别去做底层实现了,因为底层其实是08、09年火的,现在都不做了,做KLEE的那帮人和BitBlaze已经有一个能给顶层研究提供的平台,现在已经风向转到了用这样的技术来解决一些其他领域的问题去了,比如恶意代码分析、协议分析,漏洞利用等。你可能刚刚接触片领域,你现在研究的东西很快就要成熟到商用了,研究的油水已经不多,尽管国内能做原型的团队并不多,你算是不错的一个,但研究还一定要再看远一点。选个在远一点的方向,应该能出好研究成果。
2012-5-6 14:14
0
雪    币: 163
活跃值: (75)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
谢谢提点,其实这也是我的兴趣,原来做这个工具的目的也就是为了能够做点实用的东西出来,而不只是为了写几篇垃圾论文凑数。目前还在不断完善中吧,商用的出来也无所谓,至少我参与过这个过程,我学到了东西,那就足够了。
2012-5-6 18:51
0
雪    币: 2194
活跃值: (1001)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
楼主的心态真好
2012-5-6 23:54
0
雪    币: 258
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
楼主加油 我之前也打算搞个符号化执行的 没有坚持下去
2012-5-17 22:02
0
雪    币: 200
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
加油,加油!!!
2012-5-18 08:58
0
雪    币: 163
活跃值: (75)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
谢谢
2012-5-22 09:47
0
雪    币: 226
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
拿来试试能不能跑出程序的BUG。
2012-6-21 13:34
0
雪    币: 51
活跃值: (61)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
顶 我要看看是否实用了  不管如何都要感谢楼主的开源精神
2012-7-26 14:44
0
雪    币: 217
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
目前只要程序比较大,运算资源、存储资源都是极大的瓶颈

希望有好的思路能从根本上解决问题
2012-7-26 16:42
0
雪    币: 363
活跃值: (338)
能力值: ( LV15,RANK:310 )
在线值:
发帖
回帖
粉丝
14
好文!顶兄台!
2012-8-21 22:05
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
谢谢分享,正在努力学习中
2012-10-7 11:36
0
雪    币: 130
活跃值: (66)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
顶啊,自动生成测试用例,好东西,多谢
2012-11-7 10:13
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
17
神器出炉~
支持,顶起~
能不能搞个MSVC编译的版本或者弄个Cmake模式也行
cgywin编译后看起来二进制代码怪怪的~
2012-11-7 11:40
0
游客
登录 | 注册 方可回帖
返回
//