Example #1
0
 def test_md4_length_extension(self):
     """Challenge 30"""
     orig_message = 'comment1=cooking%20MCs;userdata=foo;comment2=%20like' \
             '%20a%20pound%20of%20bacon'
     # this is not known to attacker.
     key = Crypto.gen_random_key(43)
     suffix = ';admin=true;'
     orig_hash = md4(key + orig_message)
     forged_message = MD4Hash.pad(key + orig_message) + suffix
     forged_hash = md4(forged_message)
     validate = lambda h: h == forged_hash
     self.assertTrue(extend_md4(orig_hash, orig_message, suffix, validate))
Example #2
0
 def test_md4_length_extension(self):
     """Challenge 30"""
     orig_message = 'comment1=cooking%20MCs;userdata=foo;comment2=%20like' \
             '%20a%20pound%20of%20bacon'
     # this is not known to attacker.
     key = Crypto.gen_random_key(43)
     suffix = ';admin=true;'
     orig_hash = md4(key + orig_message)
     forged_message = MD4Hash.pad(key + orig_message) + suffix
     forged_hash = md4(forged_message)
     validate = lambda h: h == forged_hash
     self.assertTrue(extend_md4(orig_hash, orig_message, suffix, validate))
Example #3
0
def forgeHash(keylen, message, digest, suffix):
    paddedForgedMessageWithKey = padMD4(key + message) + suffix
    forgedMessage = paddedForgedMessageWithKey[keylen:]
    h = struct.unpack("<4I", digest)
    md4obj = md4.md4(h[0], h[1], h[2], h[3])
    md4obj.update(suffix)
    forgedDigest = md4obj.digest(len(paddedForgedMessageWithKey) * 8)
    return (forgedMessage, forgedDigest)
def forgeHash(keylen, message, digest, suffix):
    paddedForgedMessageWithKey = padMD4(key + message) + suffix
    forgedMessage = paddedForgedMessageWithKey[keylen:]
    h = struct.unpack('<4I', digest)
    md4obj = md4.md4(h)
    md4obj.update(suffix)
    forgedDigest = md4obj.digest(len(paddedForgedMessageWithKey) * 8)
    return (forgedMessage, forgedDigest)
Example #5
0
def assert_md4_state(b, expected_state_str, expected_hash_str):
    md4obj = md4.md4()
    md4obj.update(b)

    expected_s = expected_state_str.replace(' ', '')
    s = binascii.hexlify(md4obj.state_be()).decode('ascii')
    if s != expected_s:
        raise Exception('expected {}, got {}'.format(expected_s, s))

    expected_h = expected_hash_str.replace(' ', '')
    h = md4obj.hexdigest()
    if h != expected_h:
        raise Exception('expected {}, got {}'.format(expected_h, h))
def md4_length_attack(message, mac, extension):
    registers = get_registers(mac)

    for i in range(0, 40):
        padded_text = md4_pad('A' * i + message)
        registers = struct.unpack("<4I", mac)
        extended_message = padded_text[i:] + extension
        forged_mac = md4.md4(registers[0], registers[1], registers[2],
                             registers[3]).update(extension).digest(
                                 len(padded_text + extension) * 8)
        if validate_mac(extended_message, key, forged_mac) is True:
            return i, forged_mac

    return -1, ""
Example #7
0
def main():
	# create mac instance
	global key
	global key_min
	global key_max
	
		
	mac_gen = secret_prefix_mac(key, md4.md4)
	msg = """comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon"""
	mac = mac_gen.tag(msg)
	wanted_extension = ";admin=true"
	
	assert mac_gen.verify(msg, mac)
	
	print "The mac for the msg: \n%r\nis:" % (msg,)
	print "\t%r" % (mac.hexdigest(),)
	print "Trying to extend with %r" % (wanted_extension,)
	print
	
	
	print "Starting search from key lengths %d to %d" % (key_min, key_max)
	for i in range(key_min, key_max+1):
		# for each possible key length
		# generate a valid padding block for the original msg, truncating it to remove the key
		padded = md_pad(("A"*i) + msg, little_endian = True)[i:]
		 
		
		# create a new sha1 generator and splice in the original tag
		fake_tag = md4.md4()
		fake_tag._a, fake_tag._b, fake_tag._c, fake_tag._d = struct.unpack("<LLLL", mac.hexdigest().decode("hex"))   
		
		# extend the hash by hasing the extension, with a fake length value in the padding
		# the fake length value should reflect the length of the original block (512 bits) 
		# plus the length of the extension (in bits)
		fake_length = (i + len(padded) + len(wanted_extension)) * 8
		fake_tag._md4(wanted_extension, fake_length = fake_length)		
		
		# attempt to verify it 
		if mac_gen.verify(padded + wanted_extension, fake_tag):
			print "Success!" 
			print "Key length is %d, we succesfully verified the following msg:" % (i,)
			print repr(padded + wanted_extension)
			break
	else:
		print "Could not create a fake tag!"
