Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    def tunnelConnection(self):
        # For the rest of the remaining packets, we should just read and send. Except when trying to log out,
        # that's forbidden! ;)
        while True:
            # 1. Get Data from client
            data = self.__NBSession.recv_packet().get_trailer()

            if len(data) == 0:
                break

            if self.isSMB2 is False:
                packet = NewSMBPacket(data=data)

                if packet['Command'] == SMB.SMB_COM_LOGOFF_ANDX:
                    # We do NOT want to get logged off do we?
                    LOG.debug(
                        'SOCKS: Avoiding logoff for %s@%s:%s' %
                        (self.username, self.targetHost, self.targetPort))
                    data = self.getLogOffAnswer(packet)
                else:
                    # 2. Send it to the relayed session
                    self.clientConnection.getSMBServer()._sess.send_packet(
                        data)

                    # 3. Get the target's answer
                    data = self.clientConnection.getSMBServer(
                    )._sess.recv_packet().get_trailer()

                    packet = NewSMBPacket(data=data)

                    if packet['Command'] == SMB.SMB_COM_TRANSACTION or packet[
                            'Command'] == SMB.SMB_COM_TRANSACTION2:
                        try:
                            while True:
                                # Anything else to read? with timeout of 1 sec. This is something to test or find
                                # a better way to control
                                data2 = self.clientConnection.getSMBServer(
                                )._sess.recv_packet(timeout=1).get_trailer()
                                self.__NBSession.send_packet(data)
                                data = data2
                        except Exception as e:
                            if str(e).find('timed out') > 0:
                                pass
                            else:
                                raise

                    if len(data) == 0:
                        break
            else:
                packet = SMB2Packet(data=data)
                origID = packet['MessageID']

                # Just in case, let's remove any signing attempt
                packet['Signature'] = ""
                packet['Flags'] &= ~(SMB2_FLAGS_SIGNED)

                # Let's be sure the TreeConnect Table is filled with fake data
                if (packet['TreeID'] in self.clientConnection.getSMBServer().
                        _Session['TreeConnectTable']) is False:
                    self.clientConnection.getSMBServer(
                    )._Session['TreeConnectTable'][packet['TreeID']] = {}
                    self.clientConnection.getSMBServer(
                    )._Session['TreeConnectTable'][
                        packet['TreeID']]['EncryptData'] = False

                if packet['Command'] == SMB2_LOGOFF:
                    # We do NOT want to get logged off do we?
                    LOG.debug(
                        'SOCKS: Avoiding logoff for %s@%s:%s' %
                        (self.username, self.targetHost, self.targetPort))
                    data = self.getLogOffAnswer(packet)
                else:
                    # 2. Send it to the relayed session
                    self.clientConnection.getSMBServer().sendSMB(packet)

                    # 3. Get the target's answer
                    packet = self.clientConnection.getSMBServer().recvSMB()

                    if len(packet.getData()) == 0:
                        break
                    else:
                        packet['MessageID'] = origID
                        data = packet.getData()

            # 4. Send it back to the client
            self.__NBSession.send_packet(data)

        return True
Beispiel #4
0
    def processSessionSetup(self, recvPacket):
        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.smbData['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)

            # Check if we have a connection for the user
            if self.activeRelays.has_key(authenticateMessage['user_name']):
                LOG.info('SOCKS: Proxying client session for %s@%s(445)' %
                         (authenticateMessage['user_name'].decode('utf-16le'),
                          self.targetHost))
                errorCode = STATUS_SUCCESS
                smbClient = self.activeRelays[
                    authenticateMessage['user_name']]['client']
                uid = smbClient.get_uid()
            else:
                LOG.error('SOCKS: No session for %s@%s(445) available' %
                          (authenticateMessage['user_name'].decode('utf-16le'),
                           self.targetHost))
                errorCode = STATUS_ACCESS_DENIED
                uid = 0

            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, authenticateMessage['user_name']
        else:
            LOG.error('SOCKS: Can\'t handle standard security at the moment!')
            return None