Skip to content

Commit 6e06114

Browse files
committed
Fixes #6157
1 parent c9745f8 commit 6e06114

2 files changed

Lines changed: 22 additions & 9 deletions

File tree

‎lib/core/settings.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from thirdparty import six
2020

2121
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
22-
VERSION = "1.10.10.19"
22+
VERSION = "1.10.10.20"
2323
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2424
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2525
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

‎lib/techniques/blind/inference.py‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@ def normalizedExpression(expression):
109109

110110
return retVal
111111

112+
def replaceInferenceOperator(payload, replacement):
113+
"""
114+
Replaces only the inference comparison operator (i.e. the one right in front of the compared
115+
value placeholder), leaving any other occurrence (e.g. inside the original parameter value) intact
116+
117+
>>> replaceInferenceOperator("1FF>6182 AND ASCII(SUBSTRING((%s),%d,1))>%d", "!=")
118+
'1FF>6182 AND ASCII(SUBSTRING((%s),%d,1))!=%d'
119+
>>> replaceInferenceOperator("a>b AND SUBSTR((%s),%d,1)>'%c'", "=")
120+
"a>b AND SUBSTR((%s),%d,1)='%c'"
121+
"""
122+
123+
return re.sub(r"%s(?=%%d|'%%c')" % re.escape(INFERENCE_GREATER_CHAR), lambda match: replacement, payload)
124+
112125
def getHuffmanPrior(order, scale, dbms=None):
113126
"""
114127
Character-level order-N Markov model {context: {ordinal: count}} used to warm the Huffman
@@ -350,7 +363,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
350363
elif Backend.isDbms(DBMS.FRONTBASE):
351364
match = re.search(r"\ASELECT\b(\s+TOP\s*\([^)]+\)\s+)?(.+)\bFROM\b(.+)\Z", expression, re.I)
352365
if match:
353-
payload = payload.replace(INFERENCE_GREATER_CHAR, " FROM %s)%s" % (match.group(3).strip(), INFERENCE_GREATER_CHAR))
366+
payload = replaceInferenceOperator(payload, " FROM %s)%s" % (match.group(3).strip(), INFERENCE_GREATER_CHAR))
354367
payload = payload.replace("SUBSTRING", "(SELECT%sSUBSTRING" % (match.group(1) if match.group(1) else " "), 1)
355368
expression = match.group(2).strip()
356369

@@ -509,9 +522,9 @@ def tryHint(idx):
509522

510523
markingValue = "'%s'" % CHAR_INFERENCE_MARK
511524
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
512-
forgedPayload = agent.extractPayload(payload) or ""
525+
forgedPayload = replaceInferenceOperator(agent.extractPayload(payload) or "", INFERENCE_EQUALS_CHAR)
513526
forgedPayload = forgedPayload.replace(markingValue, unescapedCharValue)
514-
forgedPayload = safeStringFormat(forgedPayload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue))
527+
forgedPayload = safeStringFormat(forgedPayload, (expressionUnescaped, idx, posValue))
515528
result = Request.queryPage(agent.replacePayload(payload, forgedPayload), timeBasedCompare=timeBasedCompare, raise404=False)
516529
incrementCounter(getTechnique())
517530

@@ -530,7 +543,7 @@ def validateChar(idx, value):
530543

531544
threadData = getCurrentThreadData()
532545

533-
validationPayload = re.sub(r"(%s.*?)%s(.*?%s)" % (PAYLOAD_DELIMITER, INFERENCE_GREATER_CHAR, PAYLOAD_DELIMITER), r"\g<1>%s\g<2>" % INFERENCE_NOT_EQUALS_CHAR, payload)
546+
validationPayload = replaceInferenceOperator(payload, INFERENCE_NOT_EQUALS_CHAR) if PAYLOAD_DELIMITER in payload else payload
534547

535548
if "'%s'" % CHAR_INFERENCE_MARK not in payload:
536549
forgedPayload = safeStringFormat(validationPayload, (expressionUnescaped, idx, value))
@@ -668,7 +681,7 @@ def _hasEscape(n):
668681
# If it disagrees, the IN() channel is unreliable here: latch the technique off so the
669682
# classic '>' bisection takes over for the rest of the run (graceful fallback).
670683
if not kb.huffmanValidated:
671-
verifyPayload = safeStringFormat(payload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, value))
684+
verifyPayload = safeStringFormat(replaceInferenceOperator(payload, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, value))
672685
verified = Request.queryPage(verifyPayload, timeBasedCompare=timeBasedCompare, raise404=False)
673686
incrementCounter(getTechnique())
674687
if verified:
@@ -739,7 +752,7 @@ def getChar(idx, charTbl=None, continuousOrder=True, expand=charsetType is None,
739752
return None
740753

741754
elif len(charTbl) == 1:
742-
forgedPayload = safeStringFormat(payload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, charTbl[0]))
755+
forgedPayload = safeStringFormat(replaceInferenceOperator(payload, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, charTbl[0]))
743756
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
744757
incrementCounter(getTechnique())
745758

@@ -963,7 +976,7 @@ def getChar(idx, charTbl=None, continuousOrder=True, expand=charsetType is None,
963976
choice = sorted(bits.items(), key=lambda _: abs(_[1]))[0][0]
964977
mask = 1 << choice
965978

966-
forgedPayload = safeStringFormat(payload.replace(INFERENCE_GREATER_CHAR, "&%d%s" % (mask, INFERENCE_GREATER_CHAR)), (expressionUnescaped, idx, 0))
979+
forgedPayload = safeStringFormat(replaceInferenceOperator(payload, "&%d%s" % (mask, INFERENCE_GREATER_CHAR)), (expressionUnescaped, idx, 0))
967980
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
968981
incrementCounter(getTechnique())
969982

@@ -975,7 +988,7 @@ def getChar(idx, charTbl=None, continuousOrder=True, expand=charsetType is None,
975988
bit += 1
976989

977990
if candidates:
978-
forgedPayload = safeStringFormat(payload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, candidates[0]))
991+
forgedPayload = safeStringFormat(replaceInferenceOperator(payload, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, candidates[0]))
979992
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
980993
incrementCounter(getTechnique())
981994

0 commit comments

Comments
 (0)