作者:desword
预估稿费:200RMB(不服你也来投稿啊!)
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
0.前言
来看看这个集成框架在二进制代码分析的CTF中解决过哪些问题吧,下面是git中列举的解决过的CTF赛题:
其中,HackCon 2016 – angry-reverser花费31 min,SecurityFest 2016 – fairlight花费20s,Defcamp CTF Qualification 2015 – Reversing 100和Reversing 200几乎都不要人工的干预,能够自动化的完成分析。这么逆天的功能,是不是要心动了?简直是CTF二进制的利器呀。下面我就来介绍一下这个神奇的工具angr。(注:本文仅作抛砖引玉的作用,更深入的工具用法和源码分析将在后续更新。)
在二进制代码中寻找并且利用漏洞是一项非常具有挑战性的工作,它的挑战性主要在于人工很难直观的看出二进制代码中的数据结构、控制流信息等。angr是一个基于python的二进制漏洞分析框架,它将以前多种分析技术集成进来,方便后续的安全研究人员的开发。它能够进行动态的符号执行分析(如,KLEE和Mayhem),也能够进行多种静态分析。
最近在许多的安全顶会(S&P, USENIX Security, CCS)上都见到有使用symbolic execution这个框架,之后打算整理成一个专题来介绍它们的使用以及优缺点。
该项目的Github: https://github.com/angr/angr
- angr的简要过程
1)将二进制程序载入angr分析系统
2)将二进制程序转换成中间件语言(intermediate representation, IR)
3)将IR语言转换成语义较强的表达形式,比如,这个程序做了什么,而不是它是什么。
4)执行进一步的分析,比如,完整的或者部分的静态分析(依赖关系分析,程序分块)、程序空间的符号执行探索(挖掘溢出漏洞)、一些对于上面方式的结合。
- angr的安装
理论上来说angr目前支持linux、windows、MAC多个平台。但是支持的最好的还是linux平台。Windows平台下由于相关的依赖库文件较难安装,因此不太建议在windows上安装。
Linux
推荐的是14.04 的ubuntu, 16 和12 的版本都会出现不同的问题。
首先是按照依赖库,这个一般没什么问题:
sudo apt-get install python-dev libffi-dev build-essential virtualenvwrapper
virtualenvwrapper是一个python的虚拟环境,使用这个的主要原因是angr会对于libz3 or libVEX产生修改,为了防止对已经安装的库的修改而影响到到之后其他程序的使用,使用一个python的虚拟机环境是一个不错的选择。
接着就是正式的安装,首先新建一个python的虚拟机环境:
mkvirutalenv angr
接着再是使用pip安装:
pip install angr
一些坑:
- 在新建的虚拟机环境angr中的python中,import angr, 出现ImportError: No module named decorator这个错误,直接安装就好。
pip install decorator
还有一些其他的坑在angr的gitbook里面有,可以从这里下载
安装完成后,进入虚拟的python环境中,就可以载入angr库了:
$ mkvirtualenv angr
(angr) $ python
import angr
Linux 下 angr-dev脚本安装
还有一种简单的安装方式,就是pull这个github: https://github.com/angr/angr-dev
直接在根目录下面运行这个shell脚本,可以自动配置virtualenv环境,安装angr库:
./setup.sh -i -e angr
接着可以通过下面的方式启动angr
w o r k o n a n g r ( a n g r ) workon angr (angr) workonangr(angr)ipython
import angr
MAC OS
第一步也是依赖库:
pip install -I --no-use-wheel angr-only-z3-custom
完了就是安装:
pip install angr
windows
windows下面没有测试过,但是有一个网站上有人已经搜集了相关的资料:https://github.com/Owlz/angr-Windows
- angr简单的例子
这个简单的例子说明了angr的用法。样例程序来自于:https://github.com/angr/angr-doc/tree/master/examples/fauxware
以下是有漏洞的样例程序代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
char *sneaky = “SOSNEAKY”;
int authenticate(char *username, char *password)
{
char stored_pw[9];
stored_pw[8] = 0;
int pwfile;
// evil back d00r
if (strcmp(password, sneaky) == 0) return 1;
pwfile = open(username, O_RDONLY);
read(pwfile, stored_pw, 8);
if (strcmp(password, stored_pw) == 0) return 1;
return 0;
}
int accepted()
{
printf(“Welcome to the admin console, trusted user!n”);
}
int rejected()
{
printf(“Go away!”);
exit(1);
}
int main(int argc, char **argv)
{
char username[9];
char password[9];
int authed;
username[8] = 0;
password[8] = 0;
printf(“Username: n”);
read(0, username, 8);
read(0, &authed, 1);
printf(“Password: n”);
read(0, password, 8);
read(0, &authed, 1);
authed = authenticate(username, password);
if (authed) accepted();
else rejected();
}
整个样例程序的功能就是让你输入用户名和密码,然后authenticate函数会进行检验,如果失败就显示Go away,反之就显示认证成功。我们来看看怎么来用angr挖掘出这个程序的验证码。(这个程序实际上非常简单,简单的利用OD或者IDA就能立刻看出来,但是为了介绍angr的基本功能,就使用了这个简单的例子)
- 首先,需要进入虚拟python环境,并导入angr库。
$ mkvirutalenv angr
(angr) $ python
import angr
- 新建一个angr的工程。Project()中是目标二进制程序的路径。
p = angr.Project(‘./< path > /fauxware’)
- 接着新建一个SimState的对象。
SimState的对象在angr其中的一个子模块SimuVEX中,它追踪且记录着符号信息、符号对应的内存信息和符号对应的寄存器信息,以及打开的文件信息等。你可以通过”Project.factory”这个容器中的任何一个来获取一个SimState对象,这个factory有很多类型,如:factory.block, factory.entry_state 等,详细可以看文档。这里使用factory.entry_state这个容器表示返回一个初始化到二进制入口函数的SimState对象。
state = p.factory.entry_state()
- 接着,我们使用factory.path这个容器获取state的起点path对象。
我的理解是相当于path的开端,之后将沿着这个开端往后进行。对于这个path对象的深入解释也在文档中p64.
path = p.factory.path(state)
- 我们根据前面获取的函数入口点的path对象,利用path_group容器获取沿着path开端下面将会执行的path列表,详细的path_group对象的解释在文档中p70.
pathgroup = p.factory.path_group(path)
- 接下来就让pathgroup对象一直执行下去,直到执行到可选择的路径个数大于一个,即产生选择分支的时候,再停止。对应在上述的简单程序中authenticate函数的 if (strcmp(password, sneaky) == 0)这个条件判断语句。
pathgroup.step(until=lambda lpg: len(lpg.active) > 1)
- dump出所有分支的内容,看看哪个答案应该是最可能的。
for I in range(len(pathgroup.active)):
. . . . print “possible %d: ” % I , pathgroup.active[i].state.posix.dumps(0)
对于解决这种问题的基本用法可以是这样,为了提高效率,还可以自己挖掘一些基于此框架的更加trick的方法。
总结
以上就是angr二进制分析框架基本功能的介绍,更多花式的用法和原理性的知识可以查看angr的github项目。Symbolic execution最近较为火热,KLEE和Mayhem也是两项较为典型的开源工具,学习这些工具能够更好的提高我们二进制分析,漏洞跟进的效率。