转载:All Right

符号执行概述

在学习这个框架之前首先要知道符号执行。
符号执行技术使用符号值代替数字值执行程序,得到的变量的值是由输入变 量的符号值和常量组成的表达式。符号执行技术首先由King在1976年提出 ,经过三十多年的发展,现在仍然被广泛研究,它在软件测试和程序验证中发挥着重 要作用。符号执行是一种重要的形式化方法和静态分析技术,它使用数学和逻辑 首先定义一些基本概念。程序的路径(path)是程序的一个语句序列,这个 语句序列包括程序的一些顺序的代码片段,代码片段之间的连接是由于分支语句 导致的控制转移。一个路径是可行的(feasible),是指存在程序输入变量的至少一组值,如果以这组值作为输入,程序将沿着这条路径执行。否则,路径就是不 可行的(infeasible)。路径条件(path condition,PC)是针对一个路径的,它是一 个关于程序输入变量的符号值的约束,一组输入值使得程序沿着这条路径执行当 且仅当这组输入值满足这条路径的路径条件。具体看这里,链接

angr框架介绍

在二进制代码中寻找并且利用漏洞是一项非常具有挑战性的工作,它的挑战性主要在于人工很难直观的看出二进制代码中的数据结构、控制流信息等。angr是一个基于python的二进制漏洞分析框架,它将以前多种分析技术集成进来,方便后续的安全研究人员的开发。­­­它能够进行动态的符号执行分析(如,KLEE和Mayhem),也能够进行多种静态分析。
当然这款工具在CTF中的运用还是比较火的,在一些国际比赛中经常会看到它所带来的神奇之处,比如下面我们将要讲的的DEFCON CTF Qualifier 2016 baby-re这道题它仅仅用了10min就完成看了自动化分析拿到了flag。angr的github地址为,链接

angr的安装

理论上来说angr目前支持linux、windows、MAC多个平台。但是支持的最好的还是linux平台。Windows平台下由于相关的依赖库文件较难安装,因此不太建议在windows上安装。
接下来我们介绍一下ubuntu上的安装。

  • 安装独立python虚拟环境,virtualenvwrapper是一个python的虚拟环境,使用这个的主要原因是angr会对于libz3 or libVEX产生修改,为了防止对已经安装的库的修改而影响到到之后其他程序的使用,使用一个python的虚拟机环境是一个不错的选择。

    1
    sudo apt-get install python-dev libffi-dev build-essential virtualenvwrapper

此时virtualenvwrapper就可以使用了,常用命令如下:

  1. 列出虚拟环境列表:workon,也可以使用:lsvirtualenv
  2. 新建虚拟环境:mkvirtualenv [虚拟环境名称]
  3. 启动/切换虚拟环境:workon [虚拟环境名称]
  4. 删除虚拟环境:rmvirtualenv [虚拟环境名称]
  5. 离开虚拟环境:deactivate
  • 接着angr安装
1
pip install angr

安装好以后我们启动虚拟环境,进入虚拟的python库后就可以载入angr库了

1
2
3
4
5
6
longlong@ubuntu:~/examples/defcon2016quals_baby-re_0$ workon angr
(angr) longlong@ubuntu:~/examples/defcon2016quals_baby-re_0$ python
Python 2.7.6 (default, Oct 26 2016, 20:30:19)
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import angr

angr的使用之简单例子一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#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编写利用脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python
#_*_ coding:utf-8 _*_
import angr
 
def basic_symbolic_execution():
p = angr.Project('fauxware') #新建一个angr的工程,括号中是目标二进制程序的路径
state = p.factory.entry_state() #接着新建一个SimState的对象
path = p.factory.path(state) #使用factory.path这个容器获取state的起点path对象
pathgroup = p.factory.path_group(path) #根据前面获取的函数入口点的path对象,利用path_group容器获取沿着path开端下面将会执行的path列表
pathgroup.step(until=lambda lpg: len(lpg.active) > 1)#接下来就让pathgroup对象一直执行下去,直到执行到可选择的路径个数大于一个,即产生选择分支的时候,再停止。
#对应在上述的简单程序中authenticate函数的 if (strcmp(password, sneaky) == 0)这个条件判断语句
 
 
input_0 = pathgroup.active[0].state.posix.dumps(0) #dump出所有分支的内容,看看哪个答案应该是最可能的
input_1 = pathgroup.active[1].state.posix.dumps(0)
 
if 'SOSNEAKY' in input_0:
return input_0
else:
return input_1
 
def test():
pass
if __name__ == '__main__':
print basic_symbolic_execution()

结果如下:

1
2
3
(angr) longlong@ubuntu:~/examples/fauxware$ python solve.py
SOSNEAKY
(angr) longlong@ubuntu:~/examples/fauxware$

angr的使用之简单例子二(CTF题)

这道题是DEFCON CTF Qualifier 2016 baby-re0,在打开二进制可执行文件后,我们向下移动到主要的底部,看到0x4028e7有两条非常明显的路径,一条路径是0x402941,打印出错误。另一条是0x4028e9,将会打印出flag。但是这个程序的中间有大量的繁琐的指令,看的人眼花缭乱,接下来我们用angr解决这个问题。

脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python2
#_*_ coding:UTF-8 _*_
import angr
 
def main():
proj = angr.Project('./baby-re', load_options={'auto_load_libs': False})
 
path_group = proj.factory.path_group(threads=4) # 设置了四个线程,对于这个程序线程再多了没意义
 
