0%

angr学习_2

从本篇博客开始,我们以实例的形式来了解angr,期待共同学习,共同进步

XCTF嘉年华体验-re1

很简单的一个逆向题目

看伪代码,很明显,是通过以参数作为输入,输入应为一个四位整数,通过各位的判断是否满足条件,最终确定correct还是wrong
直接上脚本

1
2
3
4
5
6
7
for thousand in xrange(0,10):
for hundred in xrange(0,10):
for ten in xrange(1,10):
for num in xrange(1,10):
if num + thousand + ten + hundred == 23 and ten / num == 2 and hundred - ten == -1 and thousand % ten == 3:
print thousand,hundred,ten,num
break

得到答案

验证下

但是这不是我们这篇文章的主要意图,这个题目特别简单,只要会编程并且了解点逆向,这个题目都很容易解出来了,下面我们进入正题,用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
import angr

p = angr.Project('./ppp')
state = p.factory.entry_state()

for _ in xrange(4):
k = state.posix.files[0].read_from(1)
state.se.add(k>47)

k = state.posix.files[0].read_from(1)
state.se.add(k==10)

state.posix.files[0].seek(0)
state.posix.files[0].length = 5

print '[*] simulation_manager start...............'

sm = p.factory.simulation_manager(state)

sm.explore(find=0x08048692,avoid=0x080486A5)


if len(sm.found)>0:
inp = sm.found[0].posix.files[0].all_bytes()
print sm.found[0].solver.eval(inp,cast_to = str)

print '[*] end angr.....'

我们直接从之前未接触过的开始

1
2
3
for _ in xrange(4):
k = state.posix.files[0].read_from(1)
state.se.add(k>47)

这个部分是用来获取标准输入并且对其长度,范围进行限制的部分,xrange(4)函数后面的4是用来表示获取4位标准输入,并且state.posix.files[0].read_from(1),这个部分设置工程文件固定读取标准输入一个字节,,最后通过add()函数对读取的字节进行限制,由于我们的输入限定于数字0~9,所有限定输入一定大于47.
state.se.add(k==10),换行符表示输入结束

1
2
state.posix.files[0].seek(0)
state.posix.files[0].length = 5

这个部分用于限定输入字符长度从起始位置计数一定为5位

inp = sm.found[0].posix.files[0].all_bytes(),读取得到第一个解的所有标准输入
print sm.found[0].solver.eval(inp,cast_to = str),以字符形式输出我的输入

sm.explore(find=0x08048692,avoid=0x080486A5),中地址分别为correct和wrong的分支

最终执行结果如图