def sendNegotiatev2(self, negotiateMessage): v2client = self.session.getSMBServer() sessionSetup = SMB2SessionSetup() sessionSetup['Flags'] = 0 # Let's build a NegTokenInit with the NTLMSSP blob = SPNEGO_NegTokenInit() # NTLMSSP blob['MechTypes'] = [ TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider'] ] blob['MechToken'] = str(negotiateMessage) sessionSetup['SecurityBufferLength'] = len(blob) sessionSetup['Buffer'] = blob.getData() packet = v2client.SMB_PACKET() packet['Command'] = SMB2_SESSION_SETUP packet['Data'] = sessionSetup packetID = v2client.sendSMB(packet) ans = v2client.recvSMB(packetID) if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED): v2client._Session['SessionID'] = ans['SessionID'] sessionSetupResponse = SMB2SessionSetup_Response(ans['Data']) respToken = SPNEGO_NegTokenResp(sessionSetupResponse['Buffer']) return respToken['ResponseToken'] return False
def sendNegotiatev2(self, negotiateMessage): v2client = self.session.getSMBServer() sessionSetup = SMB2SessionSetup() sessionSetup['Flags'] = 0 sessionSetup['SecurityBufferLength'] = len(negotiateMessage) sessionSetup['Buffer'] = negotiateMessage packet = v2client.SMB_PACKET() packet['Command'] = SMB2_SESSION_SETUP packet['Data'] = sessionSetup packetID = v2client.sendSMB(packet) ans = v2client.recvSMB(packetID) if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED): v2client._Session['SessionID'] = ans['SessionID'] sessionSetupResponse = SMB2SessionSetup_Response(ans['Data']) return sessionSetupResponse['Buffer'] return False
def processSessionSetup(self, recvPacket): if self.isSMB2 is False: respSMBCommand = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) smbCommand = SMBCommand(recvPacket['Data'][0]) if smbCommand['WordCount'] == 12: respParameters = SMBSessionSetupAndX_Extended_Response_Parameters( ) respData = SMBSessionSetupAndX_Extended_Response_Data() # First of all, we should received a type 1 message. Let's answer it # NEGOTIATE_MESSAGE challengeMessage = self.sessionData['CHALLENGE_MESSAGE'] challengeMessage['flags'] &= ~(NTLMSSP_NEGOTIATE_SIGN) 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) respParameters['SecurityBlobLength'] = len(respToken) respData['SecurityBlobLength'] = respParameters[ 'SecurityBlobLength'] respData['SecurityBlob'] = respToken.getData() respData['NativeOS'] = '' respData['NativeLanMan'] = '' respSMBCommand['Parameters'] = respParameters respSMBCommand['Data'] = respData resp = NewSMBPacket() resp['Flags1'] = SMB.FLAGS1_REPLY resp['Flags2'] = SMB.FLAGS2_NT_STATUS resp['Pid'] = recvPacket['Pid'] resp['Tid'] = recvPacket['Tid'] resp['Mid'] = recvPacket['Mid'] resp['Uid'] = 0 errorCode = STATUS_MORE_PROCESSING_REQUIRED resp['ErrorCode'] = errorCode >> 16 resp['ErrorClass'] = errorCode & 0xff resp.addCommand(respSMBCommand) self.__NBSession.send_packet(resp.getData()) recvPacket, smbCommand = self.getSMBPacket() sessionSetupParameters = SMBSessionSetupAndX_Extended_Parameters( smbCommand['Parameters']) sessionSetupData = SMBSessionSetupAndX_Extended_Data() sessionSetupData[ 'SecurityBlobLength'] = sessionSetupParameters[ 'SecurityBlobLength'] sessionSetupData.fromString(smbCommand['Data']) if 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'] # Now we should've received a type 3 message authenticateMessage = NTLMAuthChallengeResponse() authenticateMessage.fromString(token) try: username = ( '%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le')) ).upper() except UnicodeDecodeError: # Not Unicode encoded? username = ('%s/%s' % (authenticateMessage['domain_name'], authenticateMessage['user_name'])).upper() # Check if we have a connection for the user if self.activeRelays.has_key(username): LOG.info('SOCKS: Proxying client session for %s@%s(445)' % (username, self.targetHost)) errorCode = STATUS_SUCCESS smbClient = self.activeRelays[username][ 'protocolClient'].session uid = smbClient.getSMBServer().get_uid() else: LOG.error('SOCKS: No session for %s@%s(445) available' % (username, self.targetHost)) errorCode = STATUS_ACCESS_DENIED uid = 0 smbClient = None resp = NewSMBPacket() resp['Flags1'] = recvPacket['Flags1'] | SMB.FLAGS1_REPLY resp['Flags2'] = recvPacket[ 'Flags2'] | SMB.FLAGS2_EXTENDED_SECURITY resp['Command'] = recvPacket['Command'] resp['Pid'] = recvPacket['Pid'] resp['Tid'] = recvPacket['Tid'] resp['Mid'] = recvPacket['Mid'] resp['Uid'] = uid resp['ErrorCode'] = errorCode >> 16 resp['ErrorClass'] = errorCode & 0xff respData['NativeOS'] = '' respData['NativeLanMan'] = '' if uid == 0: resp['Data'] = '\x00\x00\x00' smbClient = None else: respToken = SPNEGO_NegTokenResp() # accept-completed respToken['NegResult'] = '\x00' respParameters['SecurityBlobLength'] = len(respToken) respData['SecurityBlobLength'] = respParameters[ 'SecurityBlobLength'] respData['SecurityBlob'] = respToken.getData() respSMBCommand['Parameters'] = respParameters respSMBCommand['Data'] = respData resp.addCommand(respSMBCommand) self.__NBSession.send_packet(resp.getData()) return smbClient, username else: LOG.error( 'SOCKS: Can\'t handle standard security at the moment!') return None else: respSMBCommand = SMB2SessionSetup_Response() sessionSetupData = SMB2SessionSetup(recvPacket['Data']) securityBlob = sessionSetupData['Buffer'] rawNTLM = False if unpack('B', securityBlob[0])[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']: # Nope, do we know it? if MechTypes.has_key(mechType): mechStr = MechTypes[mechType] else: mechStr = hexlify(mechType) LOG.debug( "Unsupported MechType '%s', we just want NTLMSSP, answering" % mechStr) # We don't know the token, we answer back again saying # we just support NTLM. # ToDo: Build this into a SPNEGO_NegTokenResp() respToken = '\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 resp = SMB2Packet() resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR resp['Status'] = STATUS_SUCCESS resp['CreditRequestResponse'] = 1 resp['CreditCharge'] = recvPacket['CreditCharge'] resp['Command'] = recvPacket['Command'] resp['SessionID'] = 0 resp['Reserved'] = recvPacket['Reserved'] resp['MessageID'] = recvPacket['MessageID'] resp['TreeID'] = recvPacket['TreeID'] resp['Data'] = respSMBCommand self.__NBSession.send_packet(resp.getData()) recvPacket, smbCommand = self.getSMBPacket() return self.processSessionSetup(recvPacket) elif unpack('B', securityBlob[0])[0] == ASN1_SUPPORTED_MECH: # AUTH packet blob = SPNEGO_NegTokenResp(securityBlob) token = blob['ResponseToken'] else: # No GSSAPI stuff, raw NTLMSSP rawNTLM = True token = securityBlob # NEGOTIATE_MESSAGE # First of all, we should received a type 1 message. Let's answer it challengeMessage = self.sessionData['CHALLENGE_MESSAGE'] challengeMessage['flags'] &= ~(NTLMSSP_NEGOTIATE_SIGN) if rawNTLM is False: respToken = SPNEGO_NegTokenResp() # accept-incomplete. We want more data respToken['NegResult'] = '\x01' respToken['SupportedMech'] = TypesMech[ 'NTLMSSP - Microsoft NTLM Security Support Provider'] respToken['ResponseToken'] = challengeMessage.getData() else: respToken = challengeMessage resp = SMB2Packet() resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR resp['Status'] = STATUS_MORE_PROCESSING_REQUIRED resp['CreditRequestResponse'] = 1 resp['CreditCharge'] = recvPacket['CreditCharge'] resp['Command'] = recvPacket['Command'] resp['SessionID'] = 0 resp['Reserved'] = recvPacket['Reserved'] resp['MessageID'] = recvPacket['MessageID'] resp['TreeID'] = recvPacket['TreeID'] respSMBCommand['SecurityBufferOffset'] = 0x48 respSMBCommand['SecurityBufferLength'] = len(respToken) respSMBCommand['Buffer'] = respToken.getData() resp['Data'] = respSMBCommand self.__NBSession.send_packet(resp.getData()) recvPacket, smbCommand = self.getSMBPacket() sessionSetupData = SMB2SessionSetup(recvPacket['Data']) securityBlob = sessionSetupData['Buffer'] blob = SPNEGO_NegTokenResp(securityBlob) token = blob['ResponseToken'] # AUTHENTICATE_MESSAGE, here we deal with authentication authenticateMessage = NTLMAuthChallengeResponse() authenticateMessage.fromString(token) try: username = ( '%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le')) ).upper() except UnicodeDecodeError: # Not Unicode encoded? username = ('%s/%s' % (authenticateMessage['domain_name'], authenticateMessage['user_name'])).upper() respToken = SPNEGO_NegTokenResp() # Check if we have a connection for the user if self.activeRelays.has_key(username): LOG.info('SOCKS: Proxying client session for %s@%s(445)' % (username, self.targetHost)) errorCode = STATUS_SUCCESS smbClient = self.activeRelays[username][ 'protocolClient'].session uid = smbClient.getSMBServer()._Session['SessionID'] else: LOG.error('SOCKS: No session for %s@%s(445) available' % (username, self.targetHost)) errorCode = STATUS_ACCESS_DENIED uid = 0 smbClient = None # accept-completed respToken['NegResult'] = '\x00' resp = SMB2Packet() resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR resp['Status'] = errorCode resp['CreditRequestResponse'] = 1 resp['CreditCharge'] = recvPacket['CreditCharge'] resp['Command'] = recvPacket['Command'] resp['SessionID'] = uid resp['Reserved'] = recvPacket['Reserved'] resp['MessageID'] = recvPacket['MessageID'] resp['TreeID'] = recvPacket['TreeID'] respSMBCommand['SecurityBufferOffset'] = 0x48 # This is important for SAMBA client to work. If it is not set as a guest session, # SAMBA will *not* like the fact that the packets are not signed (even tho it was not enforced). respSMBCommand['SessionFlags'] = SMB2_SESSION_FLAG_IS_GUEST respSMBCommand['SecurityBufferLength'] = len(respToken) respSMBCommand['Buffer'] = respToken.getData() resp['Data'] = respSMBCommand self.__NBSession.send_packet(resp.getData()) return smbClient, username