【技术分享】angr:基于python的二进制分析框架

admin 2023-12-07 17:49:44 AnQuanKeInfo 来源:ZONE.CI 全球网 0 阅读模式

https://p5.ssl.qhimg.com/t0186dad73557671385.jpg

作者:desword

预估稿费:200RMB(不服你也来投稿啊!)

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

0.前言

来看看这个集成框架在二进制代码分析的CTF中解决过哪些问题吧,下面是git中列举的解决过的CTF赛题:

http://p6.qhimg.com/t015ba4fc1d8db0f080.jpg

http://p5.qhimg.com/t01b92784928b964e49.jpg

其中,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


1. angr的简要过程

1)将二进制程序载入angr分析系统

2)将二进制程序转换成中间件语言(intermediate representation, IR)

3)将IR语言转换成语义较强的表达形式,比如,这个程序做了什么,而不是它是什么。

4)执行进一步的分析,比如,完整的或者部分的静态分析(依赖关系分析,程序分块)、程序空间的符号执行探索(挖掘溢出漏洞)、一些对于上面方式的结合。


2. 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

一些坑:

1. 在新建的虚拟机环境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

$workon angr
(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


3. 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的基本功能,就使用了这个简单的例子)

1. 首先,需要进入虚拟python环境,并导入angr库。

$ mkvirutalenv angr
(angr) $ python
>>> import angr

2. 新建一个angr的工程。Project()中是目标二进制程序的路径。

>>> p = angr.Project(‘./< path > /fauxware’)

3. 接着新建一个SimState的对象。

SimState的对象在angr其中的一个子模块SimuVEX中,它追踪且记录着符号信息、符号对应的内存信息和符号对应的寄存器信息,以及打开的文件信息等。你可以通过”Project.factory”这个容器中的任何一个来获取一个SimState对象,这个factory有很多类型,如:factory.block, factory.entry_state 等,详细可以看文档。这里使用factory.entry_state这个容器表示返回一个初始化到二进制入口函数的SimState对象。

>>> state = p.factory.entry_state()

4. 接着,我们使用factory.path这个容器获取state的起点path对象。

我的理解是相当于path的开端,之后将沿着这个开端往后进行。对于这个path对象的深入解释也在文档中p64.

>>> path = p.factory.path(state)

5. 我们根据前面获取的函数入口点的path对象,利用path_group容器获取沿着path开端下面将会执行的path列表,详细的path_group对象的解释在文档中p70.

>>> pathgroup = p.factory.path_group(path)

6. 接下来就让pathgroup对象一直执行下去,直到执行到可选择的路径个数大于一个,即产生选择分支的时候,再停止。对应在上述的简单程序中authenticate函数的 if (strcmp(password, sneaky) == 0)这个条件判断语句。

>>> pathgroup.step(until=lambda lpg: len(lpg.active) > 1)

7. 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也是两项较为典型的开源工具,学习这些工具能够更好的提高我们二进制分析,漏洞跟进的效率。

weinxin
版权声明
本站原创文章转载请注明文章出处及链接,谢谢合作!
评论:0   参与:  0