三种验证算法:
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://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/libc---printf-chk-1.html