def genericdetect(self, usecache=True, cacheresponse=True): knownflops = [ ('Microsoft-IIS/7.0','Microsoft-HTTPAPI/2.0'), ] reason = '' reasons = ['Blocking is being done at connection/packet level.', 'The server header is different when an attack is detected.', 'The server returned a different response code when a string trigged the blacklist.', 'It closed the connection for a normal request.', 'The connection header was scrambled.' ] # test if response for a path containing html tags with known evil strings # gives a different response from another containing invalid html tags try: cleanresponse, _tmp = self._perform_and_check(self.cleanhtml) xssresponse, _tmp = self._perform_and_check(self.xssstandard) if xssresponse.status != cleanresponse.status: self.log.info('Server returned a different response when a script tag was tried') reason = reasons[2] reason += '\r\n' reason += 'Normal response code is "%s",' % cleanresponse.status reason += ' while the response code to an attack is "%s"' % xssresponse.status self.knowledge['generic']['reason'] = reason self.knowledge['generic']['found'] = True return True cleanresponse, _tmp = self._perform_and_check(self.cleanhtmlencoded) xssresponse, _tmp = self._perform_and_check(self.xssstandardencoded) if xssresponse.status != cleanresponse.status: self.log.info('Server returned a different response when a script tag was tried') reason = reasons[2] reason += '\r\n' reason += 'Normal response code is "%s",' % cleanresponse.status reason += ' while the response code to an attack is "%s"' % xssresponse.status self.knowledge['generic']['reason'] = reason self.knowledge['generic']['found'] = True return True response, responsebody = self._perform_and_check(self.normalrequest) normalserver = response.getheader('Server') for attack in self.attacks: response, responsebody = self._perform_and_check(lambda: attack(self)) attackresponse_server = response.getheader('Server') if attackresponse_server: if attackresponse_server != normalserver: if (normalserver, attackresponse_server) in knownflops: return False self.log.info('Server header changed, WAF possibly detected') self.log.debug('attack response: %s' % attackresponse_server) self.log.debug('normal response: %s' % normalserver) reason = reasons[1] reason += '\r\nThe server header for a normal response is "%s",' % normalserver reason += ' while the server header a response to an attack is "%s.",' % attackresponse_server self.knowledge['generic']['reason'] = reason self.knowledge['generic']['found'] = True return True for attack in self.wafdetectionsprio: if self.wafdetections[attack](self) is None: self.knowledge['generic']['reason'] = reasons[0] self.knowledge['generic']['found'] = True return True for attack in self.attacks: response, responsebody = self._perform_and_check(lambda: attack(self)) for h, v in response.getheaders(): if scrambledheader(h): self.knowledge['generic']['reason'] = reasons[4] self.knowledge['generic']['found'] = True return True except RequestBlocked: self.knowledge['generic']['reason'] = reasons[0] self.knowledge['generic']['found'] = True return True return False
def genericdetect(self, usecache=True, cacheresponse=True): knownflops = [ ('Microsoft-IIS/7.0', 'Microsoft-HTTPAPI/2.0'), ] reason = '' reasons = [ 'Blocking is being done at connection/packet level.', 'The server header is different when an attack is detected.', 'The server returned a different response code when a string trigged the blacklist.', 'It closed the connection for a normal request.', 'The connection header was scrambled.' ] # test if response for a path containing html tags with known evil strings # gives a different response from another containing invalid html tags try: cleanresponse, _tmp = self._perform_and_check(self.cleanhtml) xssresponse, _tmp = self._perform_and_check(self.xssstandard) if xssresponse.status != cleanresponse.status: self.log.info( 'Server returned a different response when a script tag was tried' ) reason = reasons[2] reason += '\r\n' reason += 'Normal response code is "%s",' % cleanresponse.status reason += ' while the response code to an attack is "%s"' % xssresponse.status self.knowledge['generic']['reason'] = reason self.knowledge['generic']['found'] = True return True cleanresponse, _tmp = self._perform_and_check( self.cleanhtmlencoded) xssresponse, _tmp = self._perform_and_check( self.xssstandardencoded) if xssresponse.status != cleanresponse.status: self.log.info( 'Server returned a different response when a script tag was tried' ) reason = reasons[2] reason += '\r\n' reason += 'Normal response code is "%s",' % cleanresponse.status reason += ' while the response code to an attack is "%s"' % xssresponse.status self.knowledge['generic']['reason'] = reason self.knowledge['generic']['found'] = True return True response, _ = self._perform_and_check(self.normalrequest) normalserver = response.getheader('Server') for attack in self.attacks: response, _ = self._perform_and_check(lambda: attack(self)) attackresponse_server = response.getheader('Server') if attackresponse_server: if attackresponse_server != normalserver: if (normalserver, attackresponse_server) in knownflops: return False self.log.info( 'Server header changed, WAF possibly detected') self.log.debug('attack response: %s' % attackresponse_server) self.log.debug('normal response: %s' % normalserver) reason = reasons[1] reason += '\r\nThe server header for a normal response is "%s",' % normalserver reason += ' while the server header a response to an attack is "%s",' % attackresponse_server self.knowledge['generic']['reason'] = reason self.knowledge['generic']['found'] = True return True for attack in wafdetectionsprio: if self.wafdetections[attack](self) is None: self.knowledge['generic']['reason'] = reasons[0] self.knowledge['generic']['found'] = True return True for attack in self.attacks: response, _ = self._perform_and_check(lambda: attack(self)) for h, _ in response.getheaders(): if scrambledheader(h): self.knowledge['generic']['reason'] = reasons[4] self.knowledge['generic']['found'] = True return True except RequestBlocked: self.knowledge['generic']['reason'] = reasons[0] self.knowledge['generic']['found'] = True return True return False