前言
最近在突破学习angr使用
这儿就拿这个例题来写写, 挺好的
方便我复习
构造堆栈的核心: 找到函数调用前的exp情况和调用后的esp的情况以及输入的地址
例题:https://github.com/angr/angr-doc/tree/master/examples/flareon2015_2
直接开整
? 我以为是elf文件
查下壳
拖入ida分析
函数这么少??
决定用angr来解题 那么 想想构造堆栈的核心
那就找呗
可以先看下 官方exp
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
| import angr
def main(): b = angr.Project("very_success", load_options={"auto_load_libs":False}) s = b.factory.blank_state(addr=0x401084) s.memory.store(s.regs.esp+12, s.solver.BVV(40, s.arch.bits)) s.mem[s.regs.esp+8:].dword = 0x402159 s.mem[s.regs.esp+4:].dword = 0x4010e4 s.mem[s.regs.esp:].dword = 0x401064 s.memory.store(0x402159, s.solver.BVS("ans", 8*40)) sm = b.factory.simulation_manager(s) sm.explore(find=0x40106b, avoid=0x401072) found_state = sm.found[0] return found_state.solver.eval(found_state.memory.load(0x402159, 40), cast_to=bytes).strip(b'\0')
def test(): assert main() == b'a_Little_b1t_harder_plez@flare-on.com'
if __name__ == '__main__': print(main())
|
为了必满调用win的api, 我们需要把入口设为0小01084
0x401084为函数sub-401084校验输入的地方
但是这样的话就会跳过sub-401000函数, 所以我们要模仿此函数
函数调用前后的堆栈
这道题的关键就在这里
1 2 3 4 5
| s.memory.store(s.regs.esp+12, s.solver.BVV(40, s.arch.bits)) s.mem[s.regs.esp+8:].dword = 0x402159 s.mem[s.regs.esp+4:].dword = 0x4010e4 s.mem[s.regs.esp:].dword = 0x401064
|
至于这一句
1
| s.memory.store(s.regs.esp+12, s.solver.BVV(40, s.arch.bits))
|
这个创建了一个值40 大小为s.arch.bits的BVV(位向量值 也就是输入)
其中s.arch.bits的值位32(因为这是一个32位的程序)
接着的话 把该值载入到exp+12的位置上
为什么呢? (逆出来的 图方便 - 抽象 哈哈)
因为这个地址对此程序无影响 所以就拿来当作参照物
保存call sub401084调用后的堆栈情况
这儿需要知道[ebp-10h]地址存的啥
可以动调(笔者这种懒人最喜欢做的事了)
也可以往回逆
接下来就简单了
构造模拟器 设置find以及avoid
1 2
| sm = b.factory.simulation_manager(s) sm.explore(find=0x40106b, avoid=0x401072)
|
最后输出就好了
1 2
| found_state = sm.found[0] print(found_state.solver.eval(found_state.memory.load(0x402159, 40), cast_to=bytes).strip(b'\0')
|
整理一下exp
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
| import angr import claripy
def main(): p = angr.Project('./very_success', auto_load_libs=False) state = p.factory.blank_state(addr=0x401084) state.memory.store(state.regs.esp+12, state.solver.BVV(40, state.arch.bits)) state.mem[state.regs.esp+8:].dword = 0x402159 state.mem[state.regs.esp+4:].dword = 0x4010E4 state.mem[state.regs.esp:].dword = 0x401064 state.memory.store(0x402159, state.solver.BVS("ans", 40*8)) simgr = p.factory.simulation_manager(state) simgr.explore(find=0x40106B, avoid=0x401072) found = simgr.found[0] return found.solver.eval(found.memory.load(0x402159, 40), cast_to=bytes).strip(b'\0') if __name__ == '__main__': print(main())
|
ok
总结
构造堆栈的核心: 找到函数调用前的exp情况和调用后的esp的情况以及输入的地址
本题结束 感谢观看
Orz