I found this great explanation of a length extension attack here by Skullsecurity and decided to implement my own proof-of-concept in Python for MD5. Turns out it was quite simple.
Tl;dr; I should be able to spoof hash signatures in the cases where
H(secret + data)
is used for verification.
I found an alternative MD5 implementation which let me edit the initilization vectors.The one provided by python is a C module. Using the alternative one, and the great explanation provided by Skull, I wrote the folowing script.
import md5py
import struct
def hexdump(s):
for b in xrange(0, len(s), 16):
lin = [c for c in s[b : b + 16]]
#~ if sum([ord(l) for l in lin]) == 0:
#~ continue
hxdat = ' '.join('%02X' % ord(c) for c in lin)
pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)
print(' %04x: %-48s %s' % (b, hxdat, pdat))
print
secret = b"secret"
original = b"data"
append = b"append"
def pad(s):
padlen = 64 - ((len(s) + 8) % 64)
bit_len = 8*len(s)
if(padlen < 64):
s += '\x80' + '\000' * (padlen - 1)
return s + struct.pack('<q', bit_len)
val = md5py.new(secret+original)
print "Original payload:", val.hexdigest()
payload = pad(secret+original)+append
hexdump(payload)
legit = md5py.new(payload)
print "Legit digest:", legit.hexdigest()
not_legit = md5py.new("A"*64)
not_legit.A, not_legit.B, not_legit.C, not_legit.D = md5py._bytelist2long(val.digest())
not_legit.update(append)
print "Illicit digest:", not_legit.hexdigest()
if legit.hexdigest() == not_legit.hexdigest():
print "Success!"
else:
print "Fail!"
An example run:
tethik@capncrunch:~/code/python/learningcrypto/md5$ python length-extension.py
Original payload: 6036708eba0d11f6ef52ad44e8b74d5b
0000: 73 65 63 72 65 74 64 61 74 61 80 00 00 00 00 00 secretdata......
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030: 00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 ........P.......
0040: 61 70 70 65 6E 64 append
Legit digest: 6ee582a1669ce442f3719c47430dadee
Illicit digest: 6ee582a1669ce442f3719c47430dadee
Success!