# Copyright (c) 2003-2006 CORE Security Technologies # # This software is provided under under a slightly modified version # of the Apache Software License. See the accompanying LICENSE file # for more information. # # $Id: ntlm.py,v 1.2 2006/05/23 21:19:25 gera Exp $ # from impacket.structure import Structure try: from Crypto.Cipher import DES from Crypto.Hash import MD4 POW = None except Exception: try: import POW except Exception: pass NTLM_AUTH_NONE = 1 NTLM_AUTH_CONNECT = 2 NTLM_AUTH_CALL = 3 NTLM_AUTH_PKT = 4 NTLM_AUTH_PKT_INTEGRITY = 5 NTLM_AUTH_PKT_PRIVACY = 6 NTLMSSP_KEY_56 = 0x80000000 NTLMSSP_KEY_EXCHANGE = 0x40000000 NTLMSSP_KEY_128 = 0x20000000 # NTLMSSP_ = 0x10000000 # NTLMSSP_ = 0x08000000 # NTLMSSP_ = 0x04000000 # NTLMSSP_ = 0x02000000 # NTLMSSP_ = 0x01000000 NTLMSSP_TARGET_INFO = 0x00800000 # NTLMSSP_ = 0x00400000 # NTLMSSP_ = 0x00200000 # NTLMSSP_ = 0x00100000 NTLMSSP_NTLM2_KEY = 0x00080000 NTLMSSP_CHALL_NOT_NT = 0x00040000 NTLMSSP_CHALL_ACCEPT = 0x00020000 NTLMSSP_CHALL_INIT = 0x00010000 NTLMSSP_ALWAYS_SIGN = 0x00008000 # forces the other end to sign packets NTLMSSP_LOCAL_CALL = 0x00004000 NTLMSSP_WORKSTATION = 0x00002000 NTLMSSP_DOMAIN = 0x00001000 # NTLMSSP_ = 0x00000800 # NTLMSSP_ = 0x00000400 NTLMSSP_NTLM_KEY = 0x00000200 NTLMSSP_NETWARE = 0x00000100 NTLMSSP_LM_KEY = 0x00000080 NTLMSSP_DATAGRAM = 0x00000040 NTLMSSP_SEAL = 0x00000020 NTLMSSP_SIGN = 0x00000010 # means packet is signed, if verifier is wrong it fails # NTLMSSP_ = 0x00000008 NTLMSSP_TARGET = 0x00000004 NTLMSSP_OEM = 0x00000002 NTLMSSP_UNICODE = 0x00000001 class NTLMAuthHeader(Structure): commonHdr = ( ('auth_type', 'B=10'), ('auth_level','B'), ('auth_pad_len','B=0'), ('auth_rsvrd','"\x00'), ('auth_ctx_id','> 1) & 0x7f) << 1) s = s + chr(((ord(key[0]) & 0x01) << 6 | ((ord(key[1]) >> 2) & 0x3f)) << 1) s = s + chr(((ord(key[1]) & 0x03) << 5 | ((ord(key[2]) >> 3) & 0x1f)) << 1) s = s + chr(((ord(key[2]) & 0x07) << 4 | ((ord(key[3]) >> 4) & 0x0f)) << 1) s = s + chr(((ord(key[3]) & 0x0f) << 3 | ((ord(key[4]) >> 5) & 0x07)) << 1) s = s + chr(((ord(key[4]) & 0x1f) << 2 | ((ord(key[5]) >> 6) & 0x03)) << 1) s = s + chr(((ord(key[5]) & 0x3f) << 1 | ((ord(key[6]) >> 7) & 0x01)) << 1) s = s + chr((ord(key[6]) & 0x7f) << 1) return s def __DES_block(key, msg): if POW: cipher = POW.Symmetric(POW.DES_ECB) cipher.encryptInit(__expand_DES_key(key)) return cipher.update(msg) else: cipher = DES.new(__expand_DES_key(key),DES.MODE_ECB) return cipher.encrypt(msg) def ntlmssp_DES_encrypt(key, challenge): answer = __DES_block(key[:7], challenge) answer += __DES_block(key[7:14], challenge) answer += __DES_block(key[14:], challenge) return answer def compute_lmhash(password): # This is done according to Samba's encryption specification (docs/html/ENCRYPTION.html) password = password.upper() lmhash = __DES_block(password[:7], KNOWN_DES_INPUT) lmhash += __DES_block(password[7:14], KNOWN_DES_INPUT) return lmhash def compute_nthash(password): # This is done according to Samba's encryption specification (docs/html/ENCRYPTION.html) password = unicode(password).encode('utf_16le') if POW: hash = POW.Digest(POW.MD4_DIGEST) else: hash = MD4.new() hash.update(password) return hash.digest() def get_ntlmv1_response(key, challenge): return ntlmssp_DES_encrypt(key, challenge)