Example #8
0
def check_weak_message(message):
    m = md4()
    m.update(message)
    a, b, c, d = m.intermediates

    assert get_bit(a[1], 7) == get_bit(b[0], 7)
    assert get_bit(d[1], 7) == 0
    return
    assert get_bit(d[1], 8) == get_bit(a[1], 8)
    assert get_bit(d[1], 11) == get_bit(a[1], 11)
    assert get_bit(c[1], 7) == 1
    assert get_bit(c[1], 8) == 1
    assert get_bit(c[1], 11) == 0
    assert get_bit(c[1], 26) == get_bit(d[1], 26)
    assert get_bit(b[1], 7) == 1
    assert get_bit(b[1], 8) == 0
    assert get_bit(b[1], 11) == 0
    assert get_bit(b[1], 26) == 0
Example #9
0
def make_weak_message(message):
    md = md4()
    md.update(message)
    a, b, c, d = md.intermediates

    m = message_numbers(message)

    # a17 = b07
    a[1] ^= xor_bit(a[1], b[0], 7)
    assert get_bit(a[1], 7) == get_bit(b[0], 7)
    m[0] = ror(a[1], 3) - a[0] - F(b[0], c[0], d[0])
    m[0] = m[0] & 0xffffffff

    assert a[1] == rol(a[0] + F(b[0], c[0], d[0]) + m[0], 3)
    assert get_bit(a[1], 7) == get_bit(b[0], 7)

    # d17 = 0
    d[1] ^= get_bit(d[1], 7) << 6
    
    return numbers_to_message(m)
def validate_mac(message, key, mac):
    output_mac = md4.md4().update(key + message).digest()
    if output_mac == mac:
        return True
    else:
        return False
Example #11
0
def smd4(msg):
    m = md4()
    m.update(msg)
    return m.hexdigest()
Example #12
0
from md4 import md4


md4_tests = [
    ('', '31d6cfe0d16ae931b73c59d7e0c089c0'),
    ("a",   'bde52cb31de33e46245e05fbdbd6fb24'),
    ("abc",   'a448017aaf21d8525fc10ae87aa6729d'),
    ("message digest",   'd9130a8164549fe818874806e1c7014b'),
    ("abcdefghijklmnopqrstuvwxyz",   'd79e1c308aa5bbcdeea8ed63df412da9'),
    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
    '043f8582f241db351ce627e153e7f0e4'),
    ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
    'e33b4ddc9c38f2199c3e7b164fcc0536'),
]

for test in md4_tests:

    if md4(test[0]) == test[1]:
        print "[+] {0}".format(test[0])
    else:
        print "[-] {0}".format(test[0])
Example #13
0
from __future__ import print_function
from md4 import md4
import sys

md4_tests = [
    ('', '31d6cfe0d16ae931b73c59d7e0c089c0'),
    ("a",   'bde52cb31de33e46245e05fbdbd6fb24'),
    ("abc",   'a448017aaf21d8525fc10ae87aa6729d'),
    ("message digest",   'd9130a8164549fe818874806e1c7014b'),
    ("abcdefghijklmnopqrstuvwxyz",   'd79e1c308aa5bbcdeea8ed63df412da9'),
    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
    '043f8582f241db351ce627e153e7f0e4'),
    ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
    'e33b4ddc9c38f2199c3e7b164fcc0536'),
]

for test in md4_tests:
    if md4(test[0]) == test[1]:
        print("[+] {0}".format(test[0]))
    else:
        print("[-] {0}".format(test[0]))
        assert 0

print("Passed assertions: " + __file__, file=sys.stderr)
Example #14
0
assert get_bit(1, 1) == 1
assert get_bit(2, 1) == 0
assert get_bit(2, 2) == 1

assert xor_bit(1, 1, 1) == 0
assert xor_bit(2, 2, 2) == 0
assert xor_bit(1, 2, 2) == 2

assert ror(0xdeadbeef, 4) == 0xfdeadbee
assert rol(0xdeadbeef, 4) == 0xeadbeefd

assert numbers_to_message(message_numbers(b'test' * 16)) == b'test' * 16

message = os.urandom(64)
m = md4()
m.update(message)

a, b, c, d = m.intermediates

assert a[0] == 0x67452301
assert b[0] == 0xefcdab89
assert c[0] == 0x98badcfe
assert d[0] == 0x10325476

assert len(message) == 64

