fragattacks/research/libwifi/mschap.py
Mathy Vanhoef 7f93c1cec7 fragattacks: directly track libwifi and not as submodule
This will make it easier for users to clone the repository and will
assure that they always use the correct version of libwifi.
2021-05-08 19:35:48 +04:00

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