mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-01-31 01:04:03 -05:00
78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
|
#!/usr/bin/env python3
|
||
|
import binascii, struct
|
||
|
from Crypto.Hash import MD4, SHA
|
||
|
from Crypto.Cipher import DES
|
||
|
|
||
|
|
||
|
def des_encrypt(clear, key, offset):
|
||
|
cNext = 0
|
||
|
cWorking = 0
|
||
|
hexKey = {}
|
||
|
|
||
|
for x in range(0,8):
|
||
|
cWorking = 0xFF & key[x + offset]
|
||
|
hexKey[x] = ((cWorking >> x) | cNext | 1) & 0xFF
|
||
|
cWorking = 0xFF & key[x + offset]
|
||
|
cNext = ((cWorking << (7 - x)))
|
||
|
|
||
|
newKey = b""
|
||
|
for x in range(0, len(hexKey)):
|
||
|
newKey += struct.pack(">B", hexKey[x])
|
||
|
|
||
|
des = DES.new(newKey, DES.MODE_ECB)
|
||
|
return des.encrypt(clear)
|
||
|
|
||
|
def challenge_hash(peer_challenge, authenticator_challenge, username):
|
||
|
challenge = SHA.new(peer_challenge + authenticator_challenge + username).digest()
|
||
|
return challenge[0:8]
|
||
|
|
||
|
def nt_password_hash(password):
|
||
|
unicode_pw = password.encode("utf-16-le")
|
||
|
return MD4.new(unicode_pw).digest()
|
||
|
|
||
|
def hash_nt_password_hash(password_hash):
|
||
|
md4 = MD4.new()
|
||
|
md4.update(password_hash)
|
||
|
return md4.digest()
|
||
|
|
||
|
def challenge_response(challenge, pwhash):
|
||
|
# for some reason in python we need to pad an extra byte so that
|
||
|
# the offset works out correctly when we call DesEncrypt
|
||
|
pwhash += b'\x00' * (22 - len(pwhash))
|
||
|
|
||
|
response = b""
|
||
|
for x in range(0, 3):
|
||
|
encrypted = des_encrypt(challenge, pwhash, x * 7)
|
||
|
response += encrypted
|
||
|
|
||
|
return response
|
||
|
|
||
|
def generate_nt_response_mschap2(authenticator_challenge, peer_challenge, username, password):
|
||
|
challenge = challenge_hash(peer_challenge, authenticator_challenge, username)
|
||
|
password_hash = nt_password_hash(password)
|
||
|
return challenge_response(challenge, password_hash)
|
||
|
|
||
|
def generate_authenticator_response(password, nt_response, peer_challenge, authenticator_challenge, username):
|
||
|
magic1 = b"\x4D\x61\x67\x69\x63\x20\x73\x65\x72\x76\x65\x72\x20\x74\x6F\x20\x63\x6C\x69\x65\x6E\x74\x20\x73\x69\x67\x6E\x69\x6E\x67\x20\x63\x6F\x6E\x73\x74\x61\x6E\x74"
|
||
|
magic2 = b"\x50\x61\x64\x20\x74\x6F\x20\x6D\x61\x6B\x65\x20\x69\x74\x20\x64\x6F\x20\x6D\x6F\x72\x65\x20\x74\x68\x61\x6E\x20\x6F\x6E\x65\x20\x69\x74\x65\x72\x61\x74\x69\x6F\x6E"
|
||
|
|
||
|
password_hash = nt_password_hash(password)
|
||
|
password_hash_hash = hash_nt_password_hash(password_hash)
|
||
|
|
||
|
sha_hash = SHA.new()
|
||
|
sha_hash.update(password_hash_hash)
|
||
|
sha_hash.update(nt_response)
|
||
|
sha_hash.update(magic1)
|
||
|
digest = sha_hash.digest()
|
||
|
|
||
|
challenge = challenge_hash(peer_challenge, authenticator_challenge, username)
|
||
|
|
||
|
sha_hash = SHA.new()
|
||
|
sha_hash.update(digest)
|
||
|
sha_hash.update(challenge)
|
||
|
sha_hash.update(magic2)
|
||
|
digest = sha_hash.digest()
|
||
|
|
||
|
return digest
|
||
|
|