diff --git a/lib/core/common.py b/lib/core/common.py index 5ed873b7f..eef88ae8a 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -54,6 +54,7 @@ from lib.core.enums import HTTPHEADER from lib.core.enums import OS from lib.core.enums import PLACE from lib.core.enums import PAYLOAD +from lib.core.enums import REFLECTIVE_COUNTER from lib.core.enums import SORTORDER from lib.core.enums import WARNFLAGS from lib.core.exception import sqlmapDataException @@ -94,6 +95,7 @@ from lib.core.settings import REFLECTED_VALUE_MARKER from lib.core.settings import TIME_DEFAULT_DELAY from lib.core.settings import TIME_STDEV_COEFF from lib.core.settings import DYNAMICITY_MARK_LENGTH +from lib.core.settings import REFLECTIVE_MISS_THRESHOLD from lib.core.settings import SENSITIVE_DATA_REGEX from lib.core.settings import SUPPORTED_OS from lib.core.settings import UNKNOWN_DBMS_VERSION @@ -2498,7 +2500,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False): retVal = content - if all([content, payload]): + if all([content, payload]) and kb.reflectiveMechanism: payload = payload.replace(PAYLOAD_DELIMITER, '') regex = filterStringValue(payload, r'[A-Za-z0-9]', REFLECTED_NON_ALPHA_NUM_REGEX) @@ -2508,9 +2510,19 @@ def removeReflectiveValues(content, payload, suppressWarning=False): retVal = re.sub(regex, REFLECTED_VALUE_MARKER, content, re.I) - if retVal != content and not suppressWarning: - debugMsg = "reflective value found and filtered out" - logger.debug(debugMsg) + if retVal != content: + kb.reflectiveCounters[REFLECTIVE_COUNTER.HIT] += 1 + if not suppressWarning: + debugMsg = "reflective value found and filtered out" + logger.debug(debugMsg) + + elif not kb.testMode and not kb.reflectiveCounters[REFLECTIVE_COUNTER.HIT]: + kb.reflectiveCounters[REFLECTIVE_COUNTER.MISS] += 1 + if kb.reflectiveCounters[REFLECTIVE_COUNTER.MISS] > REFLECTIVE_MISS_THRESHOLD: + kb.reflectiveMechanism = False + if not suppressWarning: + debugMsg = "turning off reflection removal mechanism (for optimization purposes)" + logger.debug(debugMsg) return retVal diff --git a/lib/core/enums.py b/lib/core/enums.py index 39a21aac1..b6bd47c67 100644 --- a/lib/core/enums.py +++ b/lib/core/enums.py @@ -57,6 +57,10 @@ class NULLCONNECTION: HEAD = "HEAD" RANGE = "Range" +class REFLECTIVE_COUNTER: + MISS = "MISS" + HIT = "HIT" + class HASH: MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z' MYSQL_OLD = r'(?i)\A[0-9a-f]{16}\Z' diff --git a/lib/core/option.py b/lib/core/option.py index ddc293fa1..b06397cf3 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -61,6 +61,7 @@ from lib.core.enums import HTTPMETHOD from lib.core.enums import MOBILES from lib.core.enums import PAYLOAD from lib.core.enums import PRIORITY +from lib.core.enums import REFLECTIVE_COUNTER from lib.core.exception import sqlmapConnectionException from lib.core.exception import sqlmapFilePathException from lib.core.exception import sqlmapGenericException @@ -1378,6 +1379,8 @@ def __setKnowledgeBaseAttributes(flushAll=True): kb.proxyAuthHeader = None kb.queryCounter = 0 kb.redirectSetCookie = None + kb.reflectiveMechanism = True + kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS:0, REFLECTIVE_COUNTER.HIT:0} kb.responseTimes = [] kb.resumedQueries = {} kb.singleLogFlags = set() diff --git a/lib/core/settings.py b/lib/core/settings.py index f0d1d424a..798e03fbc 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -302,7 +302,7 @@ EXCLUDE_UNESCAPE = ("WAITFOR DELAY ", " INTO DUMPFILE ", " INTO OUTFILE ", "CREA REFLECTED_VALUE_MARKER = '__REFLECTED_VALUE__' # Regular expression used for marking non-alphanum characters -REFLECTED_NON_ALPHA_NUM_REGEX = r'\W+?' +REFLECTED_NON_ALPHA_NUM_REGEX = r'\W+' # Chars which can be used as a failsafe values in case of too long URL encoding value URLENCODE_FAILSAFE_CHARS = '()|,' @@ -348,3 +348,6 @@ LOW_TEXT_PERCENT = 20 IGNORE_SPACE_AFFECTED_KEYWORDS = ("CAST", "COUNT", "EXTRACT", "GROUP_CONCAT", "MAX", "MID", "MIN", "SESSION_USER", "SUBSTR", "SUBSTRING", "SUM", "SYSTEM_USER", "TRIM") LEGAL_DISCLAIMER = "usage of sqlmap for attacking web servers without prior mutual consent can be considered as an illegal activity. it is the final user's responsibility to obey all applicable local, state and federal laws. authors assume no liability and are not responsible for any misuse or damage caused by this program." + +# After this number of misses reflective removal mechanism is turned off (for speed up reasons) +REFLECTIVE_MISS_THRESHOLD = 20