Heuristically checking for WAF/IDS/IPS by default

This commit is contained in:
Miroslav Stampar 2015-01-06 14:01:47 +01:00
parent cd7d9edcbe
commit 6fc41ca940
6 changed files with 14 additions and 43 deletions

View File

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

View File

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

View File

@ -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",

View File

@ -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

View File

@ -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 "

View File

@ -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