MD5 Length Extension Attack

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. .. TEASER_END

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.

length-extension.py (Source)

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!