符号执行:利用Angr进行简单CTF逆向分析


发布人:admin分类:网络安全浏览量:154发布时间:2017-11-29

CTO训练营 | 12月3-5日,深圳,是时候成为优秀的技术管理者了


一、符号执行概括

简单的来说,符号执行就是在运行程序时,用符号来替代真实值。符号执行相较于真实值执行的优点在于,当使用真实值执行程序时,我们能够遍历的程序路径只有一条,而使用符号进行执行时,由于符号是可变的,我们就可以利用这一特性,尽可能的将程序的每一条路径遍历,这样的话,必定存在至少一条能够输出正确结果的分支,每一条分支的结果都可以表示为一个离散关系式,使用约束求解引擎即可分析出正确结果,这就是符号执行的简单阐述。

符号执行:利用Angr进行简单CTF逆向分析

Angr是一个利用python开发的二进制程序分析框架,我们可以利用这个工具尝试对一些CTF题目进行符号执行来找到正确的解答,即flag。当然,要注意的是符号执行的路径选择问题到现在依旧是一个很大的问题,换句话说也就是当我们的程序存在循环时,因为符号执行会尽量遍历所有的路径,所以每次循环之后会形成至少两个分支,当循环的次数足够多时,就会造成路径爆炸,整个机器的内存会被耗尽。

二、Angr使用

个人感觉Angr在求解REVERSE题目时很有用,但在处理PWN题目时,多用在一些辅助的位置,比如寻找 strcmp 等敏感的函数等,这次我们简单的讲解一下如何使用Angr进行REVERSE题目的分析求解。我首先讲解一下Angr在实践中的几步关键操作,之后会使用一个简单的CTF题目进行实践。推荐大家使用ipython进行简单的实践,ipython的tab补全可以让你看到Angr中很多奇妙的函数。

1. 运行程序

我们在得到一个程序时,首先需要对此程序创建一个Angr工程。

  1. p = angr.Project(‘program’) 

我们可以通过这个工程得到程序的一些信息,比如程序名p.filename等等。

然后需要将这个程序运行起来,并且处理程序的一些输入,前面已经说过,在符号执行时,我们使用的并不是真实值,而是一个个符号,可以简单的理解为变量,所以我们需要构造一个Angr中的符号来当做程序的输入。

(1) 命令行参数

当程序要求命令行参数时,我们首先需要使用claripy这个模块来定义抽象的数据。

  1. import claripy 

claripy的BVS函数可以创建一个指定长度的抽象数据,BVS函数要求两个参数,第一个参数为变量名,第二个参数为变量长度。

  1. argv = [p.filename,]  
  2. arg = claripy.BVS(‘arg1′, 8)argv.append(arg1) 

