Skip to content

Commit

Permalink
fixed RPC_C_AUTHN_NETLOGON auth error
Browse files Browse the repository at this point in the history
  • Loading branch information
cghou committed Jan 8, 2025
1 parent 51d05b7 commit c7eed3b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
47 changes: 46 additions & 1 deletion impacket/dcerpc/v5/nrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,21 @@ def ComputeNetlogonSignatureMD5(authSignature, message, confounder, sessionKey):
hm.update(finalMD5)
return hm.digest()[:8]

def ComputeNetlogonAuthenticatorAES(clientStoredCredential, sessionKey):
# [MS-NRPC] Section 3.1.4.5
timestamp = int(time.time())

authenticator = NETLOGON_AUTHENTICATOR()
authenticator['Timestamp'] = timestamp

credential = unpack('<I', clientStoredCredential[:4])[0] + timestamp
if credential > 0xffffffff:
credential &= 0xffffffff
credential = pack('<I', credential)

authenticator['Credential'] = ComputeNetlogonCredentialAES(credential + clientStoredCredential[4:], sessionKey)
return authenticator

def ComputeNetlogonAuthenticator(clientStoredCredential, sessionKey):
# [MS-NRPC] Section 3.1.4.5
timestamp = int(time.time())
Expand Down Expand Up @@ -1769,7 +1784,7 @@ def SIGN(data, confounder, sequenceNum, key, aes = False):
signature['SequenceNumber'] = encryptSequenceNumberRC4(deriveSequenceNumber(sequenceNum), signature['Checksum'], key)
return signature
else:
signature = NL_AUTH_SIGNATURE()
signature = NL_AUTH_SHA2_SIGNATURE()
signature['SignatureAlgorithm'] = NL_SIGNATURE_HMAC_SHA256
if confounder == '':
signature['SealAlgorithm'] = NL_SEAL_NOT_ENCRYPTED
Expand Down Expand Up @@ -1844,6 +1859,36 @@ def UNSEAL(data, auth_data, key, aes = False):
plain = cipher.decrypt(data)
return plain, cfounder

def toCompressedUtf8String(domain_name):
if domain_name is None:
raise ValueError("domain_name cannot be None")

MAX_LABEL_LENGTH = 63

buf = bytearray()
labels = domain_name.split('.')

for label in labels:
label_bytes = label.encode('utf-8')
if len(label_bytes) > MAX_LABEL_LENGTH:
raise ValueError("Label exceeded max length of 63 bytes.")
buf.append(len(label_bytes))
buf.extend(label_bytes)
buf.append(0)

return bytes(buf)

def createNlAuthMessage(clientComputerName, domainName):
auth = NL_AUTH_MESSAGE()
auth['MessageType'] = NL_AUTH_MESSAGE_REQUEST
if '.' in domainName:
auth['Flags'] = NL_AUTH_MESSAGE_NETBIOS_HOST | NL_AUTH_MESSAGE_DNS_DOMAIN
auth['Buffer'] = b(clientComputerName) + b'\x00' + toCompressedUtf8String(domainName)
else:
auth['Flags'] = NL_AUTH_MESSAGE_NETBIOS_DOMAIN | NL_AUTH_MESSAGE_NETBIOS_HOST
auth['Buffer'] = b(domainName) + b'\x00' + b(clientComputerName) + b'\x00'
return auth


def getSSPType1(workstation='', domain='', signingRequired=False):
auth = NL_AUTH_MESSAGE()
Expand Down
17 changes: 10 additions & 7 deletions impacket/dcerpc/v5/rpcrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,9 +921,11 @@ def __init__(self, transport):
self.__cipher = None
self.__confounder = b''
self.__gss = None
self.__aseandsha = False

def set_session_key(self, session_key):
def set_session_key(self, session_key, aesandsha = False):
self.__sessionKey = session_key
self.__aseandsha = aesandsha

def get_session_key(self):
return self.__sessionKey
Expand Down Expand Up @@ -1006,7 +1008,8 @@ def bind(self, iface_uuid, alter = 0, bogus_binds = 0, transfer_syntax = ('8a885
use_ntlmv2=self._transport.doesSupportNTLMv2())
elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
from impacket.dcerpc.v5 import nrpc
auth = nrpc.getSSPType1(self.__username[:-1], self.__domain, signingRequired=True)
#auth = nrpc.getSSPType1(self.__username[:-1], self.__domain, signingRequired=True)
auth = nrpc.createNlAuthMessage(self.__username[:-1], self.__domain)
elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
self.__cipher, self.__sessionKey, auth = kerberosv5.getKerberosType1(self.__username, self.__password,
self.__domain, self.__lmhash,
Expand Down Expand Up @@ -1200,7 +1203,7 @@ def _transport_send(self, rpc_packet, forceWriteAndx = 0, forceRecv = 0):
self.__clientSealingHandle)
elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
from impacket.dcerpc.v5 import nrpc
sealedMessage, signature = nrpc.SEAL(plain_data, self.__confounder, self.__sequence, self.__sessionKey, False)
sealedMessage, signature = nrpc.SEAL(plain_data, self.__confounder, self.__sequence, self.__sessionKey, self.__aseandsha)
elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
sealedMessage, signature = self.__gss.GSS_Wrap(self.__sessionKey, plain_data, self.__sequence)

Expand All @@ -1227,7 +1230,7 @@ def _transport_send(self, rpc_packet, forceWriteAndx = 0, forceRecv = 0):
self.__confounder,
self.__sequence,
self.__sessionKey,
False)
self.__aseandsha)
elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
signature = self.__gss.GSS_GetMIC(self.__sessionKey, plain_data, self.__sequence)

Expand Down Expand Up @@ -1374,7 +1377,7 @@ def recv(self):
answer, cfounder = nrpc.UNSEAL(answer,
auth_data[len(sec_trailer):],
self.__sessionKey,
False)
self.__aseandsha)
self.__sequence += 1
elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
if self.__sequence > 0:
Expand Down Expand Up @@ -1406,7 +1409,7 @@ def recv(self):
self.__confounder,
self.__sequence,
self.__sessionKey,
False)
self.__aseandsha)
self.__sequence += 1
elif self.__auth_type == RPC_C_AUTHN_GSS_NEGOTIATE:
# Do NOT increment the sequence number when Signing Kerberos
Expand Down Expand Up @@ -1688,4 +1691,4 @@ def processRequest(self,data):
packet = MSRPCRespHeader(data)
packet['type'] = MSRPC_FAULT

return packet
return packet

0 comments on commit c7eed3b

Please sign in to comment.