libfuzzer那个系列先放一放吧,学了学感觉也没有比AFL好用很多,所以重复性较高的东西先不着急学了吧,这里开个新坑,为了做同学出的一道auto pwn,来学学angr
基础知识
首先了解一下什么是符号执行:
- 传统符号执行
传统的符号执行一般是静态的,即将具体的输入值抽象成符号,执行完之后再根据符号结果解方程,举个例子就会好懂很多
a=input()
b=3+a
c=2*b
if(c*2+4==9):
win()
else:
lose()
对于上述代码,正常的程序执行是给a赋一个实际值,然后经过一系列运算,最后比较c2+4是否等于9,根据比较结果决定程序走向,如果使用fuzz类技术,则是随机给a赋值,记录覆盖率,从而粗略的引导程序,但是对于符号执行技术来说,要做的是给a赋一个符号x,然后直接执行,不用具体值。
a=x
b=3+x
c=2x+6
c2+4=4x+16
最后解4*x+16=9这样一个方程,即可知道让程序执行流走到win,所需的输入是什么
这种静态符号执行的方式看似优秀,但是也面临一些问题,比如当等式两边都是约束式的时候无法求解,比如将上述代码改成:
a=input()
e=input()
b=3+a
c=2*b
if(c*2+4==e):
win()
else:
lose()
那么a和e会被分别赋予不同的符号,执行到最后,等式两边都有符号且无法合并,式子就无法求解,为了解决这个问题,引入了动态符号执行
- 动态符号执行
将传统的静态符号执行和实际执行结合起来,称之为动态符号执行(concolic execution),concolic维持了两个状态。一种是实际变量的状态,另一种是符号化的状态。实际状态将随机生成值映射到变量中,而符号化状态将变量进行符号化。concolic首先将实际状态运行,并收集实际运行时该路径的变量符号化的约束式,i求解。并将约束式取反,获取另一条路径的约束式并求解。过程不断重复,直到路径被探索完,或者达到用户设置的限制
如果针对上述代码,则是先不给e或a赋成符号,而是一个随机的具体的值,然后求解,如果路径探索完了则退出,没探索完则换一个变量换一个随机值继续尝试。
接下来我们正式介绍这款强大的工具angr
angr是一款开源的python框架,具有强大的符号执行功能
直接pip install angr就可以安装
先来看看angr架构:
- CLE:
CLE是angr加载二进制文件的组建,在加载二进制文件的时候会分析病读取binary的信息,包括指令地址、shared library、arch information等等
import angr
b = angr.Project("./test")
-
VEX
它会将指令转化为中间语言IR,分析IR并且模拟,搞清楚它是什么并且做了什么 -
Claripy
它是angr的求解引擎,根据程序所需要的输入设置符号变量以及收集限制式等等,在argr中多用于符号化
接下来我们用一些例子来熟悉一下angr
项目地址:https://github.com/angr/angr-doc
目标程序:https://github.com/angr/angr-doc/tree/master/examples/sym-write
#include <stdio.h>
char u=0;
int main(<