weakened = make_weak_message(message)
print(hexlify(message))
print(hexlify(weakened))
check_weak_message(weakened)
def authMD4(key, message):
    md4obj = md4.md4()
    md4obj.update(key + message)
    return md4obj.digest()
Example #16
0
 def test_md4(self):
     text = "naresh"
     m = MD4.new()
     m.update(text)
     self.assertEquals(m.digest(), md4(text))

def get_registers(mac):
    return struct.unpack("<4I", mac)


def md4_length_attack(message, mac, extension):
    registers = get_registers(mac)

    for i in range(0, 40):
        padded_text = md4_pad('A' * i + message)
        registers = struct.unpack("<4I", mac)
        extended_message = padded_text[i:] + extension
        forged_mac = md4.md4(registers[0], registers[1], registers[2],
                             registers[3]).update(extension).digest(
                                 len(padded_text + extension) * 8)
        if validate_mac(extended_message, key, forged_mac) is True:
            return i, forged_mac

    return -1, ""


if __name__ == "__main__":
    message = b'comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon'
    mac = md4.md4().update(key + message).digest()

    key_len, forged_mac = md4_length_attack(message, mac, ';admin=true')

    print("The key length is {} with a forged MAC of {}".format(
        key_len, forged_mac.encode('hex')))
Example #18
0
def md4hex(message):
    md = md4()
    md.update(message)
    return md.hexdigest()
Example #19
0
def init_state(hexmac, blocks):
    binary = unhexlify(hexmac)
    int_parts = struct.unpack("<4I", binary)
    obj = md4(*int_parts)
    obj._count = blocks
    return obj        
Example #20
0
import md4
import os


def MAC(key: bytes, mess: bytes) -> bytes:
    return md4.md4(key + mess)


MESS = b'comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon'
KSIZ = 16
_KEY = os.urandom(KSIZ)  # SECRET
MAC0 = MAC(_KEY, MESS)
SUFF = b';admin=true'

if __name__ == '__main__':
    M = bytearray(KSIZ)  # 0-block for the unknown key
    M.extend(MESS)
    md4.pad(M)
    lold = len(M)
    # new message
    M.extend(SUFF)
    MESS1 = bytes(M[KSIZ:])
    print(MESS1)
    # forge a MAC
    md4.pad(M)
    MAC1 = md4.md4(M[lold:], MAC0, False)
    print(MAC1.hex())
    # check MAC validity
    assert MAC1 == MAC(_KEY, MESS1)
Example #21
0
    M[4] = (rrot(d, 5) - d0 - G(a, b, c) - 0x5a827999) & msk32
    # this one might interfere with the 4 conditions on a2,
    # so overall we get at most +4 new conditions
    # (+4 on d5  +  -0 to -4 on a2)
    A[2] = lrot((A[1] + F(B[1], C[1], D[1]) + M[4]) & msk32, 3)
    M[5] = (rrot(D[2], 7) - D[1] - F(A[2], B[1], C[1])) & msk32
    M[6] = (rrot(C[2], 11) - C[1] - F(D[2], A[2], B[1])) & msk32
    M[7] = (rrot(B[2], 19) - B[1] - F(C[2], D[2], A[2])) & msk32
    M[8] = (rrot(A[3], 3) - A[2] - F(B[2], C[2], D[2])) & msk32


if __name__ == '__main__':
    a0, b0, c0, d0 = md4.H0
    cnt = 1
    while True:
        M = md4.bytes_to_ints32(os.urandom(64))
        modification(M)
        Md = differential(M)
        if md4.compress(a0, b0, c0, d0, M) == md4.compress(a0, b0, c0, d0, Md):
            break
        cnt += 1
    M = md4.ints32_to_bytes(M)
    Md = md4.ints32_to_bytes(Md)
    print(f'Collision found ({cnt} tries):')
    print(f'M  = {M.hex()}')
    print(f"M' = {Md.hex()}")
    H = md4.md4(M)
    Hd = md4.md4(Md)
    assert H == Hd
    print(f'H  = {H.hex()}')
Example #22
0
def MAC(key: bytes, mess: bytes) -> bytes:
    return md4.md4(key + mess)
Example #23
0
def authMD4(key, message):
    md4obj = md4.md4()
    md4obj.update(key + message)
    return md4obj.digest()
Example #24
0
def md4hash(msg):
    obj = md4()
    obj.update(msg)
    return obj.hexdigest()
Example #25
0
def mac_tac(key, message):
    return md4.md4(key + message)
Example #26
0
def md4_hexdigest(m, msglen=None):
    md4obj = md4.md4()
    md4obj.update(m)
    return md4obj.hexdigest(msglen)
Example #27
0
 def test_md4(self):
     text = "naresh"
     m = MD4.new()
     m.update(text)
     self.assertEquals(m.digest(), md4(text))