三种验证算法:
1.angr 的解法:
- import angr
- import logging
- logging.getLogger('angr.sim_mananger').setLevel(logging.DEBUG)
- proj = angr.Project('./sftp')
- state = proj.factory.entry_state(addr=0x4013F0)
- simgr = proj.factory.simgr(state)
- simgr.explore(find=0x401531)
- print [simgr.found[0].posix.dumps(0)]
2.Z3 解法
这个算法有点问题:
+ 字符集选取的不同, 会出现小概率的失败.
+ 对其中出现的字符进行改变, 或者过滤, 就会成功.
- from z3 import *
- def rel():
- s=Solver()
- hash =BitVec(0x5417,16)
- password=[BitVec(('password%d'%i),16) for i in range(0,15)]
- for i in range(0,15):
- s.add(password[i]>0x20,password[i]<0x7e,password[i]!=0x24)
- hash^=password[i]
- #print "11",password[i]
- hash<<=1
- hash&=(0xffff)
- s.add(hash==36346)
- s.check()
- if s.check()==sat:
- answer=s.model()
- #print(chr(answer[password[1]].as_long()))
- #print "%s" %(answer[3].as_long())
- s=''
- for i in range(0,15):
- #print chr(answer[password[i]].as_long())
- s+=chr(answer[password[i]].as_long())
- print(s)
- else:
- print "unset"
- if __name__=="__main__":
- rel()
3: 通过对算法的逆向的方法:
这是我们队逆向大佬做得: 通过自己的逻辑思维进行逆向分析, 复现逆向的公式, 并对其进行化简. 通过同构映射的方法, 将验证算法转化成多项式系数的求解问题.(此方法无比强大, 不得不佩服他的想法)
- import copy
- def add_sub_elem(p,elem_a):
- for elem in elem_a:
- if elem in p:
- p.remove(elem)
- else:
- p.append(elem)
- return p
- def get_input_numbers(p_org,p_res):
- input_v=[]
- p_op=copy.copy(p_res)
- print "first p_op:",p_op
- print "------- start loop ---------"
- for i in reversed(range(1,16)):
- print "------- loop:"+str(i)+"--------"
- for i2 in range(len(p_op)):
- p_op[i2]=p_op[i2]-1
- print "p_op after divide x :",p_op
- if i==1:
- p_op=add_sub_elem(p_op,p_org)
- p_op_op=copy.copy(p_op)
- for elem in p_op_op:
- if elem>6:
- if elem in p_op:
- p_op.remove(elem)
- input_v.append(p_op)
- print "p_op :",p_op
- print "input_v :",input_v[15-i]
- return input_v
- if 0 in p_op:
- input_v.append([0,5])
- p_op=add_sub_elem(p_op,[0,5])
- else:
- input_v.append([6,])
- p_op=add_sub_elem(p_op,[6,])
- if i==2:
- input_v[:-1].append(6)
- p_op=add_sub_elem(p_op,[6,])
- print "p_op :",p_op
- print "input_v :",input_v[15-i]
- def generate_poly_coe(v4):
- res_poly_coe=[]
- v4_b=bin(v4)[2:].zfill(16)
- idx=16
- for b in v4_b:
- idx-=1
- if b=='1':
- res_poly_coe.append(idx)
- return res_poly_coe
- def strize_my(arr):
- res=''
- arr=list(reversed(arr))
- for elem in arr:
- val=0
- for v in elem:
- val+=pow(2,v)
- res+=chr(val)
- return res
- def solve(v4_0,v4_N):
- p_org=generate_poly_coe(v4_0)
- p_res=generate_poly_coe(v4_N)
- print "p_org:",p_org
- print "p_res:",p_res
- input_value_a=get_input_numbers(p_org,p_res)
- print "input_value_a :", input_value_a
- input_value=strize_my(input_value_a)
- print "input_value ---------> : \'"+input_value+"\'"
- if __name__=="__main__":
- solve(21527,0x8dfa)
参考:
_printf_chk:
来源: http://www.jianshu.com/p/75365826e5fb