Crypto-hashcoll
先贴上源码
#!/usr/bin/env python2 FLAG = '*********************************' h0 = 45740974929179720441799381904411404011270459520712533273451053262137196814399 # 2**168 + 355 g = 374144419156711147060143317175368453031918731002211L def shitty_hash(msg): h = h0 msg = map(ord, msg) for i in msg: h = (h + i)*g # This line is just to screw you up :)) h = h & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff return h - 0xe6168647f636 if __name__ == '__main__': try: introduction = """ .--. .------------------------. | __\ | | | > < < Homies, Hash collision | | \| | | |/_// `------------------------' | / `-' I never want to create challenges that people can grab random scripts to solve it. Nah """ print introduction m1 = raw_input('m1 : ') m2 = raw_input('m2 : ') assert m1 != m2 #print "m1 = {!r}".format(m1) #print "m2 = {!r}".format(m2) hash1 = shitty_hash(m1) hash2 = shitty_hash(m2) if hash1 == hash2: print "\nThe flag is simple, it is 'the flag' :)) " print FLAG else: print 'Wrong.' except: print "Take your time to think of the inputs." pass
先看main函数,发现就是将传进来的两个参数经过shitty_hash这个函数运行后,返回值如果相等就获取flag。所以此题的重点就只有一个,就是shitty_hash函数。
def shitty_hash(msg): h = h0 msg = map(ord, msg) for i in msg: h = (h + i)*g # This line is just to screw you up :)) h = h & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff return h - 0xe6168647f636h
化简一下此函数。
此函数的意思就是将字符串转化成ascii 然后累加、累乘。
化简之后为下面式子
hash = (h0*g^n+x1*g^n+x2*g^(n-1)+x3*g^(n-2)+......+xn*g)%(2^256)
若想让输入的两个字符串经过处理后相等则需要满足
(h0*g^n+x1*g^n+x2*g^(n-1)+x3*g^(n-2)+......+xn*g)%(2^256)=(h0*g^n+y1*g^n+y2*g^(n-1)+y3*g^(n-2)+......+yn*g)%(2^256)
(x1*g^n+x2*g^(n-1)+x3*g^(n-2)+......+xn*g)%(2^256)=(y1*g^n+y2*g^(n-1)+y3*g^(n-2)+......+yn*g)%(2^256)
0=(x1*g^n+x2*g^(n-1)+x3*g^(n-2)+......+xn*g)%(2^256)
0=((x1-y1)*g^n+(x2-y2)*g^(n-1)+(x3-y3)*g^(n-2)+......+(xn-yn)*g)%(2^256)
设zi = xi-yi,得到
(z1*g^n+z2*g^(n-1)+z3*g^(n-2)+......+zn*g)%(2^256)=0
也就是说此问题可已转化为在2^256有限域上寻找一组解的情况。也就是最短向量问题。
直接用LLL算法。
from sage.all import * mod = 2**256 h0 = 45740974929179720441799381904411404011270459520712533273451053262137196814399 g = 2**168 + 355 K = 2**256 base = map(ord, "S4tan"*9) base = (list(base)) N = len(base) m = matrix(ZZ, N + 1, N + 2) for i in range(N): ge = pow(g, N-i, mod) m[i,0] = ge m[i,1+i] = 1 m[N,0] = mod for i in range(N+1): m[i,0] *= K ml = m.LLL() ttt = ml.rows()[0] print("result:", ttt) if ttt[0] != 0: print("Error") exit() if not base: base = [BASE] * N msg = [] for i in range(N): msg.append(base[i] + ttt[1+i]) if not (0 <= msg[-1] <= 255): print("Need more bytes!") quit() def shitty_hash(msg): h = h0 for i in msg: h = (h + i)*g # This line is just to screw you up :)) h = h & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff#mod2**256 #print h return h - 0xe6168647f636 def pure_hash(msg): h = 0 for i in msg: h = (h + i)*g # This line is just to screw you up :)) h = h & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff#mod2**256 return h print(base) print("m1:", "".join(map(chr, base))) print(hex(shitty_hash(base)), shitty_hash(base)) print(msg) diff = [i-j for i,j in zip(msg,base)] print(diff) print(hex(pure_hash(diff))) print("m2:", "".join(map(chr, msg))) print(hex(shitty_hash(msg)), shitty_hash(msg))
利用pwntools发送即可。

浙公网安备 33010602011771号