目录
- 预备知识
- 1.关于Angr
- 实验目的
- 实验环境
- 实验步骤一
- 实验步骤二
- 实验步骤三
预备知识
1.关于Angr
Angr是一个利用python开发的二进制程序分析框架,我们可以利用这个工具尝试对一些CTF题目进行符号执行来找到正确的解答,即flag。当然,要注意的是符号执行的路径选择问题到现在依旧是一个很大的问题,换句话说也就是当我们的程序存在循环时,因为符号执行会尽量遍历所有的路径,所以每次循环之后会形成至少两个分支,当循环的次数足够多时,就会造成路径爆炸,整个机器的内存会被耗尽(我们这次分析的程序只有两个分支,不会存在这个问题)。
实验目的
通过该实验了解符号执行的思维和方法,学会使用Angr,进一步掌握IDA的常见用法。
实验环境
服务器:Windows 8
kali IP地址:随机分配
辅助工具:win8装IDA,kali下安装在下文
实验文件请在实验机内下载使用:http://tools.hetianlab.com/tools/T034.zip
实验步骤一
kali上安装angr方法(已装):



官方建议使用python虚拟环境来安装和使用angr。几个angr的依赖项(z3,pyvex)需要从原始代码分叉的本机代码库,如果已经安装了libz3或libVEX,绝对不应该用angr的代码覆盖官方共享对象。为了避免覆盖等问题,一般建议在虚拟环境中使用,由于使用虚拟机演示,所以可以忽略这个问题,使用完毕后如果出现问题恢复镜像即可,如果采用物理机演示,建议在python环境中操作。
要分析文件的文件为下载的fauxware,首先在同目录创建一个project:

类似于上面的流程,可以查看CPU架构(arch)、文件路径(filename)、入口地址(entry)。

angr的CLE模块用于加载二进制程序到虚拟地址空间。加载器(loader)作为项目的一个属性可用于查看与二进制程序一起加载的共享库,并且可在加载地址空间进行查询操作。
查看内存空间中的共享库:

查看加载到内存空间的主要二进制文件、查询栈是否可执行、查询是否为位置无关代码:

angr中有很多类,其中大部分需要在项目中进行实例化。通过project.factory可以方便地使用一些常用的对象。
使用project.factory.block可从给定的地址提取代码块。

还可将block转化为VEX中间语言形式。

Project中保存的是程序的初始内存映像,二进制程序执行后的状态由SimState(simulated program state)表示。
SimState包含程序执行时的状态数据,比如进程内存、寄存器和文件数据等。下图演示的是分别获取寄存器的值、获取程序入口地址处内存(以int类型解析)。

simulation managers是angr中用于执行和模拟程序的接口,可以管理多个程序state。stash为包含多个同类状态的列表,默认执行的stash为active。模拟管理器中使用.step()以基本block为单位运行。

和分析/bin/true一样,同样可以生成程序的控制流图:

同样是不加载共享库,打印出节点数0x5c,即十进制的92个。

对fauxware的黑盒分析到此告一段落,接下来去看看源码。
实验步骤二
关注authenticate函数。
由注释的提示可知,存在后门,只要密码输入为SOSNEAKY,就可以验证成功。

根据authenticate的判断逻辑结合angr的工作原理,我们可以知道:
当程序运行到if(strcmp(password, sneaky) == 0)分支时会产生两个状态,其中一个状态将会包含用户输入正确后门密码的约束条件。
使用IDA分析:
先判断文件格式:
IDA载入:

找到main函数:

F5反编译:

双击authenticate函数:

可以看到在if判断中是跟着sneaky。
双击查看:

可以看到sneaky的数据就是后门密码。
至于判断之后分叉的两个状态可以切换到view-A,然后空格键切换到graph overview。

找到authenticate之后双击查看执行流图:

上图显示的就是authenticate执行后的两个分支,也即angr分析时的state1和state2。
实验步骤三
使用angr分析时可以清楚地看到两个状态:

一直执行直到出现两个分支时停下:

获取进入特定分支,需要往stdin输入数据。
可以看到这里如果要进入返回1的分支(state1),只要往stdin输入SOSNEAKY,从而认证通过,这就是前面分析源码时判断的后门密码。
angr重写了一些libc的函数,比如获取stdin数据,会返回符号量,用于符号执行,在某个状态下可以使用state1.posix.dumps(0)获取进入该状态时stdin需要输入的数据(0表示的就是stdin,1则是stdout),所以上面我们使用state.posix.dumps来获取。
以上是我们为了便于理解angr的使用才一步步来分析,如果熟练掌握的话可以直接写脚本获取后门密码。
代码:

前面提到1表示stdout,脚本首先判断分支后的哪个状态会打印出welcome,然后打印出进入该状态需要输入的数据。
运行:

运行:

随意输入会报错:

输入后门密码即可通过判断。
















