内容简介:本文主要介绍如何基于首先查看源码 demo_bin.c,存在一处堆溢出漏洞,关键点如下:
*本文原创作者:xiaohan0x00,本文属FreeBuf原创奖励计划,未经许可禁止转载
本文主要介绍如何基于 Angr 进行漏洞挖掘,并自动生成 Exploit。对于 Exploit 的自动生成问题,也被称为 AEG(Automatic Exploit Generation),其中包含漏洞挖掘、Crash分析、约束条件构造、约束求解、Exploit 生成等环节,下文通过符号执行实现对二进制程序的自动化漏洞挖掘及利用,并展示完整的 AEG 过程。文中所分析的漏洞程序为 Insomni`Hack 2016 题目之一。 下载地址 ,其中包含漏洞程序源码 demo_bin.c、编译后的可执行程序 demo_bin 以及 Angr 脚本 solver.py。
0×00 漏洞原理
1、源码分析
首先查看源码 demo_bin.c,存在一处堆溢出漏洞,关键点如下:
1) component_name[128] 大于 component->name[32];
2) initializa_component( char *cmp_naem) 函数中,在赋值时未检查缓冲区大小;
3) 调用 do_something() 时,产生 Crash。
2、GDB 调试
分析过程序源码后,利用 GDB 动态调试 demo_bin,以触发 Crash。首先通过 r2 查看 initializa_component( char *cmp_naem) 所对应的汇编代码。
分析后可知,结构体 component 大小为 36 字节,其中 component->name[32] 占用 32 字节,随后 4 字节为函数指针,因此构造 PoC 为 “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB”。
利用 GDB 加载 demo_bin 并输入 PoC,在 initializa_component( char *cmp_naem) 函数中,调用 malloc() 之后设置断点。查看此时 malloc() 所分配的内存情况。
继续调试,单步至 initializa_component( char *cmp_naem) 函数返回,查看此时内存情况。可见 cmp 在堆上的地址为 “0x804b410”,而 cmp->do_something(1) 所对应的地址 “0x804b430” 此刻已被 “\x42\x42\x42\x42” 所覆盖,如下图所示。
当程序执行至 cmp->do_something(1) 时触发 Segmentation fault,此时 EIP 为 “\x42\x42\x42\x42”,表明程序的控制流已被劫持。
通过以上简要分析可知,demo_bin 中存在堆溢出漏洞,可导致控制流劫持。在此基础上,下文主要介绍如何通过 Angr 实现对该漏洞的自动化挖掘以及利用。
0×01 Angr AEG
完整的 AEG 过程,在逻辑上大致可分为以下几个环节:
1) 漏洞挖掘,Angr 主要采用带有前置约束及路径选择策略的符号执行; 2) 崩溃现场分析:EIP 状态、内存布局; 3) 约束条件构造; 4) 约束求解,Exploit 生成;
1、漏洞挖掘
在本例中,主要是针对控制流劫持漏洞的挖掘。利用符号执行检测控制流劫持,关键在于 EIP,若 EIP 完全被符号变量所覆盖,则代表着控制流可以被劫持,此时 Angr 会抛出 unconstrained 状态。
solve.py 中 65 ~ 84 行,通过搜索二进制程序的状态空间以实现漏洞挖掘。由于 demo_bin.c 中的漏洞逻辑较为简单,因此在挖掘过程中并未加入复杂的前置约束以缓解路径爆炸,也未采用额外的路径搜索策略,仅使用 SimulationManager 的 step() 方法,循环执行,直到出现 unconstrained 状态。
注意,在设置 SimulationManager() 时,save_unconstrained 必须设置为 True。
2、崩溃现场分析
脚本运行不久后,便会触发 unconstrained 状态,此时需要对崩溃现场进行分析,以判定 unconstrained 状态的可利用性。
1) EIP 可控性分析
solve.py 中使用 fully_symbolic() 方法检查 EIP 中符号变量的数量。其中 state.arch.bits 代表系统字长(The number of bits in a word),state.solver.symbolic() 用以判断输入数据是否为符号变量,该方法在 ./angr/state_plugins/solver.py 中实现:
当 EIP 完全被符号变量覆盖时,代表控制流已被劫持,此时堆及 EIP 状态如下:
在实际调试过程中,会出现多次 unconstrained 状态,但前若干次符号变量均未能完全覆盖 EIP,因此并不能利用。最终 EIP 被符号变量完全覆盖时,其内容如下:
2)内存布局分析
在触发控制流劫持后,需要分析当前状态下内存中符号变量的分布情况。solve.py 中的 find_symbolic_buffer() 实现相关功能,主要包括查找符号输入、追踪符号变量两个部分。
(1) 查找符号输入
Angr 在处理 scanf 的输入数据时,采用 streams 模式。默认情况下,stdin、stdout、stderr 均采用该模式。state.posix.stdin 为输入程序的全部符号变量,调试结果如下:
(2) 追踪符号变量
通过 state.solver.get_variables() 追踪内存中的符号变量。该函数位于 ./angr/state_plugins/solver.py 中,返回结果如下:
state.memory.addrs_for_name() 返回符号变量对应的地址,结果如下:
至此,已完成漏洞挖掘与崩溃现场的分析,后续需要结合 Exploit 的方式(ret2text、ret2syscall、ROP 等),构造完整的约束条件,并求解。
3、约束条件构造
对于 Exploit 自动生成问题来说,其关键是构造合适的约束条件,并利用 SMT(Satisfiability Modulo Theories) 约束求解器求解,若约束可解,则生成成功,否则生成失败。其中包括路径约束、EIP 约束、shellcode 约束等。
本例中,Exploit 方式采用 ret2text 且不考虑安全机制,因此仅需找到一片足以放置 shellcode 的连续空间即可。检查空间连续性的函数如下:
solve.py 中的 shellcode 大小为 22 字节,最终构造约束条件如下:
4、约束求解
通过 ep.satisfiable() 对约束条件 extra_constraints=(memory == sc_bvv,ep.regs.pc == buf_addr) 的可解性进行判断。最终判定为约束可解,并生成 Exploit:
0×02 小结
本文以简单的堆溢出为例,展示了如何利用 Angr 自动生成 Exploit。与此同时,也展示了 AEG 的完整过程。文中并未涉及复杂漏洞的自动利用及符号执行所面临的路径爆炸、路径选择、约束求解等问题。由于笔者接触 Angr 时间不久,文中难免存在理解不当之处,望各位大佬批评指正(Orz…)。
*本文原创作者:xiaohan0x00,本文属FreeBuf原创奖励计划,未经许可禁止转载
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Simulink自动生成代码
- changelog 日志自动生成插件
- APIAuto 2.0.0 发布,机器学习自动化测试、自动生成代码和注释、自动静态检查...
- 深度有趣 | 23 歌词古诗自动生成
- 测者的测试技术手册:自动的自动化EvoSuite 自动生成JUnit的测试用例
- 数据生成工具 ZenData 发布 2.0 版本,自动生成“互联网黑话”!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Foundations of PEAR
Good, Nathan A./ Kent, Allan / Springer-Verlag New York Inc / 2006-11 / $ 50.84
PEAR, the PHP Extension and Application Repository, is a bountiful resource for any PHP developer. Within its confines lie the tools that you need to do your job more quickly and efficiently. You need......一起来看看 《Foundations of PEAR》 这本书的介绍吧!