mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-08-06 05:10:10 +03:00
Merge 2479cb5ec8
into 3a8c0cd3a2
This commit is contained in:
commit
09b775d3e2
|
@ -65,6 +65,7 @@ from lib.core.settings import LOWER_RATIO_BOUND
|
||||||
from lib.core.settings import UPPER_RATIO_BOUND
|
from lib.core.settings import UPPER_RATIO_BOUND
|
||||||
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
|
from lib.core.wafs import wafs
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
from lib.request.inject import checkBooleanExpression
|
from lib.request.inject import checkBooleanExpression
|
||||||
from lib.request.templates import getPageTemplate
|
from lib.request.templates import getPageTemplate
|
||||||
|
@ -1027,6 +1028,19 @@ def checkWaf():
|
||||||
if not falseResult:
|
if not falseResult:
|
||||||
retVal = True
|
retVal = True
|
||||||
|
|
||||||
|
if retVal:
|
||||||
|
if conf.identifyWaf:
|
||||||
|
infoMsg = "detecting the vendor of the waf"
|
||||||
|
logger.info(infoMsg)
|
||||||
|
for waf in wafs:
|
||||||
|
if waf.identify():
|
||||||
|
kb.waf = waf.vendor
|
||||||
|
infoMsg = "the vendor of the waf seems to be " + kb.waf
|
||||||
|
logger.info(infoMsg)
|
||||||
|
break
|
||||||
|
infoMsg = "the vendor of the waf is not detected"
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
conf.parameters = dict(backup)
|
conf.parameters = dict(backup)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
|
|
|
@ -1632,6 +1632,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.timeValidCharsRun = 0
|
kb.timeValidCharsRun = 0
|
||||||
kb.uChar = NULL
|
kb.uChar = NULL
|
||||||
kb.unionDuplicates = False
|
kb.unionDuplicates = False
|
||||||
|
kb.waf = None
|
||||||
kb.xpCmdshellAvailable = False
|
kb.xpCmdshellAvailable = False
|
||||||
|
|
||||||
if flushAll:
|
if flushAll:
|
||||||
|
|
313
lib/core/wafs.py
Normal file
313
lib/core/wafs.py
Normal file
|
@ -0,0 +1,313 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'doc/COPYING' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import httplib
|
||||||
|
from lib.request.connect import Connect as Request
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.enums import PLACE
|
||||||
|
from lib.core.common import getHostHeader
|
||||||
|
|
||||||
|
class Waf(object):
|
||||||
|
"""
|
||||||
|
This class defines waf vendors and attack vectors for identification
|
||||||
|
"""
|
||||||
|
attack_vectors = [
|
||||||
|
'/Admin_Files/',
|
||||||
|
'<script>alert(1)</script>',
|
||||||
|
'%3Cscript%3Ealert%281%29%3C/script%3E',
|
||||||
|
'../../../../etc/passwd',
|
||||||
|
'<invalid>hello'
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = None
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def matchheader(headers, field, match):
|
||||||
|
headers = dict(headers.items())
|
||||||
|
if field in headers:
|
||||||
|
if field == 'set-cookie':
|
||||||
|
values = headers[field].split('; ')
|
||||||
|
else:
|
||||||
|
values = [headers[field]]
|
||||||
|
for value in values:
|
||||||
|
if re.match(match, value, re.IGNORECASE):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafProfense(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'Profense'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'server', 'profense')
|
||||||
|
|
||||||
|
class WafNetContinuum(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'NetContinuum'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'set-cookie', '^NCI__SessionId=')
|
||||||
|
|
||||||
|
class WafBarracuda(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'Barracuda'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'set-cookie', '^barra_counter_session=')
|
||||||
|
|
||||||
|
class WafHyperGuard(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'HyperGuard'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'set-cookie', '^WODSESSION=')
|
||||||
|
|
||||||
|
class WafBinarySec(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'BinarySec'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'server', 'BinarySec')
|
||||||
|
|
||||||
|
class WafTeros(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'Teros'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'set-cookie', '^st8id=')
|
||||||
|
|
||||||
|
class WafF5Trafficshield(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'F5 Trafficshield'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
if Waf.matchheader(headers, 'cookie', '^ASINFO='):
|
||||||
|
return True
|
||||||
|
if Waf.matchheader(headers, 'server', 'F5-TrafficShield'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafF5ASM(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'F5 ASM'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'set-cookie', '^TS[a-zA-Z0-9]{3,6}=')
|
||||||
|
|
||||||
|
class WafAirlock(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'Airlock'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'set-cookie', '^AL[_-]?(SESS|LB)=')
|
||||||
|
|
||||||
|
class WafCitrixNetScaler(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'Citrix NetScaler'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
if Waf.matchheader(headers, 'set-cookie', '^(ns_af=|citrix_ns_id|NSC_)'):
|
||||||
|
return True
|
||||||
|
|
||||||
|
for attack_vector in Waf.attack_vectors:
|
||||||
|
get = attack_vector
|
||||||
|
page, headers, code = Request.getPage(content=True, get=get)
|
||||||
|
if Waf.matchheader(headers, 'Cneonction', 'close') or Waf.matchheader(headers, 'nnCoection', 'close'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafModSecurity(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'ModSecurity'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
for attack_vector in Waf.attack_vectors:
|
||||||
|
get = attack_vector
|
||||||
|
page, headers, code = Request.getPage(content=True, get=get)
|
||||||
|
if code == 501:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafIBMWebApplicationSecurity(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'IBM Web Application Security'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
get = '/Admin_Files/'
|
||||||
|
page, headers, code = Request.getPage(content=True, get=get)
|
||||||
|
if page is None:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafIBMDataPower(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'IBM DataPower'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
return Waf.matchheader(headers, 'X-Backside-Transport', '^(OK|FAIL)')
|
||||||
|
|
||||||
|
class WafDenyALL(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'DenyALL'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
if Waf.matchheader(headers, 'set-cookie', '^sessioncookie='):
|
||||||
|
return True
|
||||||
|
for attack_vector in Waf.attack_vectors:
|
||||||
|
get = attack_vector
|
||||||
|
conn, _, _ = Request.getPage(response=True, get=get)
|
||||||
|
if conn.code == 200:
|
||||||
|
if conn.msg == 'Condition Intercepted':
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafdotDefender(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'dotDefender'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
for attack_vector in Waf.attack_vectors:
|
||||||
|
get = attack_vector
|
||||||
|
page, headers, code = Request.getPage(content=True, get=get)
|
||||||
|
if Waf.matchheader(headers, 'X-dotDefender-denied', '^1$'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafwebAppSecure(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'webApp.secure'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
page, headers, code = Request.getPage(content=True)
|
||||||
|
if code == 403:
|
||||||
|
return False
|
||||||
|
get = 'nx=@@'
|
||||||
|
page, headers, code = Request.getPage(content=True, get=get)
|
||||||
|
if code == 403:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafBIGIP(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'BIG-IP'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
for attack_vector in Waf.attack_vectors:
|
||||||
|
get = attack_vector
|
||||||
|
page, headers, code = Request.getPage(content=True, get=get)
|
||||||
|
if Waf.matchheader(headers, 'X-Cnection', '^close$'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafURLScan(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'URLScan'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
auxHeaders = dict()
|
||||||
|
auxHeaders['Translate'] = 'z'*10
|
||||||
|
auxHeaders['If'] = 'z'*10
|
||||||
|
auxHeaders['Lock-Token'] = 'z'*10
|
||||||
|
auxHeaders['Transfer-Encoding'] = 'z'*10
|
||||||
|
page, headers, code1 = Request.getPage(content=True)
|
||||||
|
page, headers, code2 = Request.getPage(content=True, auxHeaders=auxHeaders)
|
||||||
|
if code1 != code2 and code2 == 404:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafWebKnight(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'WebKnight'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
for attack_vector in Waf.attack_vectors:
|
||||||
|
get = attack_vector
|
||||||
|
page, headers, code = Request.getPage(content=True, get=get)
|
||||||
|
if code == 999:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafSecureIIS(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'SecureIIS'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
auxHeaders = dict()
|
||||||
|
auxHeaders['Transfer-Encoding'] = 'z' * 1025
|
||||||
|
page, headers, code = Request.getPage(content=True, auxHeaders=auxHeaders)
|
||||||
|
if code == 404:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafImperva(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'Imperva'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
for attack_vector in Waf.attack_vectors:
|
||||||
|
conn = httplib.HTTPConnection(getHostHeader(conf.url), conf.port)
|
||||||
|
conn.request('GET', '/' + attack_vector)
|
||||||
|
r = conn.getresponse()
|
||||||
|
if r.version == 10:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
class WafISAServer(Waf):
|
||||||
|
def __init__(self):
|
||||||
|
self.vendor = 'ISA Server'
|
||||||
|
|
||||||
|
def identify(self):
|
||||||
|
auxHeaders = dict()
|
||||||
|
auxHeaders['Host'] = '123456'
|
||||||
|
conn, _, _ = Request.getPage(response=True, auxHeaders=auxHeaders)
|
||||||
|
if conn.msg == 'Forbidden ( The server denied the specified Uniform Resource Locator (URL). Contact the server administrator. )':
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
wafs = [
|
||||||
|
WafProfense(),
|
||||||
|
WafNetContinuum(),
|
||||||
|
WafBarracuda(),
|
||||||
|
WafHyperGuard(),
|
||||||
|
WafBinarySec(),
|
||||||
|
WafTeros(),
|
||||||
|
WafF5Trafficshield(),
|
||||||
|
WafF5ASM(),
|
||||||
|
WafAirlock(),
|
||||||
|
WafCitrixNetScaler(),
|
||||||
|
WafModSecurity(),
|
||||||
|
WafIBMWebApplicationSecurity(),
|
||||||
|
WafIBMDataPower(),
|
||||||
|
WafDenyALL(),
|
||||||
|
WafdotDefender(),
|
||||||
|
WafwebAppSecure(),
|
||||||
|
WafBIGIP(),
|
||||||
|
WafURLScan(),
|
||||||
|
WafWebKnight(),
|
||||||
|
WafSecureIIS(),
|
||||||
|
WafImperva(),
|
||||||
|
WafISAServer()
|
||||||
|
]
|
|
@ -616,6 +616,10 @@ def cmdLineParser():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Heuristically check for WAF/IPS/IDS protection")
|
help="Heuristically check for WAF/IPS/IDS protection")
|
||||||
|
|
||||||
|
miscellaneous.add_option("--identify-waf", dest="identifyWaf",
|
||||||
|
action="store_true",
|
||||||
|
help="Identify the vendor of WAF")
|
||||||
|
|
||||||
miscellaneous.add_option("--cleanup", dest="cleanup",
|
miscellaneous.add_option("--cleanup", dest="cleanup",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Clean up the DBMS by sqlmap specific "
|
help="Clean up the DBMS by sqlmap specific "
|
||||||
|
|
Loading…
Reference in New Issue
Block a user