diff --git a/lib/controller/checks.py b/lib/controller/checks.py index 2476cd5ba..f3167a41f 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -66,13 +66,14 @@ from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX from lib.core.settings import FORMAT_EXCEPTION_STRINGS from lib.core.settings import HEURISTIC_CHECK_ALPHABET +from lib.core.settings import IDS_WAF_CHECK_PAYLOAD +from lib.core.settings import IDS_WAF_CHECK_RATIO +from lib.core.settings import IDS_WAF_CHECK_TIMEOUT +from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH from lib.core.settings import SUPPORTED_DBMS from lib.core.settings import URI_HTTP_HEADER 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_RATIO -from lib.core.settings import IDS_WAF_CHECK_TIMEOUT from lib.core.threads import getCurrentThreadData from lib.request.connect import Connect as Request from lib.request.inject import checkBooleanExpression @@ -932,7 +933,7 @@ def heuristicCheckSqlInjection(place, parameter): kb.heuristicMode = True - randStr1, randStr2 = randomStr(), randomStr() + randStr1, randStr2 = randomStr(NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH), randomStr(NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH) value = "%s%s%s" % (randStr1, DUMMY_NON_SQLI_CHECK_APPENDIX, randStr2) payload = "%s%s%s" % (prefix, "'%s" % value, suffix) payload = agent.payload(place, parameter, newValue=payload) @@ -940,15 +941,17 @@ def heuristicCheckSqlInjection(place, parameter): paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place - if value in (page or ""): + if value.lower() in (page or "").lower(): infoMsg = "heuristic (XSS) test shows that %s parameter " % paramType infoMsg += "'%s' might be vulnerable to cross-site scripting attacks" % parameter logger.info(infoMsg) - if re.search(r"(?i)Failed opening[^\n]+%s" % randStr1, page or ""): - infoMsg = "heuristic (FI) test shows that %s parameter " % paramType - infoMsg += "'%s' might be vulnerable to file inclusion attacks" % parameter - logger.info(infoMsg) + for match in re.finditer("(?i)[^\n]*(no such file|failed (to )?open)[^\n]*", page or ""): + if randStr1.lower() in match.group(0).lower(): + infoMsg = "heuristic (FI) test shows that %s parameter " % paramType + infoMsg += "'%s' might be vulnerable to file inclusion attacks" % parameter + logger.info(infoMsg) + break kb.heuristicMode = False diff --git a/lib/core/settings.py b/lib/core/settings.py index 52e2ba738..84a0c67e0 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -548,9 +548,12 @@ DNS_BOUNDARIES_ALPHABET = re.sub("[a-fA-F]", "", string.ascii_letters) # Alphabet used for heuristic checks HEURISTIC_CHECK_ALPHABET = ('"', '\'', ')', '(', ',', '.') -# String used for dummy non-SQLi (e.g. XSS) check of a tested parameter value +# String used for dummy non-SQLi (e.g. XSS) heuristic checks of a tested parameter value DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">" +# Length of prefix and suffix used in non-SQLI heuristic checks +NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6 + # Connection chunk size (processing large responses in chunks to avoid MemoryError crashes - e.g. large table dump in full UNION injections) MAX_CONNECTION_CHUNK_SIZE = 10 * 1024 * 1024