# 如果是0x40294b就执行,如果是0x402941就不去执行
path_group.explore(find=0x40294b, avoid=0x402941)
# flag在0x40292c的位置
print path_group.found[0].state.posix.dumps(0)
return path_group.found[0].state.posix.dumps(1) # dumps出flag
 
 
if __name__ == '__main__':
print(repr(main()))

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(angr) longlong@ubuntu:~/examples/defcon2016quals_baby-re_0$ python solve.py
WARNING | 2017-04-09 16:34:11,976 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:34:14,865 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:34:19,274 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:34:26,447 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:34:38,414 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:34:58,141 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:35:24,905 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:36:00,673 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:36:45,998 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:37:48,193 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:39:20,551 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:41:20,080 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2017-04-09 16:44:18,468 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
+000000077+000000097+000000116+000000104+000000032+000000105+000000115+000000032+000000104+000000097+000000114+000000100+000000033B
'Var[0]: Var[1]: Var[2]: Var[3]: Var[4]: Var[5]: Var[6]: Var[7]: Var[8]: Var[9]: Var[10]: Var[11]: Var[12]: The flag is: Math is hard!\n'
(angr) longlong@ubuntu:~/examples/defcon2016quals_baby-re_0$

大概10min后我们得到的flag 是Math is hard!

符号执行-基于python的二进制分析框架angr的更多相关文章

  1. Appium基于Python unittest自动化测试 & 自动化测试框架 -- PO并生成html测试报告

    基于python单元测试框架unittest完成appium自动化测试,生成基于html可视化测试报告 代码示例: #利用unittest并生成测试报告 class Appium_test(unitt ...

  2. ShutIt:一个基于 Python 的 shell 自动化框架

    ShutIt是一个易于使用的基于shell的自动化框架.它对基于python的expect库(pexpect)进行了包装.你可以把它看作是“没有痛点的expect”.它可以通过pip进行安装. Hel ...

  3. 基于Python的接口自动化测试框架

    项目背景 公司内部的软件采用B/S架构,目的是进行实验室的数据存储.分析.管理. 大部分是数据的增删改查,但是由于还在开发阶段,所以UI的变化非常快,难以针对UI进行自动化测试,那样会消耗大量的精力与 ...

  4. 《Selenium自动化测试实战:基于Python》Selenium自动化测试框架入门

    第1章  Selenium自动化测试框架入门 1.1  Selenium自动化测试框架概述 说到目前流行的自动化测试工具,相信只要做过软件测试相关工作,就一定听说过Selenium. 图1-1是某企业 ...

  5. 基于python的unittest测试框架集成到jenkins(Mac)

    1.jenkins部分 1.1 安装jenkins jenkins下载地址:https://jenkins.io/download/ 安装步骤,疯狂点击下一步 1.2 打开jenkins服务 在浏览器 ...

  6. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

  7. Selenium 4 Python的最佳测试框架

    随着Python语言的使用越来越流行,基于Python的测试自动化框架也越来越流行.在项目选择最佳框架时,开发人员和测试人员会有些无法下手.做出选择是应该判断很多事情,框架的脚本质量,测试用例的简单性 ...

  8. Django,Flask,Tornado三大框架对比,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Django 与 Tornado 各自的优缺点Django优点: 大和全(重量级框架)自带orm,template,view 需要的功能也可以去找第三方的app注重高效开发全自动化的管理后台(只需要使 ...

  9. Python几种主流框架

    从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python Web应用开发框架 Djang ...

随机推荐

  1. 如何查看Linux操作系统版本?

    参考地址:http://www.ggat.cn/newsInfo.html/71 如何查看Linux操作系统版本? 1. 查看内核版本命令: $ cat /proc/version $ uname - ...

  2. NOI2018d1t1 归程 (dijkstra+kruskal重构树)

    题意:给一张无向联通图,每条边有长度和高度,每次询问在高度大于p的边,从v点能到达的所有点到1号点的最短距离(强制在线) 首先dijkstra求出每个点到1号点的距离 易知:如果我按高度从高到低给边排 ...

  3. 简明的Python教程中的几个疑惑点分析#2

    #1简明的Python教程当中第十四章Python标准库介绍中的使用sys模块 假如你没看懂sys模块这一章节,那么没关系,看下面一段代码再看简明的Python教程中的sys模块实例你将很容易看懂 代 ...

  4. 如何设置 ssh secure shell 支持中文

    只需要设置下/etc/sysconfig/i18n 文件内容如清单 1 所示. 清单 1. 文件内容 1 2 3 LANG="zh_CN.GB18030" SUPPORTED=&q ...

  5. Arcgis for qml - 鼠标拖拽移动

    以实现鼠标拖拽文本图层为例 GitHub:ArcGIS拖拽文本 作者:狐狸家的鱼 目的是利用鼠标进行拖拽. 实现两种模式,一种是屏幕上的拖拽,第二种是地图上图层的挪动. 屏幕上的拖拽其实跟ArcGIS ...

  6. Vim在图形环境下全屏产生黑边

    在终端中运行Vim或运行GVim都会遇到这个问题,当窗口全屏时,左右和底部可能会出现边框,这个边框在终端中的Vim表现为Terminal的背景颜色.下图为SpaceVim+Neovim+Termina ...

  7. A1113. Integer Set Partition

    Given a set of N (> 1) positive integers, you are supposed to partition them into two disjoint se ...

  8. notepad问题汇总

    右键无法设置为默认打开方式:https://blog.csdn.net/jl1134069094/article/details/50749075

  9. C#面向对象中类的继承和扫描顺序和接口

    1.   类的分类:普通基类.抽象基类(abstract  class)1.   类的扫描顺序:a.先近后远 b.(向上扫描)以谁身份声明的变量就在谁身上开始扫描, 2.   扫描的特殊情况:普通基类 ...

  10. JMeter关联(正则表达式提取器)

    正则表达式总结 关联:与系统交互过程中,系统返回的内容,需要在接下来的交互中用到,如防止csrf攻击而生成的token. 从前一个请求中取,用Regular Expression Extractor ...