这样,我们就创建好了一个命令行参数,我们现在可以将程序运行到程序入口处,并获得当前的一个状态。

  1. state = p.factory.entry_state(args=argv

P.factory是工厂函数的一个集合,在这里面可以调用各种各样的函数来进行符号执行,其中entry_state()函数接收一个list作为程序的命令行参数并且返回程序入口的状态(这个状态将在2.2节讲解)。

(2) 标准输入

当程序需要从标准输入处读取数据时,需要使用read_from()函数,要注意,这个函数位于状态中,并且我们可以对输入进行一些约束以减少符号执行遍历的路径。

  1. for _ in xrange(5):   
  2.     k = state.posix.files[0].read_from(1) 
  3.     state.se.add(k!=10) 

这表示我们从标准输入读入了5个字节,并且每个字节都不为换行符。

2. Angr中程序的几种状态

我们在之前提到了获取程序入口点的状态,状态在Angr中表示着程序符号执行后的几种结果,在Angr中,当获取到程序入口点的状态后,我们需要使用Angr的Simgr模拟器来进行符号执行

  1. sm = p.factory.simgr(state) 

表示从入口点出创建一个模拟器来进行符号执行。

在 Angr 寻找路径时,程序的当前状态有多种表示。

  • step()表示向下执行一个block(42bytes),step()函数产生active状态,表示该分支在执行中;
  • run()表示运行到结束,run()函数产生deadended状态,表示分支结束;
  • explore()可以对地址进行限制以减少符号执行遍历的路径。例如
  • sm.explore(find=0x400676,avoid=[0x40073d])
  • explore()产生found状态,表示探索的结果等等

3. 获取输出

当符号执行遍历玩路径后,会产生大量的状态,我们则需要从这些状态中找出我们所需要的一条路径。

我们可以获取当前状态程序的输出

  1. print sm.found.posix.dumps(1) 

命令行参数

  1. print sm.found.solver.eval(arg1,cast_to = str

标准输入

  1. inp = sm.found.posix.files[0].all_bytes()   
  2. print sm.found.solver.eval(inp,cast_to = str)z 

在求解命令行参数和标准输入的值时,我们使用了约束求解引擎来进行求解

3. Angr实践

bin(re50)下载:

http://oj.xctf.org.cn/web/practice/defensetrain/465f6bb8f4ad4d65a70cce2bd69dfacf/

脚本编写

  1. import angr 
  2. import sys 
  3. print "[*]start------------------------------------" 
  4. p = angr.Project(sys.argv[1])  # 建立工程初始化二进制文件 
  5. state = p.factory.entry_state() # 获取入口点处状态 
  6.   
  7. ''' 
  8. state.posix.files[0].read_from(1)表示从标准输入读取一个字节 
  9. ''' 
  10.   
  11. for _ in xrange(int(sys.argv[2])):  # 对输入进行简单约束(不为回车) 
  12.     k = state.posix.files[0].read_from(1) 
  13.     state.se.add(k!=10) 
  14.   
  15. k = state.posix.files[0].read_from(1) 
  16. state.se.add(k==10)  # 回车为结束符 
  17.   
  18. state.posix.files[0].seek(0) 
  19. state.posix.files[0].length = int(sys.argv[2])+1 # 约束输入长度(大于实际长度也可) 
  20.   
  21. print "[*]simgr start-------------------------------" 
  22.   
  23. sm = p.factory.simgr(state)   # 初始化进程模拟器 
  24. sm.explore(find=lambda s:"correct!" in s.posix.dumps(1)) # 寻找运行过程中存在 “correct!”的路径,并丢弃其他路径 
  25. print "[*]program excuted---------------------------" 
  26.   
  27. for pp in sm.found: 
  28.     out = pp.posix.dumps(1)   # 表示程序的输出 
  29.     print out 
  30.     inp = pp.posix.files[0].all_bytes()  # 取输入的变量 
  31.     print pp.solver.eval(inp,cast_to = str)  # 利用约束求解引擎求解输入 

运行

  1. root@kali:~# python re50.py ppp 4 
  2. [*]start------------------------------------ 
  3. /usr/local/lib/python2.7/dist-packages/cle/loader.py:729: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal 
  4.   if ilibname.strip('.0123456789') == spec.strip('.0123456789'): 
  5. [*]simgr start------------------------------- 
  6. [*]program excuted--------------------------- 
  7. please input the key:correct! 
  8.   
  9. 9563 
  10.   
  11. root@kali:~# 

我们就得到了正确的key值 9563

【编辑推荐】

  1. XCTF联赛“出海计划”开启,八月新加坡站国际赛蓄势待发
  2. XCTF联赛迈出走向海外第一步,为安全人才提供国际交流机会
  3. DEFCON CTF 2017圆满收关,三支中国战队闯入全球前五
  4. 黑客“世界杯”DEFCON CTF 2017,美国PPP战队再夺冠!
  5. 第二期XCTF-XMan特训夏令营收官,两支优秀战队将出征新加坡!
【责任编辑:赵宁宁 TEL:(010)68476606】

点赞 0

被黑站点统计 - 文章版权1、本主题所有言论和图片纯属会员个人意见,与本文章立场无关
2、本站所有主题由该文章作者发表,该文章作者与被黑站点统计享有文章相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和被黑站点统计的同意
4、文章作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、被黑站点统计管理员有权不事先通知发贴者而删除本文

免责声明

本站主要通过网络搜集国内被黑网站信息,统计分析数据,为部署安全型网络提供强有力的依据.本站所有工作人员均不参与黑站,挂马或赢利性行为,所有数据均为网民提供,提交者不一定是黑站人,所有提交采取不记名,先提交先审核的方式,如有任何疑问请及时与我们联系.

admin  的文章


微信公众号

微信公众号


Copyright © 2012-2022被黑网站统计系统All Rights Reserved
页面总访问量:22108292(PV) 页面执行时间:83.357(MS)
  • xml
  • 网站地图