程序拖入64位IDA,逻辑很简单,flag是argv[1],verify是检查函数,输入key长度是23
先说不用angr的做法:需要自己把数据扣出来,按照题目中的算法去逆向算(当然因为数少,也可以爆破)
扣数据的代码:
for i in xrange(0x601020, 0x601037):
print hex(Byte(i)),',',
print
然后是爆破的代码:
ans = [0xca , 0x70 , 0x93 , 0xc8 , 0x6 , 0x54 , 0xd2 , 0xd5 , 0xda , 0x6a , 0xd1 , 0x59 , 0xde , 0x45 , 0xf9 , 0xb5 , 0xa6 , 0x87 , 0x19 , 0xa5 , 0x56 , 0x6e , 0x63]
#print len(ans)
flag = ''
for i in xrange(23):
for j in xrange(128):
#num1 = (((j ^ i) % 0x100) << ((i ^ 9) & 3)) % 0x100
num1 = ((j ^ i) << ((i ^ 9) & 3)) % 0x100
num2 = ((j ^ i) >> (8 - ((i ^ 9) & 3))) % 0x100
num = (num1 | num2) % 0x100
if ans[i] == num + 8:
print i,chr(j)
flag += chr(j)
break
print flag
得到如下的结果:
0 a
1 i
2 s
3 3
5 I
6 _
7 t
8 a
9 k
10 3
11 _
12 g
13 0
14 0
15 d
16 _
17 n
18 0
19 t
20 3
21 s
22 }
ais3I_tak3_g00d_n0t3s}
然而还不是完整的,尴尬,可见自己写确实很麻烦
用angr的方法:添加限制条件
(1)长度是23
(2)可行路径位置是0x400602
#!/usr/bin/env python
# coding=utf-8
import angr
import claripy
project = angr.Project("./ais3_crackme")
argv1 = claripy.BVS("argv1", 24 * 8)
initial_state = project.factory.entry_state(args=["./ais3_crackme", argv1])
sm = project.factory.simulation_manager(initial_state)
sm.explore(find = 0x400602)
found = sm.found[0]
solution = found.solver.eval(argv1, cast_to = str)
print solution
每行代码具体解释如下:
project = angr.Project("./ais3_crackme")
选择需要分析的二进制文件
argv1 = claripy.BVS("argv1",100*8)
新建一个长度为100的向量,用来爆破
initial_state = project.factory.entry_state(args=["./crackme1",argv1])
定义爆破入口点,参数是argv1
sm = project.factory.simulation_manager(initial_state)
新建模拟器
sm.explore(find=0x400602)
根据IDA的分析,这里是输出correct的正确分支,让程序执行到此即可
found = sm.found[0]
solution = found.solver.eval(argv1, cast_to=str)
print solution
输出结果即可