mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-04 18:07:46 +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
 | 
					 | 
				
			||||||
    Request.queryPage()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if kb.errorIsNone and kb.matchRatio is None:
 | 
					 | 
				
			||||||
        kb.matchRatio = LOWER_RATIO_BOUND
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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[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:
 | 
					    try:
 | 
				
			||||||
            falseResult = Request.queryPage()
 | 
					        retVal = Request.queryPage(getRatioValue=True, noteResponseTime=False, silent=True)[1] < IDS_WAF_CHECK_RATIO
 | 
				
			||||||
    except SqlmapConnectionException:
 | 
					    except SqlmapConnectionException:
 | 
				
			||||||
            falseResult = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not falseResult:
 | 
					 | 
				
			||||||
        retVal = True
 | 
					        retVal = True
 | 
				
			||||||
 | 
					    finally:
 | 
				
			||||||
 | 
					        kb.matchRatio = None
 | 
				
			||||||
        conf.parameters = dict(backup)
 | 
					        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,7 +372,6 @@ 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:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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