mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-01-23 15:54:24 +03:00
Heuristically checking for WAF/IDS/IPS by default
This commit is contained in:
parent
cd7d9edcbe
commit
6fc41ca940
|
@ -59,6 +59,7 @@ from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapSilentQuitException
|
from lib.core.exception import SqlmapSilentQuitException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
|
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||||
from lib.core.settings import DUMMY_XSS_CHECK_APPENDIX
|
from lib.core.settings import DUMMY_XSS_CHECK_APPENDIX
|
||||||
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
|
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
|
||||||
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
|
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
|
||||||
|
@ -68,6 +69,7 @@ from lib.core.settings import URI_HTTP_HEADER
|
||||||
from lib.core.settings import LOWER_RATIO_BOUND
|
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.settings import IDS_WAF_CHECK_RATIO
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
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
|
||||||
|
@ -1094,56 +1096,32 @@ def checkWaf():
|
||||||
Reference: http://seclists.org/nmap-dev/2011/q2/att-1005/http-waf-detect.nse
|
Reference: http://seclists.org/nmap-dev/2011/q2/att-1005/http-waf-detect.nse
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not conf.checkWaf:
|
|
||||||
return False
|
|
||||||
|
|
||||||
infoMsg = "heuristically checking if the target is protected by "
|
infoMsg = "heuristically checking if the target is protected by "
|
||||||
infoMsg += "some kind of WAF/IPS/IDS"
|
infoMsg += "some kind of WAF/IPS/IDS"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
retVal = False
|
retVal = False
|
||||||
|
|
||||||
backup = dict(conf.parameters)
|
backup = dict(conf.parameters)
|
||||||
|
|
||||||
payload = "%d %s" % (randomInt(), IDS_WAF_CHECK_PAYLOAD)
|
payload = "%d %s" % (randomInt(), IDS_WAF_CHECK_PAYLOAD)
|
||||||
|
|
||||||
conf.parameters = dict(backup)
|
conf.parameters = dict(backup)
|
||||||
conf.parameters[PLACE.GET] = "" if not conf.parameters.get(PLACE.GET) else conf.parameters[PLACE.GET] + "&"
|
conf.parameters[PLACE.GET] = "" if not conf.parameters.get(PLACE.GET) else conf.parameters[PLACE.GET] + DEFAULT_GET_POST_DELIMITER
|
||||||
conf.parameters[PLACE.GET] += "%s=%s" % (randomStr(), payload)
|
conf.parameters[PLACE.GET] += "%s=%s" % (randomStr(), payload)
|
||||||
|
|
||||||
logger.log(CUSTOM_LOGGING.PAYLOAD, payload)
|
logger.log(CUSTOM_LOGGING.PAYLOAD, payload)
|
||||||
|
|
||||||
kb.matchRatio = None
|
try:
|
||||||
Request.queryPage()
|
retVal = Request.queryPage(getRatioValue=True, noteResponseTime=False, silent=True)[1] < IDS_WAF_CHECK_RATIO
|
||||||
|
except SqlmapConnectionException:
|
||||||
if kb.errorIsNone and kb.matchRatio is None:
|
retVal = True
|
||||||
kb.matchRatio = LOWER_RATIO_BOUND
|
finally:
|
||||||
|
kb.matchRatio = None
|
||||||
conf.parameters = dict(backup)
|
|
||||||
conf.parameters[PLACE.GET] = "" if not conf.parameters.get(PLACE.GET) else conf.parameters[PLACE.GET] + "&"
|
|
||||||
conf.parameters[PLACE.GET] += "%s=%d" % (randomStr(), randomInt())
|
|
||||||
|
|
||||||
trueResult = Request.queryPage()
|
|
||||||
|
|
||||||
if trueResult:
|
|
||||||
conf.parameters = dict(backup)
|
conf.parameters = dict(backup)
|
||||||
conf.parameters[PLACE.GET] = "" if not conf.parameters.get(PLACE.GET) else conf.parameters[PLACE.GET] + "&"
|
|
||||||
conf.parameters[PLACE.GET] += "%s=%d %s" % (randomStr(), randomInt(), IDS_WAF_CHECK_PAYLOAD)
|
|
||||||
|
|
||||||
try:
|
|
||||||
falseResult = Request.queryPage()
|
|
||||||
except SqlmapConnectionException:
|
|
||||||
falseResult = None
|
|
||||||
|
|
||||||
if not falseResult:
|
|
||||||
retVal = True
|
|
||||||
|
|
||||||
conf.parameters = dict(backup)
|
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
warnMsg = "it appears that the target is protected. Please "
|
warnMsg = "it appears that the target is protected. Please "
|
||||||
warnMsg += "consider usage of tamper scripts (option '--tamper')"
|
warnMsg += "consider usage of tamper scripts (option '--tamper')"
|
||||||
logger.warn(warnMsg)
|
logger.critical(warnMsg)
|
||||||
else:
|
else:
|
||||||
infoMsg = "it appears that the target is not protected"
|
infoMsg = "it appears that the target is not protected"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
|
@ -372,8 +372,7 @@ def start():
|
||||||
if not checkConnection(suppressOutput=conf.forms) or not checkString() or not checkRegexp():
|
if not checkConnection(suppressOutput=conf.forms) or not checkString() or not checkRegexp():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if conf.checkWaf:
|
checkWaf()
|
||||||
checkWaf()
|
|
||||||
|
|
||||||
if conf.identifyWaf:
|
if conf.identifyWaf:
|
||||||
identifyWaf()
|
identifyWaf()
|
||||||
|
|
|
@ -209,7 +209,6 @@ optDict = {
|
||||||
"alert": "string",
|
"alert": "string",
|
||||||
"answers": "string",
|
"answers": "string",
|
||||||
"beep": "boolean",
|
"beep": "boolean",
|
||||||
"checkWaf": "boolean",
|
|
||||||
"cleanup": "boolean",
|
"cleanup": "boolean",
|
||||||
"dependencies": "boolean",
|
"dependencies": "boolean",
|
||||||
"disableColoring": "boolean",
|
"disableColoring": "boolean",
|
||||||
|
|
|
@ -40,6 +40,9 @@ BANNER = """\033[01;33m _
|
||||||
DIFF_TOLERANCE = 0.05
|
DIFF_TOLERANCE = 0.05
|
||||||
CONSTANT_RATIO = 0.9
|
CONSTANT_RATIO = 0.9
|
||||||
|
|
||||||
|
# Ratio used in heuristic check for WAF/IDS/IPS protected targets
|
||||||
|
IDS_WAF_CHECK_RATIO = 0.5
|
||||||
|
|
||||||
# Lower and upper values for match ratio in case of stable page
|
# Lower and upper values for match ratio in case of stable page
|
||||||
LOWER_RATIO_BOUND = 0.02
|
LOWER_RATIO_BOUND = 0.02
|
||||||
UPPER_RATIO_BOUND = 0.98
|
UPPER_RATIO_BOUND = 0.98
|
||||||
|
|
|
@ -676,10 +676,6 @@ def cmdLineParser():
|
||||||
miscellaneous.add_option("--beep", dest="beep", action="store_true",
|
miscellaneous.add_option("--beep", dest="beep", action="store_true",
|
||||||
help="Make a beep sound when SQL injection is found")
|
help="Make a beep sound when SQL injection is found")
|
||||||
|
|
||||||
miscellaneous.add_option("--check-waf", dest="checkWaf",
|
|
||||||
action="store_true",
|
|
||||||
help="Heuristically check for WAF/IPS/IDS protection")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--cleanup", dest="cleanup",
|
miscellaneous.add_option("--cleanup", dest="cleanup",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Clean up the DBMS from sqlmap specific "
|
help="Clean up the DBMS from sqlmap specific "
|
||||||
|
|
|
@ -718,10 +718,6 @@ beep = False
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
checkPayload = False
|
checkPayload = False
|
||||||
|
|
||||||
# Heuristically check for WAF/IPS/IDS protection.
|
|
||||||
# Valid: True or False
|
|
||||||
checkWaf = False
|
|
||||||
|
|
||||||
# Clean up the DBMS from sqlmap specific UDF and tables.
|
# Clean up the DBMS from sqlmap specific UDF and tables.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
cleanup = False
|
cleanup = False
|
||||||
|
|
Loading…
Reference in New Issue
Block a user