def __init__(self, flags, randomSessionKey): self.__flags = flags if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: self.__clientSigningKey = ntlm.SIGNKEY(self.__flags, randomSessionKey) self.__serverSigningKey = ntlm.SIGNKEY(self.__flags, randomSessionKey, "Server") self.__clientSealingKey = ntlm.SEALKEY(self.__flags, randomSessionKey) self.__serverSealingKey = ntlm.SEALKEY(self.__flags, randomSessionKey, "Server") # Preparing the keys handle states cipher3 = ARC4.new(self.__clientSealingKey) self.__clientSealingHandle = cipher3.encrypt cipher4 = ARC4.new(self.__serverSealingKey) self.__serverSealingHandle = cipher4.encrypt else: # Same key for everything self.__clientSigningKey = randomSessionKey self.__serverSigningKey = randomSessionKey self.__clientSealingKey = randomSessionKey self.__clientSealingKey = randomSessionKey cipher = ARC4.new(self.__clientSigningKey) self.__clientSealingHandle = cipher.encrypt self.__serverSealingHandle = cipher.encrypt self.__sequence = 0
def test_NetrLogonSamLogonEx(self): dce, rpctransport = self.connect() request = nrpc.NetrLogonSamLogonEx() request['LogonServer'] = '\x00' request['ComputerName'] = self.serverName + '\x00' request['LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation']['tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation']['LogonInteractive']['Identity']['LogonDomainName'] = self.domain request['LogonInformation']['LogonInteractive']['Identity']['ParameterControl'] = 2 + 2**14 + 2**7 + 2**9 + 2**5 + 2**11 request['LogonInformation']['LogonInteractive']['Identity']['UserName'] = self.username request['LogonInformation']['LogonInteractive']['Identity']['Workstation'] = '' if len(self.hashes) > 0: lmhash, nthash = self.hashes.split(':') lmhash = unhexlify(lmhash) nthash = unhexlify(nthash) else: lmhash = ntlm.LMOWFv1(self.password) nthash = ntlm.NTOWFv1(self.password) try: from Cryptodome.Cipher import ARC4 except Exception: print("Warning: You don't have any crypto installed. You need pycryptodomex") print("See https://pypi.org/project/pycryptodomex/") rc4 = ARC4.new(self.sessionKey) lmhash = rc4.encrypt(lmhash) rc4 = ARC4.new(self.sessionKey) nthash = rc4.encrypt(nthash) request['LogonInformation']['LogonInteractive']['LmOwfPassword'] = lmhash request['LogonInformation']['LogonInteractive']['NtOwfPassword'] = nthash request['ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4 request['ExtraFlags'] = 1 resp = dce.request(request) resp.dump()
def communicate(): serverHost = 'localhost' serverPort = 6703 randomLetter = random.choice(string.ascii_letters) arc4 = ARC4.new('warzone160\x00') with socket(AF_INET, SOCK_STREAM) as cc: cc.bind((serverHost, serverPort)) cc.listen(1) while True: print("Waiting for RAT to connect") (connectionSocket, addr) = cc.accept() print( "A connection has been established from this infected machine: ", addr) bufferSize = choices() message = "\xe4\x66\xbb\x29" message += "\x00\x00\x00" + bufferSize message += str(ord(randomLetter)) * 4 encrMessage = arc4.encrypt(message) connectionSocket.send(encrMessage) commands = list_getCodes(int(bufferSize)) for i in range(len(commands)): if commands[i] == "exit": return arc4 = ARC4.new('warzone160\x00') connectionSocket.send(arc4.encrypt(chr(commands[i]))) connectionSocket.close() print("Connection to host has been closed")
def default(self, line): if line.startswith('*'): line = line[1:] command = (line.strip('\n')+'\x00').encode('utf-16le') command = ARC4.new(self.key).encrypt(command) resp = mimilib.hMimiCommand(self.dce, self.pHandle, command) cipherText = b''.join(resp['encResult']) cipher = ARC4.new(self.key) print(cipher.decrypt(cipherText).decode('utf-16le'))
def test_NetrLogonSamLogonWithFlags(self): dce, rpctransport = self.connect() request = nrpc.NetrLogonSamLogonWithFlags() request['LogonServer'] = '\x00' request['ComputerName'] = self.serverName + '\x00' request[ 'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation'][ 'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation']['LogonInteractive']['Identity'][ 'LogonDomainName'] = self.domain request['LogonInformation']['LogonInteractive']['Identity'][ 'ParameterControl'] = 2 + 2**14 + 2**7 + 2**9 + 2**5 + 2**11 request['LogonInformation']['LogonInteractive']['Identity'][ 'UserName'] = self.username request['LogonInformation']['LogonInteractive']['Identity'][ 'Workstation'] = '' if len(self.hashes) > 0: lmhash, nthash = self.hashes.split(':') lmhash = unhexlify(lmhash) nthash = unhexlify(nthash) else: lmhash = ntlm.LMOWFv1(self.password) nthash = ntlm.NTOWFv1(self.password) try: from Cryptodome.Cipher import ARC4 except Exception: print( "Warning: You don't have any crypto installed. You need pycryptodomex" ) print("See https://pypi.org/project/pycryptodomex/") rc4 = ARC4.new(self.sessionKey) lmhash = rc4.encrypt(lmhash) rc4 = ARC4.new(self.sessionKey) nthash = rc4.encrypt(nthash) request['LogonInformation']['LogonInteractive'][ 'LmOwfPassword'] = lmhash request['LogonInformation']['LogonInteractive'][ 'NtOwfPassword'] = nthash request[ 'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4 request['Authenticator'] = self.update_authenticator() request['ReturnAuthenticator']['Credential'] = b'\x00' * 8 request['ReturnAuthenticator']['Timestamp'] = 0 request['ExtraFlags'] = 0 try: resp = dce.request(request) resp.dump() except Exception as e: if str(e).find('STATUS_NO_SUCH_USER') < 0: raise
def test_NetrLogonSamLogon(self): dce, rpctransport = self.connect() self.authenticate(dce) request = nrpc.NetrLogonSamLogon() request['LogonServer'] = self.serverName + '\x00' request['ComputerName'] = self.machine_user + '\x00' request[ 'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation'][ 'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation']['LogonInteractive']['Identity'][ 'LogonDomainName'] = self.domain request['LogonInformation']['LogonInteractive']['Identity'][ 'ParameterControl'] = 2 request['LogonInformation']['LogonInteractive']['Identity'][ 'UserName'] = self.username request['LogonInformation']['LogonInteractive']['Identity'][ 'Workstation'] = '' if len(self.hashes): blmhash = self.blmhash bnthash = self.bnthash else: blmhash = ntlm.LMOWFv1(self.password) bnthash = ntlm.NTOWFv1(self.password) try: from Cryptodome.Cipher import ARC4 except Exception: print( "Warning: You don't have any crypto installed. You need PyCrypto" ) print("See http://www.pycrypto.org/") rc4 = ARC4.new(self.sessionKey) blmhash = rc4.encrypt(blmhash) rc4 = ARC4.new(self.sessionKey) bnthash = rc4.encrypt(bnthash) request['LogonInformation']['LogonInteractive'][ 'LmOwfPassword'] = blmhash request['LogonInformation']['LogonInteractive'][ 'NtOwfPassword'] = bnthash request[ 'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo2 request['Authenticator'] = self.update_authenticator() request['ReturnAuthenticator']['Credential'] = b'\x00' * 8 request['ReturnAuthenticator']['Timestamp'] = 0 try: dce.request(request) except DCERPCException as e: if str(e).find('STATUS_NO_SUCH_USER') < 0: raise
def test_NetrLogonSamLogonEx(self): dce, rpctransport = self.connect() self.authenticate(dce) request = nrpc.NetrLogonSamLogonEx() request['LogonServer'] = self.serverName + '\x00' request['ComputerName'] = self.machine_user + '\x00' request[ 'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation'][ 'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation']['LogonInteractive']['Identity'][ 'LogonDomainName'] = self.domain request['LogonInformation']['LogonInteractive']['Identity'][ 'ParameterControl'] = 2 + 2**14 + 2**7 + 2**9 + 2**5 + 2**11 request['LogonInformation']['LogonInteractive']['Identity'][ 'UserName'] = self.username request['LogonInformation']['LogonInteractive']['Identity'][ 'Workstation'] = '' if len(self.hashes): blmhash = self.blmhash bnthash = self.bnthash else: blmhash = ntlm.LMOWFv1(self.password) bnthash = ntlm.NTOWFv1(self.password) try: from Cryptodome.Cipher import ARC4 except Exception: print( "Warning: You don't have any crypto installed. You need pycryptodomex" ) print("See https://pypi.org/project/pycryptodomex/") rc4 = ARC4.new(self.sessionKey) blmhash = rc4.encrypt(blmhash) rc4 = ARC4.new(self.sessionKey) bnthash = rc4.encrypt(bnthash) request['LogonInformation']['LogonInteractive'][ 'LmOwfPassword'] = blmhash request['LogonInformation']['LogonInteractive'][ 'NtOwfPassword'] = bnthash request[ 'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4 request['ExtraFlags'] = 1 try: dce.request(request) except DCERPCException as e: if str(e).find('STATUS_INTERNAL_ERROR') < 0: raise
def encrypt(cls, key, keyusage, plaintext, confounder): if confounder is None: confounder = get_random_bytes(8) ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() cksum = HMAC.new(ki, confounder + plaintext, MD5).digest() ke = HMAC.new(ki, cksum, MD5).digest() return cksum + ARC4.new(ke).encrypt(bytes(confounder + plaintext))
def decrypt(key: str, enc: bytes) -> str: # decrypt a given base64 bytes object. returns a string enc = base64.b64decode(enc) nonce = enc[:16] tempkey = SHA.new(key + nonce).digest() cipher = ARC4.new(tempkey) return cipher.decrypt(enc[16:]).decode("utf-8")
def getHBootKey(self): logger.debug('Calculating HashedBootKey from SAM') QWERTY = b"!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\0" DIGITS = b"0123456789012345678901234567890123456789\0" F = self.getValue(ntpath.join(r'SAM\Domains\Account', 'F'))[1] domainData = DOMAIN_ACCOUNT_F(F) if domainData['Key0'][0:1] == b'\x01': samKeyData = SAM_KEY_DATA(domainData['Key0']) rc4Key = self.MD5(samKeyData['Salt'] + QWERTY + self.__bootKey + DIGITS) rc4 = ARC4.new(rc4Key) self.__hashedBootKey = rc4.encrypt(samKeyData['Key'] + samKeyData['CheckSum']) # Verify key with checksum checkSum = self.MD5(self.__hashedBootKey[:16] + DIGITS + self.__hashedBootKey[:16] + QWERTY) if checkSum != self.__hashedBootKey[16:]: raise Exception( 'hashedBootKey CheckSum failed, Syskey startup password probably in use! :(' ) elif domainData['Key0'][0:1] == b'\x02': # This is Windows 2016 TP5 on in theory (it is reported that some W10 and 2012R2 might behave this way also) samKeyData = SAM_KEY_DATA_AES(domainData['Key0']) self.__hashedBootKey = self.__cryptoCommon.decryptAES( self.__bootKey, samKeyData['Data'][:samKeyData['DataLen']], samKeyData['Salt'])
def __decryptHash(self, key, value, iv): hmac_md5 = HMAC.new(key, iv) rc4key = hmac_md5.digest() rc4 = ARC4.new(rc4key) data = rc4.encrypt(value) return data
def __getPek(self): logger.info('Searching for pekList, be patient') pek = None while True: record = self.__ESEDB.getNextRow(self.__cursor) if record is None: break elif record[self.NAME_TO_INTERNAL['pekList']] is not None: pek = record[self.NAME_TO_INTERNAL['pekList']].decode('hex') break elif record[self.NAME_TO_INTERNAL[ 'sAMAccountType']] in self.ACCOUNT_TYPES: # Okey.. we found some users, but we're not yet ready to process them. # Let's just store them in a temp list self.__tmpUsers.append(record) if pek is not None: encryptedPek = self.PEK_KEY(pek) md5 = hashlib.new('md5') md5.update(self.__bootKey) for i in range(1000): md5.update(encryptedPek['KeyMaterial']) tmpKey = md5.digest() rc4 = ARC4.new(tmpKey) plainText = rc4.encrypt(encryptedPek['EncryptedPek']) self.__PEK = plainText[36:]
def extract_config(filebuf): yara_hit = yara_scan(filebuf) for hit in yara_hit: if hit.rule == "IcedID": # can be either a dll or a exe enc_data = None try: pe = pefile.PE(data=filebuf, fast_load=True) for section in pe.sections: if section.Name == b".data\x00\x00\x00": enc_data = section.get_data() key = enc_data[:8] enc_config = enc_data[8:592] decrypted_data = ARC4.new(key).decrypt(enc_config) config = list( filter(None, decrypted_data.split(b"\x00"))) return { "Bot ID": str(struct.unpack("I", decrypted_data[:4])[0]), "Minor Version": str(struct.unpack("I", decrypted_data[4:8])[0]), "Path": config[1], "address": [controller[1:] for controller in config[2:]], } except Exception as e: log.error("Error: %s", e) return {}
def execute(self): key = self.pad(bytes(self.key, encoding="utf-8"), 16) cipher = ARC4.new(key) text = bytes(self.text, encoding="utf-8") encrypted_text = cipher.encrypt(text) return encrypted_text
def decrypt_string(password_string, need_return=False): if not is_number(VERSION): raise ValueError('Invalid argument: --Version') ver = float(VERSION) Cipher = ARC4.new(getCipherKey()) try: if ver < 5.1: de_password = Cipher.decrypt(b64decode(password_string)).decode() else: data = b64decode(password_string) ciphertext, checksum = data[:-SHA256.digest_size], data[ -SHA256.digest_size:] plaintext = Cipher.decrypt(ciphertext) if SHA256.new(plaintext).digest() != checksum: raise ValueError('Cannot decrypt string. The key is wrong!') de_password = plaintext.decode('ascii') if need_return: return de_password else: print('%-20s : %s' % ('Version', VERSION)) print('%-20s : %s' % ('Password', password_string)) print('%-20s : %s' % ('Decrypted Password', de_password)) except Exception as e: print("Password is invalid")
def session_key(self): if self.auth_flags & NTLMSSP_NEGOTIATE_KEY_EXCH: r = RC4.new(self.key_exchange_key) self.exported_session_key = nonce(16) return r.encrypt(self.exported_session_key.tobytes()) else: self.exported_session_key = self.key_exchange_key
def session_key(self): if self.auth_flags & NTLMSSP_NEGOTIATE_KEY_EXCH: r = RC4.new(self.key_exchange_key) self.exported_session_key = nonce(16) return r.encrypt(self.exported_session_key.tostring()) else: self.exported_session_key = self.key_exchange_key
def GSS_GetMIC(self, sessionKey, data, sequenceNumber, direction='init'): GSS_GETMIC_HEADER = '\x60\x23\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02' token = self.MIC() # Let's pad the data pad = (4 - (len(data) % 4)) & 0x3 padStr = chr(pad) * pad data += padStr token['SGN_ALG'] = GSS_HMAC if direction == 'init': token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\x00' * 4 else: token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\xff' * 4 Ksign = HMAC.new(sessionKey.contents, 'signaturekey\0', MD5).digest() Sgn_Cksum = MD5.new(struct.pack('<L', 15) + str(token)[:8] + data).digest() Sgn_Cksum = HMAC.new(Ksign, Sgn_Cksum, MD5).digest() token['SGN_CKSUM'] = Sgn_Cksum[:8] Kseq = HMAC.new(sessionKey.contents, struct.pack('<L', 0), MD5).digest() Kseq = HMAC.new(Kseq, token['SGN_CKSUM'], MD5).digest() token['SND_SEQ'] = ARC4.new(Kseq).encrypt(token['SND_SEQ']) finalData = GSS_GETMIC_HEADER + token.getData() return finalData
def solve(): dec = base64.b64decode( "MzU5OThmZGI3ZmUzYjc5NDBiOTM3NWE2OGE2NTRmZjk0OWM1OGRjYjliMWFlYmIwNDhkNmFhNzRkOTA1YjdiMGM2ZTA0YjQwNGViNjExMjlmOTJhZDkxMjcwMzg1MDIwMTU4MmNlMzllNzdiZmU3MzlmZWM1Mjg3NDFiMjAyZjg5MjNhOWY4ZDYzMDM2MTdkOGU2ZTM1YTBkNjQ0MTE1ZTIzODUyMmM2ZDBjYWNkMWFmZGFlMjMwNTA0NTJjOTk4ZTM5YQ==" ) khash = dec[:40].decode("hex") msg = dec[40:].decode("hex") print(dec) cipher1 = ARC4.new(khash) print(cipher1.decrypt(msg)) id = "\xd1" n = hex(ord(id) + bs) key = "2f87011fadc6c2f7376117867621b606".decode("hex") iv = "95bc0ed56ab0e730b64cce91c9fe9390".decode("hex") key = ('').join((chr(ord(x) ^ int(n, 16)) for x in key)) iv = ('').join((chr(ord(y) ^ int(n, 16)) for y in iv)) keyout = open(keyfile, "wb") keyout.write(key) keyout.write(iv) keyout.close() decrypt()
def GSS_GetMIC(self, sessionKey, data, sequenceNumber, direction = 'init'): GSS_GETMIC_HEADER = '\x60\x23\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02' token = self.MIC() # Let's pad the data pad = (4 - (len(data) % 4)) & 0x3 padStr = chr(pad) * pad data += padStr token['SGN_ALG'] = GSS_HMAC if direction == 'init': token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\x00'*4 else: token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\xff'*4 Ksign = HMAC.new(sessionKey.contents, 'signaturekey\0', MD5).digest() Sgn_Cksum = MD5.new( struct.pack('<L',15) + str(token)[:8] + data).digest() Sgn_Cksum = HMAC.new(Ksign, Sgn_Cksum, MD5).digest() token['SGN_CKSUM'] = Sgn_Cksum[:8] Kseq = HMAC.new(sessionKey.contents, struct.pack('<L',0), MD5).digest() Kseq = HMAC.new(Kseq, token['SGN_CKSUM'], MD5).digest() token['SND_SEQ'] = ARC4.new(Kseq).encrypt(token['SND_SEQ']) finalData = GSS_GETMIC_HEADER + token.getData() return finalData
def test_MimiCommand(self): dce, rpctransport, pHandle, key = self.connect() from Cryptodome.Cipher import ARC4 cipher = ARC4.new(key[::-1]) command = cipher.encrypt('token::whoami\x00'.encode('utf-16le')) #command = cipher.encrypt('sekurlsa::logonPasswords\x00'.encode('utf-16le')) #command = cipher.encrypt('process::imports\x00'.encode('utf-16le')) request = mimilib.MimiCommand() request['phMimi'] = pHandle request['szEncCommand'] = len(command) request['encCommand'] = list(command) resp = dce.request(request) cipherText = ''.join(resp['encResult']) cipher = ARC4.new(key[::-1]) plain = cipher.decrypt(cipherText) print '='*80 print plain
def encrypt_string(self, spassowrd): spassowrd = bytes(spassowrd, encoding='utf8') sid = bytes(self.sid, encoding='utf8') # print(sid) cipher = ARC4.new(SHA256.new(sid).digest()) checksum = SHA256.new(spassowrd).digest() ciphertext = cipher.encrypt(spassowrd) return b64encode(ciphertext + checksum).decode()
def test_MimiCommand(self): dce, rpctransport, pHandle, key = self.connect() from Cryptodome.Cipher import ARC4 cipher = ARC4.new(key[::-1]) command = cipher.encrypt('token::whoami\x00'.encode('utf-16le')) #command = cipher.encrypt('sekurlsa::logonPasswords\x00'.encode('utf-16le')) #command = cipher.encrypt('process::imports\x00'.encode('utf-16le')) request = mimilib.MimiCommand() request['phMimi'] = pHandle request['szEncCommand'] = len(command) request['encCommand'] = list(command) resp = dce.request(request) cipherText = b''.join(resp['encResult']) cipher = ARC4.new(key[::-1]) plain = cipher.decrypt(cipherText) print('=' * 80) print(plain)
def decrypt_string(self, lpassowrd): v1 = base64.b64decode(lpassowrd) v3 = ARC4.new(SHA256.new(self.sid.encode('ascii')).digest()).decrypt( v1[:len(v1) - 0x20]) if SHA256.new(v3).digest() == v1[-32:]: return v3.decode('ascii') else: return None
def __removeRC4Layer(self, cryptedHash): md5 = hashlib.new('md5') md5.update(self.__PEK) md5.update(cryptedHash['KeyMaterial']) tmpKey = md5.digest() rc4 = ARC4.new(tmpKey) plainText = rc4.encrypt(cryptedHash['EncryptedHash']) return plainText
def test_NetrLogonSamLogon(self): dce, rpctransport = self.connect() request = nrpc.NetrLogonSamLogon() request['LogonServer'] = '\x00' request['ComputerName'] = self.serverName + '\x00' request['LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation']['tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation request['LogonInformation']['LogonInteractive']['Identity']['LogonDomainName'] = self.domain request['LogonInformation']['LogonInteractive']['Identity']['ParameterControl'] = 2 request['LogonInformation']['LogonInteractive']['Identity']['UserName'] = self.username request['LogonInformation']['LogonInteractive']['Identity']['Workstation'] = '' if len(self.hashes) > 0: lmhash, nthash = self.hashes.split(':') lmhash = unhexlify(lmhash) nthash = unhexlify(nthash) else: lmhash = ntlm.LMOWFv1(self.password) nthash = ntlm.NTOWFv1(self.password) try: from Cryptodome.Cipher import ARC4 except Exception: print("Warning: You don't have any crypto installed. You need PyCrypto") print("See http://www.pycrypto.org/") rc4 = ARC4.new(self.sessionKey) lmhash = rc4.encrypt(lmhash) rc4 = ARC4.new(self.sessionKey) nthash = rc4.encrypt(nthash) request['LogonInformation']['LogonInteractive']['LmOwfPassword'] = lmhash request['LogonInformation']['LogonInteractive']['NtOwfPassword'] = nthash request['ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo2 request['Authenticator'] = self.update_authenticator() request['ReturnAuthenticator']['Credential'] = b'\x00' * 8 request['ReturnAuthenticator']['Timestamp'] = 0 try: resp = dce.request(request) resp.dump() except Exception as e: if str(e).find('STATUS_NO_SUCH_USER') < 0: raise
def test_hMimiCommand(self): dce, rpc_transport = self.connect() pHandle, key = self.get_handle_key(dce) cipher = ARC4.new(key[::-1]) command = cipher.encrypt("{}\x00".format(self.mimikatz_command).encode('utf-16le')) resp = mimilib.hMimiCommand(dce, pHandle, command) self.assertEqual(resp["ErrorCode"], 0) self.assertEqual(len(resp["encResult"]), resp["szEncResult"]) dce.disconnect() rpc_transport.disconnect()
def test_MimiCommand(self): dce, rpc_transport = self.connect() pHandle, key = self.get_handle_key(dce) cipher = ARC4.new(key[::-1]) command = cipher.encrypt("{}\x00".format(self.mimikatz_command).encode('utf-16le')) request = mimilib.MimiCommand() request['phMimi'] = pHandle request['szEncCommand'] = len(command) request['encCommand'] = list(command) resp = dce.request(request) self.assertEqual(resp["ErrorCode"], 0) self.assertEqual(len(resp["encResult"]), resp["szEncResult"]) cipherText = b''.join(resp['encResult']) cipher = ARC4.new(key[::-1]) plain = cipher.decrypt(cipherText) dce.disconnect() rpc_transport.disconnect()
def rc4(key: bytes, data: bytes) -> bytes: """ Encrypts/decrypts buffer using RC4 algorithm :param key: Cryptographic key (from 3 to 256 bytes) :type key: bytes :param data: Buffer to be encrypted/decrypted :type data: bytes :return: Encrypted/decrypted data :rtype: bytes """ return ARC4.new(key).decrypt(data)
def decrypt_data3(data): if not data: return hash_obj = hashlib.sha1(b"\\System32\\WindowsPowerShel1\\v1.0\\powershel1.exe") rc4_key = hash_obj.digest() decrypted_data = ARC4.new(rc4_key).decrypt(data) if not decrypted_data: return return decrypted_data
def test_keystream(self): for tv in self.rfc6229_data: key = unhexlify(b((tv[0]))) cipher = ARC4.new(key) count = 0 for offset in range(0, 4096 + 1, 16): ct = cipher.encrypt(b('\x00') * 16) expected = tv[1].get(offset) if expected: expected = unhexlify(b(expected.replace(" ", ''))) self.assertEquals(ct, expected) count += 1 self.assertEqual(count, len(tv[1]))
def test_keystream(self): for tv in self.rfc6229_data: key = unhexlify(b((tv[0]))) cipher = ARC4.new(key) count = 0 for offset in range(0,4096+1,16): ct = cipher.encrypt(b('\x00')*16) expected = tv[1].get(offset) if expected: expected = unhexlify(b(expected.replace(" ",''))) self.assertEquals(ct, expected) count += 1 self.assertEqual(count, len(tv[1]))
def __init__(self, flags, randomSessionKey): self.__flags = flags if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: self.__clientSigningKey = ntlm.SIGNKEY(self.__flags, randomSessionKey) self.__serverSigningKey = ntlm.SIGNKEY(self.__flags, randomSessionKey,"Server") self.__clientSealingKey = ntlm.SEALKEY(self.__flags, randomSessionKey) self.__serverSealingKey = ntlm.SEALKEY(self.__flags, randomSessionKey,"Server") # Preparing the keys handle states cipher3 = ARC4.new(self.__clientSealingKey) self.__clientSealingHandle = cipher3.encrypt cipher4 = ARC4.new(self.__serverSealingKey) self.__serverSealingHandle = cipher4.encrypt else: # Same key for everything self.__clientSigningKey = randomSessionKey self.__serverSigningKey = randomSessionKey self.__clientSealingKey = randomSessionKey self.__clientSealingKey = randomSessionKey cipher = ARC4.new(self.__clientSigningKey) self.__clientSealingHandle = cipher.encrypt self.__serverSealingHandle = cipher.encrypt self.__sequence = 0
def decrypt(self, file_path, password): private_key = self.get_private_key(password) if private_key is None: return {'status': False, 'msg': "Cannot get private key"} with open(file_path, 'rb') as fi: try: msg = json.loads(fi.read()) except ValueError: return {'status': False, 'msg': "File structure is damaged"} for key, value in msg.iteritems(): msg[key] = b64decode(value) secret_key = PKCS1_OAEP.new(private_key).decrypt(msg['secret_key']) try: # init cipher if msg['alg'] == ALG_OPTIONS[0]: cipher = AES.new(secret_key, AES.MODE_EAX, msg['nonce']) elif msg['alg'] == ALG_OPTIONS[1]: cipher = AES.new(secret_key, AES.MODE_OCB, msg['nonce']) elif msg['alg'] == ALG_OPTIONS[2]: cipher = AES.new(secret_key, AES.MODE_CFB, msg['iv']) elif msg['alg'] == ALG_OPTIONS[3]: cipher = AES.new(secret_key, AES.MODE_CTR, msg['nonce']) elif msg['alg'] == ALG_OPTIONS[4]: cipher = DES.new(secret_key, DES.MODE_OFB, iv=msg['iv']) elif msg['alg'] == ALG_OPTIONS[5]: cipher = ARC2.new(secret_key, ARC2.MODE_CFB) elif msg['alg'] == ALG_OPTIONS[6]: cipher = ARC4.new(secret_key) elif msg['alg'] == ALG_OPTIONS[7]: cipher = ChaCha20.new(key=secret_key, nonce=msg['nonce']) elif msg['alg'] == ALG_OPTIONS[8]: cipher = Salsa20.new(key=secret_key, nonce=msg['nonce']) else: return {'status': False, 'msg': "Cannot define the algorithm used to encrypt this file"} # decrypt and verify if msg['alg'] in ALG_OPTIONS[1:3]: decrypted_msg = cipher.decrypt_and_verify(msg['cipher_text'], msg['tag']) elif msg['alg'] in ALG_OPTIONS[3:]: decrypted_msg = cipher.decrypt(msg['cipher_text']) SHA256.new(decrypted_msg).hexdigest(), msg['tag'] if SHA256.new(decrypted_msg).hexdigest() != msg['tag']: raise ValueError else: return {'status': False, 'msg': "Cannot define the algorithm used to encrypt this file"} except ValueError, KeyError: return {'status': False, 'msg': "Decrypt failed, you are not the owner of this file"} dir_path, file_name = os.path.split(file_path) with open(dir_path + '/' + msg['file_name'], 'wb') as fo: fo.write(decrypted_msg) return {'status': True, 'msg': "Successfully decrypted file %s" % file_path}
def decrypt(cls, key, keyusage, ciphertext): if len(ciphertext) < 24: raise ValueError('ciphertext too short') cksum, basic_ctext = bytearray(ciphertext[:16]), bytearray(ciphertext[16:]) ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() ke = HMAC.new(ki, cksum, MD5).digest() basic_plaintext = bytearray(ARC4.new(ke).decrypt(bytes(basic_ctext))) exp_cksum = bytearray(HMAC.new(ki, basic_plaintext, MD5).digest()) ok = _mac_equal(cksum, exp_cksum) if not ok and keyusage == 9: # Try again with usage 8, due to RFC 4757 errata. ki = HMAC.new(key.contents, pack('<I', 8), MD5).digest() exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest() ok = _mac_equal(cksum, exp_cksum) if not ok: raise InvalidChecksum('ciphertext integrity failure') # Discard the confounder. return bytes(basic_plaintext[8:])
def decrypt_data(data): """ Decrypts the data using the last 20 bytes as a rc4 key. Validates the decryption with the sha1 sum contained within the first 20 bytes of the decrypted data. """ if not data: return key = data[:0x14] decrypted_data = ARC4.new(key).decrypt(data[0x14:]) if not decrypted_data: return if hashlib.sha1(decrypted_data[0x14:]).digest() != decrypted_data[:0x14]: return return decrypted_data[0x14:]
def decrypt(cls, key, keyusage, ciphertext): if len(ciphertext) < 24: raise ValueError('ciphertext too short') cksum, basic_ctext = ciphertext[:16], ciphertext[16:] ki = HMAC.new(key.contents, cls.usage_str(keyusage), MD5).digest() ke = HMAC.new(ki, cksum, MD5).digest() basic_plaintext = ARC4.new(ke).decrypt(basic_ctext) exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest() ok = _mac_equal(cksum, exp_cksum) if not ok and keyusage == 9: # Try again with usage 8, due to RFC 4757 errata. ki = HMAC.new(key.contents, pack('<I', 8), MD5).digest() exp_cksum = HMAC.new(ki, basic_plaintext, MD5).digest() ok = _mac_equal(cksum, exp_cksum) if not ok: raise InvalidChecksum('ciphertext integrity failure') # Discard the confounder. return basic_plaintext[8:]
def extract_config(filebuf): config = {} try: pe = pefile.PE(data=filebuf) blob = False ResourceData = get_rsrc(pe) for rsrc in ResourceData: if rsrc[0] in ("RT_RCDATA", "SETTINGS"): blob = rsrc[1] break if blob: keylen = blob[0] key = blob[1 : keylen + 1] decrypted_data = ARC4.new(key).decrypt(blob[keylen + 1 :]) p_data = OrderedDict() p_data["Version"] = check_version(filebuf) configs = re.split(rb"\|\x1e\x1e\x1f\|", decrypted_data) for i, cont in enumerate(configs): if cont in (b"\x00", b"\x01"): p_data[idx_list[i]] = FLAG[cont] elif i in (9, 16, 25, 37): p_data[idx_list[i]] = setup_list[int(cont)] elif i in (56, 57, 58): p_data[idx_list[i]] = base64.b64encode(cont) elif i == 0: host, port, password = cont.split(b"|", 1)[0].split(b":") p_data["Control"] = f"tcp://{host.decode()}:{port.decode()}:{password.decode()}" else: p_data[idx_list[i]] = cont for k, v in p_data.items(): if k in utf_16_string_list: v = v.decode("utf16").strip("\00") config[k] = v except Exception as e: logger.error(f"Caught an exception: {e}") return config
def DecryptAttributeValue(dce, attribute): sessionKey = dce.get_session_key() # Is it a Kerberos Session Key? if isinstance(sessionKey, crypto.Key): # Extract its contents and move on sessionKey = sessionKey.contents encryptedPayload = ENCRYPTED_PAYLOAD(attribute) md5 = hashlib.new('md5') md5.update(sessionKey) md5.update(encryptedPayload['Salt']) finalMD5 = md5.digest() cipher = ARC4.new(finalMD5) plainText = cipher.decrypt(attribute[16:]) #chkSum = (binascii.crc32(plainText[4:])) & 0xffffffff #if unpack('<L',plainText[:4])[0] != chkSum: # print "RECEIVED 0x%x" % unpack('<L',plainText[:4])[0] # print "CALCULATED 0x%x" % chkSum return plainText[4:]
def GSS_Wrap(self, sessionKey, data, sequenceNumber, direction = 'init', encrypt=True, authData=None): # Damn inacurate RFC, useful info from here # https://social.msdn.microsoft.com/Forums/en-US/fb98e8f4-e697-4652-bcb7-604e027e14cc/gsswrap-token-size-kerberos-and-rc4hmac?forum=os_windowsprotocols # and here # https://www.rfc-editor.org/errata_search.php?rfc=4757 GSS_WRAP_HEADER = '\x60\x2b\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02' token = self.WRAP() # Let's pad the data pad = (8 - (len(data) % 8)) & 0x7 padStr = chr(pad) * pad data += padStr token['SGN_ALG'] = GSS_HMAC token['SEAL_ALG'] = GSS_RC4 if direction == 'init': token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\x00'*4 else: token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\xff'*4 # Random confounder :) token['Confounder'] = ''.join([rand.choice(string.letters) for _ in range(8)]) Ksign = HMAC.new(sessionKey.contents, 'signaturekey\0', MD5).digest() Sgn_Cksum = MD5.new(struct.pack('<L',13) + str(token)[:8] + token['Confounder'] + data).digest() Klocal = '' for n in sessionKey.contents: Klocal += chr(ord(n) ^ 0xF0) Kcrypt = HMAC.new(Klocal,struct.pack('<L',0), MD5).digest() Kcrypt = HMAC.new(Kcrypt,struct.pack('>L', sequenceNumber), MD5).digest() Sgn_Cksum = HMAC.new(Ksign, Sgn_Cksum, MD5).digest() token['SGN_CKSUM'] = Sgn_Cksum[:8] Kseq = HMAC.new(sessionKey.contents, struct.pack('<L',0), MD5).digest() Kseq = HMAC.new(Kseq, token['SGN_CKSUM'], MD5).digest() token['SND_SEQ'] = ARC4.new(Kseq).encrypt(token['SND_SEQ']) if authData is not None: from impacket.dcerpc.v5.rpcrt import SEC_TRAILER wrap = self.WRAP(authData[len(SEC_TRAILER()) + len(GSS_WRAP_HEADER):]) snd_seq = wrap['SND_SEQ'] Kseq = HMAC.new(sessionKey.contents, struct.pack('<L',0), MD5).digest() Kseq = HMAC.new(Kseq, wrap['SGN_CKSUM'], MD5).digest() snd_seq = ARC4.new(Kseq).encrypt(wrap['SND_SEQ']) Kcrypt = HMAC.new(Klocal,struct.pack('<L',0), MD5).digest() Kcrypt = HMAC.new(Kcrypt,snd_seq[:4], MD5).digest() rc4 = ARC4.new(Kcrypt) cipherText = rc4.decrypt(token['Confounder'] + data)[8:] elif encrypt is True: rc4 = ARC4.new(Kcrypt) token['Confounder'] = rc4.encrypt(token['Confounder']) cipherText = rc4.encrypt(data) else: cipherText = data finalData = GSS_WRAP_HEADER + token.getData() return cipherText, finalData
def generateEncryptedSessionKey(keyExchangeKey, exportedSessionKey): cipher = ARC4.new(keyExchangeKey) cipher_encrypt = cipher.encrypt sessionKey = cipher_encrypt(exportedSessionKey) return sessionKey
def setUp(self): self.cipher = ARC4.new(self.key)
def test_drop256_encrypt(self): cipher_drop = ARC4.new(self.key, 256) ct_drop = cipher_drop.encrypt(self.data[:16]) ct = self.cipher.encrypt(self.data)[256:256+16] self.assertEquals(ct_drop, ct)
def test_drop256_decrypt(self): cipher_drop = ARC4.new(self.key, 256) pt_drop = cipher_drop.decrypt(self.data[:16]) pt = self.cipher.decrypt(self.data)[256:256+16] self.assertEquals(pt_drop, pt)
def test_ntlmv1(self): print("####### 4.2.2 NTLMv1 Authentication") ntlm.USE_NTLMv2 = False print("4.2.2.1 LMOWFv1()") res = ntlm.LMOWFv1(self.password) print(repr(res)) hexdump(res) self.assertTrue(res==bytearray(b'\xe5,\xacgA\x9a\x9a"J;\x10\x8f?\xa6\xcbm')) print("\n") print("4.2.2.1.2 NTOWFv1()") res = ntlm.NTOWFv1(self.password) hexdump(res) self.assertTrue(res==bytearray(b'\xa4\xf4\x9c\x40\x65\x10\xbd\xca\xb6\x82\x4e\xe7\xc3\x0f\xd8\x52')) print("\n") print("4.2.2.1.3 Session Base Key and Key Exchange Key") ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(int(self.flags), self.serverChallenge, self.clientChallenge, self.serverName, self.domain, self.user, self.password, '', '') hexdump(sessionBaseKey) self.assertTrue(sessionBaseKey==bytearray(b'\xD8\x72\x62\xB0\xCD\xE4\xB1\xCB\x74\x99\xBE\xCC\xCD\xF1\x07\x84')) print("\n") print("4.2.2.2.1 NTLMv1 Response") hexdump(ntResponse) self.assertTrue(ntResponse==bytearray(b'\x67\xC4\x30\x11\xF3\x02\x98\xA2\xAD\x35\xEC\xE6\x4F\x16\x33\x1C\x44\xBD\xBE\xD9\x27\x84\x1F\x94')) print("\n") print("4.2.2.2.2 LMv1 Response") hexdump(lmResponse) self.assertTrue(lmResponse==bytearray(b'\x98\xDE\xF7\xB8\x7F\x88\xAA\x5D\xAF\xE2\xDF\x77\x96\x88\xA1\x72\xde\xf1\x1c\x7d\x5c\xcd\xef\x13')) print("\n") print("4.2.2.2.2 LMv1 Response with NTLMSSP_NEGOTIATE_LM_KEY set") flags2 = self.flags #flags2 = flags | ntlm.NTLMSSP_LM_KEY #hexdump(struct.pack('<L',flags2)) ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(int(flags2), self.serverChallenge, self.clientChallenge, self.serverName, self.domain, self.user, self.password, '', '') hexdump(lmResponse) print("\n") print("4.2.2.2.3 Encrypted Session Key ") ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(int(self.flags), self.serverChallenge, self.clientChallenge, self.serverName, self.domain, self.user, self.password, '', '') keyExchangeKey = ntlm.KXKEY(self.flags, sessionBaseKey, lmResponse, self.serverChallenge, self.password,'','') encryptedSessionKey = ntlm.generateEncryptedSessionKey(keyExchangeKey,self.randomSessionKey) hexdump(encryptedSessionKey) self.assertTrue(encryptedSessionKey==bytearray(b'\x51\x88\x22\xB1\xB3\xF3\x50\xC8\x95\x86\x82\xEC\xBB\x3E\x3C\xB7')) print("\n") print("4.2.2.2.3 Encrypted Session Key (NTLMSSP_NON_NT_KEY)") flags2 = self.flags | ntlm.NTLMSSP_REQUEST_NON_NT_SESSION_KEY keyExchangeKey = ntlm.KXKEY(flags2, sessionBaseKey, lmResponse, self.serverChallenge, self.password,'','') encryptedSessionKey = ntlm.generateEncryptedSessionKey(keyExchangeKey,self.randomSessionKey) hexdump(encryptedSessionKey) #ToDo Fix this #self.assertTrue(encryptedSessionKey==bytearray(b'\x74\x52\xca\x55\xc2\x25\xa1\xca\x04\xb4\x8f\xae\x32\xcf\x56\xfc')) print("\n") print("4.2.2.2.3 Encrypted Session Key (NTLMSSP_LM_KEY)") flags2 = self.flags | ntlm.NTLMSSP_NEGOTIATE_LM_KEY #hexdump(struct.pack('<L',flags2)) keyExchangeKey = ntlm.KXKEY(flags2, sessionBaseKey, lmResponse, self.serverChallenge, self.password,'','') encryptedSessionKey = ntlm.generateEncryptedSessionKey(keyExchangeKey,self.randomSessionKey) hexdump(encryptedSessionKey) #ToDo Fix this #self.assertTrue(encryptedSessionKey==bytearray(b'\x4c\xd7\xbb\x57\xd6\x97\xef\x9b\x54\x9f\x02\xb8\xf9\xb3\x78\x64') print("\n") print("4.2.2.3 AUTHENTICATE MESSAGE") ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(int(self.flags), self.serverChallenge, self.clientChallenge, self.serverName, self.domain, self.user, self.password, '', '') keyExchangeKey = ntlm.KXKEY(self.flags, sessionBaseKey, lmResponse, self.serverChallenge, self.password,'','') encryptedSessionKey = ntlm.generateEncryptedSessionKey(keyExchangeKey,self.randomSessionKey) ntlmChallengeResponse = ntlm.NTLMAuthChallengeResponse(self.user, self.password, self.serverChallenge) ntlmChallengeResponse['flags'] = flags2 ntlmChallengeResponse['host_name'] = self.workstationName.encode('utf-16le') ntlmChallengeResponse['domain_name'] = self.domain.encode('utf-16le') ntlmChallengeResponse['lanman'] = lmResponse ntlmChallengeResponse['ntlm'] = ntResponse ntlmChallengeResponse['session_key'] = encryptedSessionKey hexdump(ntlmChallengeResponse.getData()) self.assertTrue(ntlmChallengeResponse.getData()==bytearray(b'NTLMSSP\x00\x03\x00\x00\x00\x18\x00\x18\x00|\x00\x00\x00\x18\x00\x18\x00\x94\x00\x00\x00\x0c\x00\x0c\x00X\x00\x00\x00\x08\x00\x08\x00d\x00\x00\x00\x10\x00\x10\x00l\x00\x00\x00\x10\x00\x10\x00\xac\x00\x00\x00\xb3\x82\x02\xe2D\x00o\x00m\x00a\x00i\x00n\x00U\x00s\x00e\x00r\x00C\x00O\x00M\x00P\x00U\x00T\x00E\x00R\x00\x98\xde\xf7\xb8\x7f\x88\xaa]\xaf\xe2\xdfw\x96\x88\xa1r\xde\xf1\x1c}\\\xcd\xef\x13g\xc40\x11\xf3\x02\x98\xa2\xad5\xec\xe6O\x163\x1cD\xbd\xbe\xd9\'\x84\x1f\x94Q\x88"\xb1\xb3\xf3P\xc8\x95\x86\x82\xec\xbb><\xb7')) print("\n") print("4.2.2.4 GSS_WrapEx") print("Output of SEAL()") from Cryptodome.Cipher import ARC4 cipher = ARC4.new(self.randomSessionKey) handle = cipher.encrypt print("Plaintext") hexdump(self.plaintext) print("\n") sealedMsg, signature = ntlm.SEAL(self.flags, self.nonce, self.nonce, self.plaintext, self.plaintext, self.seqNum, handle) #signature = ntlm.SIGN(flags, nonce, plaintext, seqNum, handle) hexdump(sealedMsg) self.assertTrue(sealedMsg==bytearray(b'V\xfe\x04\xd8a\xf91\x9a\xf0\xd7#\x8a.;ME\x7f\xb8')) print("\n") hexdump(signature.getData()) self.assertTrue(signature.getData()==bytearray(b'\x01\x00\x00\x00\x00\x00\x00\x00\t\xdc\xd1\xdf.E\x9d6')) print("\n") print("####### 4.2.3 NTLMv1 with Client Challenge") flags = ntlm.NTLMSSP_NEGOTIATE_56 | ntlm.NTLMSSP_NEGOTIATE_VERSION | ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY \ | ntlm.NTLMSSP_TARGET_TYPE_SERVER | ntlm.NTLMSSP_NEGOTIATE_ALWAYS_SIGN | ntlm.NTLMSSP_NEGOTIATE_NTLM |\ ntlm.NTLMSSP_NEGOTIATE_SEAL | ntlm.NTLMSSP_NEGOTIATE_SIGN | ntlm.NTLM_NEGOTIATE_OEM | ntlm.NTLMSSP_NEGOTIATE_UNICODE print("Flags") hexdump(struct.pack('<L',flags)) print("\n") print("4.2.3.1.1 NTOWFv1(password)") hexdump(ntlm.NTOWFv1(self.password)) print("\n") print("4.2.3.1.2 Session Base Key") ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(int(flags), self.serverChallenge, self.clientChallenge, self.serverName, self.domain, self.user, self.password, '', '') hexdump(sessionBaseKey) self.assertTrue(sessionBaseKey==bytearray(b'\xd8rb\xb0\xcd\xe4\xb1\xcbt\x99\xbe\xcc\xcd\xf1\x07\x84')) print("\n") print("4.2.3.1.3 Key Exchange Key") keyExchangeKey = ntlm.KXKEY(flags, sessionBaseKey, lmResponse, self.serverChallenge, self.password,'','') hexdump(keyExchangeKey) # ToDo: Fix this #self.assertTrue(keyExchangeKey==bytearray(b'\xeb\x93\x42\x9a\x8b\xd9\x52\xf8\xb8\x9c\x55\xb8\x7f\x47\x5e\xdc')) print("\n") print("4.2.3.2.1 LMv1 Response") hexdump(lmResponse) #self.assertTrue(lmResponse==bytearray(b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')) print("\n") print("4.2.3.2.2 NTLMv1 Response") hexdump(ntResponse) # ToDo: Fix this #self.assertTrue(ntResponse==bytearray(b'\x75\x37\xf8\x03\xae\x36\x71\x28\xca\x45\x82\x04\xbd\xe7\xca\xf8\x1e\x97\xed\x26\x83\x26\x72\x32')) print("\n") print("AUTHENTICATE MESSAGE") encryptedSessionKey = ntlm.generateEncryptedSessionKey(keyExchangeKey,self.randomSessionKey) ntlmChallengeResponse = ntlm.NTLMAuthChallengeResponse(self.user, self.password, self.serverChallenge) ntlmChallengeResponse['flags'] = flags2 ntlmChallengeResponse['host_name'] = self.workstationName.encode('utf-16le') ntlmChallengeResponse['domain_name'] = self.domain.encode('utf-16le') ntlmChallengeResponse['lanman'] = lmResponse ntlmChallengeResponse['ntlm'] = ntResponse hexdump(ntlmChallengeResponse.getData()) self.assertTrue(ntlmChallengeResponse.getData()==bytearray(b'NTLMSSP\x00\x03\x00\x00\x00\x18\x00\x18\x00|\x00\x00\x00\x18\x00\x18\x00\x94\x00\x00\x00\x0c\x00\x0c\x00X\x00\x00\x00\x08\x00\x08\x00d\x00\x00\x00\x10\x00\x10\x00l\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\xb3\x82\x02\xe2D\x00o\x00m\x00a\x00i\x00n\x00U\x00s\x00e\x00r\x00C\x00O\x00M\x00P\x00U\x00T\x00E\x00R\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u7\xf8\x03\xae6q(\xcaE\x82\x04\xbd\xe7\xca\xf8\x1e\x97\xed&\x83&r2')) print("\n") print("4.2.3.4 GSS_WrapEx") print("Plaintext") hexdump(self.plaintext) print("\n") print("Output of SEAL()") exportedSessionKey = keyExchangeKey clientSigningKey = ntlm.SIGNKEY(flags, exportedSessionKey) serverSigningKey = ntlm.SIGNKEY(flags, exportedSessionKey, "Server") clientSealingKey = ntlm.SEALKEY(flags, exportedSessionKey) serverSealingKey = ntlm.SEALKEY(flags, exportedSessionKey, "Server") from Cryptodome.Cipher import ARC4 cipher = ARC4.new(clientSigningKey) client_signing_h = cipher.encrypt cipher2 = ARC4.new(clientSealingKey) client_sealing_h = cipher2.encrypt print("SEALKEY()") hexdump(clientSealingKey) print("\n") print("SIGNKEY()") hexdump(clientSigningKey) print("\n") print("Sealed Data") sealedMsg, signature = ntlm.SEAL(flags, clientSealingKey, clientSigningKey, self.plaintext, self.plaintext, self.seqNum, client_sealing_h) #signature = ntlm.SIGN(flags, clientSigningKey, plaintext, seqNum, client_sealing_h) hexdump(sealedMsg) # ToDo: Fix this #self.assertTrue(ntResponse==bytearray(b'\xa0\x23\x72\xf6\x53\x02\x73\xf3\xaa\x1e\xb9\x01\x90\xce\x52\x00\xc9\x9d')) print("\n") print("Signature") hexdump(signature.getData()) # ToDo: Fix this #self.assertTrue(ntResponse==bytearray(b'\x01\x00\x00\x00\xff\x2a\xeb\x52\xf6\x81\x79\x3a\x00\x00\x00\x00') print("\n")
from cryptography.hazmat.backends import default_backend from struct import pack key = b'Sixteen byte key' iv = Random.new().read(pycrypto_arc2.block_size) cipher = pycrypto_arc2.new(key, pycrypto_arc2.MODE_CFB, iv) msg = iv + cipher.encrypt(b'Attack at dawn') cipher = pycryptodomex_arc2.new(key, pycryptodomex_arc2.MODE_CFB, iv) msg = iv + cipher.encrypt(b'Attack at dawn') key = b'Very long and confidential key' nonce = Random.new().read(16) tempkey = SHA.new(key+nonce).digest() cipher = pycrypto_arc4.new(tempkey) msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL') cipher = pycryptodomex_arc4.new(tempkey) msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL') iv = Random.new().read(bs) key = b'An arbitrarily long key' plaintext = b'docendo discimus ' plen = bs - divmod(len(plaintext),bs)[1] padding = [plen]*plen padding = pack('b'*plen, *padding) bs = pycrypto_blowfish.block_size cipher = pycrypto_blowfish.new(key, pycrypto_blowfish.MODE_CBC, iv) msg = iv + cipher.encrypt(plaintext + padding) bs = pycryptodomex_blowfish.block_size cipher = pycryptodomex_blowfish.new(key, pycryptodomex_blowfish.MODE_CBC, iv) msg = iv + cipher.encrypt(plaintext + padding)
def test_ntlmv2(self): print("####### 4.2.4 NTLMv2 Authentication") ntlm.USE_NTLMv2 = True serverName = '\x02\x00\x0c\x00\x44\x00\x6f\x00\x6d\x00\x61\x00\x69\x00\x6e\x00\x01\x00\x0c\x00\x53\x00\x65\x00\x72\x00\x76\x00\x65\x00\x72\x00\x00\x00\x00\x00' # Still the aTime won't be set to zero. that must be changed in ntlm.computeResponseNTLM2. Gotta make this more automated flags = ntlm.NTLMSSP_NEGOTIATE_KEY_EXCH | ntlm.NTLMSSP_NEGOTIATE_56 | ntlm.NTLMSSP_NEGOTIATE_128 | \ ntlm.NTLMSSP_NEGOTIATE_VERSION | ntlm.NTLMSSP_NEGOTIATE_TARGET_INFO | \ ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY | ntlm.NTLMSSP_TARGET_TYPE_SERVER | \ ntlm.NTLMSSP_NEGOTIATE_ALWAYS_SIGN | ntlm.NTLMSSP_NEGOTIATE_NTLM | ntlm.NTLMSSP_NEGOTIATE_SEAL | \ ntlm.NTLMSSP_NEGOTIATE_SIGN | ntlm.NTLM_NEGOTIATE_OEM | ntlm.NTLMSSP_NEGOTIATE_UNICODE print("Flags") hexdump(struct.pack('<L',flags)) print("\n") print("4.2.4.1.1 NTOWFv2 and LMOWFv2") res = ntlm.NTOWFv2(self.user,self.password,self.domain) hexdump(res) self.assertTrue(res==bytearray(b'\x0c\x86\x8a@;\xfdz\x93\xa3\x00\x1e\xf2.\xf0.?')) print("\n") print("\n") print("4.2.4.1.2 Session Base Key") ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv2(flags, self.serverChallenge, self.clientChallenge, serverName, self.domain, self.user, self.password, '', '' ) hexdump(sessionBaseKey) self.assertTrue(sessionBaseKey==bytearray(b'\x8d\xe4\x0c\xca\xdb\xc1\x4a\x82\xf1\x5c\xb0\xad\x0d\xe9\x5c\xa3')) print("\n") print("4.2.4.2.1 LMv2 Response") hexdump(lmResponse) self.assertTrue(lmResponse==bytearray(b'\x86\xc3P\x97\xac\x9c\xec\x10%TvJW\xcc\xcc\x19\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa')) print("\n") print("4.2.4.2.2 NTLMv2 Response") hexdump(ntResponse[:16]) self.assertTrue(ntResponse[:16]==bytearray(b'\x68\xcd\x0a\xb8\x51\xe5\x1c\x96\xaa\xbc\x92\x7b\xeb\xef\x6a\x1c')) print("\n") print("4.2.4.2.3 Encrypted Session Key") keyExchangeKey = ntlm.KXKEY(flags, sessionBaseKey, lmResponse, self.serverChallenge, self.password,'','') encryptedSessionKey = ntlm.generateEncryptedSessionKey(keyExchangeKey,self.randomSessionKey) hexdump(encryptedSessionKey) self.assertTrue(encryptedSessionKey==bytearray(b'\xC5\xDA\xD2\x54\x4F\xC9\x79\x90\x94\xCE\x1C\xE9\x0B\xC9\xD0\x3E')) print("\n") print("AUTHENTICATE MESSAGE") encryptedSessionKey = ntlm.generateEncryptedSessionKey(keyExchangeKey,self.randomSessionKey) ntlmChallengeResponse = ntlm.NTLMAuthChallengeResponse(self.user, self.password, self.serverChallenge) ntlmChallengeResponse['flags'] = flags ntlmChallengeResponse['host_name'] = self.workstationName.encode('utf-16le') ntlmChallengeResponse['domain_name'] = self.domain.encode('utf-16le') ntlmChallengeResponse['lanman'] = lmResponse ntlmChallengeResponse['ntlm'] = ntResponse ntlmChallengeResponse['session_key'] = encryptedSessionKey hexdump(ntlmChallengeResponse.getData()) self.assertTrue(ntlmChallengeResponse.getData()==bytearray(b'NTLMSSP\x00\x03\x00\x00\x00\x18\x00\x18\x00|\x00\x00\x00T\x00T\x00\x94\x00\x00\x00\x0c\x00\x0c\x00X\x00\x00\x00\x08\x00\x08\x00d\x00\x00\x00\x10\x00\x10\x00l\x00\x00\x00\x10\x00\x10\x00\xe8\x00\x00\x003\x82\x8a\xe2D\x00o\x00m\x00a\x00i\x00n\x00U\x00s\x00e\x00r\x00C\x00O\x00M\x00P\x00U\x00T\x00E\x00R\x00\x86\xc3P\x97\xac\x9c\xec\x10%TvJW\xcc\xcc\x19\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaah\xcd\n\xb8Q\xe5\x1c\x96\xaa\xbc\x92{\xeb\xefj\x1c\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x00\x00\x00\x00\x02\x00\x0c\x00D\x00o\x00m\x00a\x00i\x00n\x00\x01\x00\x0c\x00S\x00e\x00r\x00v\x00e\x00r\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xda\xd2TO\xc9y\x90\x94\xce\x1c\xe9\x0b\xc9\xd0>')) print("\n") print("4.2.4.4 GSS_WrapEx") print("Plaintext") hexdump(self.plaintext) print("\n") print("Output of SEAL()") exportedSessionKey = self.randomSessionKey clientSigningKey = ntlm.SIGNKEY(flags, exportedSessionKey) serverSigningKey = ntlm.SIGNKEY(flags, exportedSessionKey, "Server") clientSealingKey = ntlm.SEALKEY(flags, exportedSessionKey) serverSealingKey = ntlm.SEALKEY(flags, exportedSessionKey, "Server") from Cryptodome.Cipher import ARC4 cipher = ARC4.new(clientSigningKey) client_signing_h = cipher.encrypt cipher2 = ARC4.new(clientSealingKey) client_sealing_h = cipher2.encrypt print("SEALKEY()") hexdump(clientSealingKey) self.assertTrue(clientSealingKey==bytearray(b'Y\xf6\x00\x97<\xc4\x96\n%H\n|\x19nLX')) print("\n") print("SIGNKEY()") hexdump(clientSigningKey) self.assertTrue(clientSigningKey==bytearray(b'G\x88\xdc\x86\x1bG\x82\xf3]C\xfd\x98\xfe\x1a-9')) print("\n") print("Sealed Data") sealedMsg, signature = ntlm.SEAL(flags, clientSealingKey, clientSigningKey, self.plaintext, self.plaintext, self.seqNum, client_sealing_h) #signature = ntlm.SIGN(flags, clientSigningKey, plaintext, seqNum, client_sealing_h) hexdump(sealedMsg) self.assertTrue(sealedMsg==bytearray(b'T\xe5\x01e\xbf\x196\xdc\x99` \xc1\x81\x1b\x0f\x06\xfb_')) print("\n") print("Signature") hexdump(signature.getData()) self.assertTrue(signature.getData()==bytearray(b'\x01\x00\x00\x00\x00\xc1a\xa1\x1e@\x03\x9f\x00\x00\x00\x00')) #print (repr(bytearray(str(signature)))) #raise print("\n")