Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5908964

Browse files
committed
Another (better) patch for #1636
1 parent 0f8a551 commit 5908964

7 files changed

Lines changed: 37 additions & 37 deletions

File tree

lib/core/common.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,16 +2222,16 @@ def wasLastResponseDelayed():
22222222
# response times should be inside +-7*stdev([normal response times])
22232223
# Math reference: http://www.answers.com/topic/standard-deviation
22242224

2225-
deviation = stdev(kb.responseTimes)
2225+
deviation = stdev(kb.responseTimes.get(kb.responseTimeMode, []))
22262226
threadData = getCurrentThreadData()
22272227

22282228
if deviation and not conf.direct:
2229-
if len(kb.responseTimes) < MIN_TIME_RESPONSES:
2229+
if len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES:
22302230
warnMsg = "time-based standard deviation method used on a model "
22312231
warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES
22322232
logger.warn(warnMsg)
22332233

2234-
lowerStdLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation
2234+
lowerStdLimit = average(kb.responseTimes[kb.responseTimeMode]) + TIME_STDEV_COEFF * deviation
22352235
retVal = (threadData.lastQueryDuration >= max(MIN_VALID_DELAYED_RESPONSE, lowerStdLimit))
22362236

22372237
if not kb.testMode and retVal:

lib/core/option.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,7 +1891,9 @@ def _setKnowledgeBaseAttributes(flushAll=True):
18911891
kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS: 0, REFLECTIVE_COUNTER.HIT: 0}
18921892
kb.requestCounter = 0
18931893
kb.resendPostOnRedirect = None
1894-
kb.responseTimes = []
1894+
kb.responseTimes = {}
1895+
kb.responseTimeMode = None
1896+
kb.responseTimePayload = None
18951897
kb.resumeValues = True
18961898
kb.safeCharEncode = False
18971899
kb.safeReq = AttribDict()
@@ -1915,7 +1917,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
19151917
kb.timeValidCharsRun = 0
19161918
kb.uChar = NULL
19171919
kb.unionDuplicates = False
1918-
kb.whereCollectTimes = False
19191920
kb.xpCmdshellAvailable = False
19201921

19211922
if flushAll:

lib/core/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
ASTERISK_MARKER = "__ASTERISK_MARK__"
6262
REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
6363

64+
RANDOM_INTEGER_MARKER = "[RANDINT]"
65+
RANDOM_STRING_MARKER = "[RANDSTR]"
66+
6467
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
6568
CHAR_INFERENCE_MARK = "%c"
6669
PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]"

lib/request/connect.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class WebSocketException(Exception):
9797
from lib.core.settings import PAYLOAD_DELIMITER
9898
from lib.core.settings import PERMISSION_DENIED_REGEX
9999
from lib.core.settings import PLAIN_TEXT_CONTENT_TYPE
100+
from lib.core.settings import RANDOM_INTEGER_MARKER
101+
from lib.core.settings import RANDOM_STRING_MARKER
100102
from lib.core.settings import REPLACEMENT_MARKER
101103
from lib.core.settings import TEXT_CONTENT_TYPE_REGEX
102104
from lib.core.settings import UNENCODED_ORIGINAL_VALUE
@@ -1020,34 +1022,37 @@ def _randomizeParameter(paramString, randomParameter):
10201022
post = urlencode(post, spaceplus=kb.postSpaceToPlus)
10211023

10221024
if timeBasedCompare:
1023-
if len(kb.responseTimes) < MIN_TIME_RESPONSES:
1025+
if len(kb.responseTimes.get(kb.responseTimeMode, [])) < MIN_TIME_RESPONSES:
10241026
clearConsoleLine()
10251027

1028+
kb.responseTimes.setdefault(kb.responseTimeMode, [])
1029+
10261030
if conf.tor:
10271031
warnMsg = "it's highly recommended to avoid usage of switch '--tor' for "
10281032
warnMsg += "time-based injections because of its high latency time"
10291033
singleTimeWarnMessage(warnMsg)
10301034

1031-
warnMsg = "[%s] [WARNING] time-based comparison requires " % time.strftime("%X")
1035+
warnMsg = "[%s] [WARNING] %stime-based comparison requires " % (time.strftime("%X"), "(case) " if kb.responseTimeMode else "")
10321036
warnMsg += "larger statistical model, please wait"
10331037
dataToStdout(warnMsg)
10341038

1035-
while len(kb.responseTimes) < MIN_TIME_RESPONSES:
1036-
Connect.queryPage(content=True)
1039+
while len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES:
1040+
value = kb.responseTimePayload.replace(RANDOM_INTEGER_MARKER, str(randomInt(6))).replace(RANDOM_STRING_MARKER, randomStr()) if kb.responseTimePayload else kb.responseTimePayload
1041+
Connect.queryPage(value=value, content=True, raise404=False)
10371042
dataToStdout('.')
10381043

1039-
dataToStdout("\n")
1044+
dataToStdout(" (done)\n")
10401045

10411046
elif not kb.testMode:
1042-
warnMsg = "it is very important not to stress the network adapter "
1047+
warnMsg = "it is very important to not stress the network adapter "
10431048
warnMsg += "during usage of time-based payloads to prevent potential "
1044-
warnMsg += "errors "
1049+
warnMsg += "disruptions "
10451050
singleTimeWarnMessage(warnMsg)
10461051

10471052
if not kb.laggingChecked:
10481053
kb.laggingChecked = True
10491054

1050-
deviation = stdev(kb.responseTimes)
1055+
deviation = stdev(kb.responseTimes[kb.responseTimeMode])
10511056

10521057
if deviation > WARN_TIME_STDEV:
10531058
kb.adjustTimeDelay = ADJUST_TIME_DELAY.DISABLE
@@ -1115,7 +1120,8 @@ def _randomizeParameter(paramString, randomParameter):
11151120
if timeBasedCompare:
11161121
return wasLastResponseDelayed()
11171122
elif noteResponseTime:
1118-
kb.responseTimes.append(threadData.lastQueryDuration)
1123+
kb.responseTimes.setdefault(kb.responseTimeMode, [])
1124+
kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration)
11191125

11201126
if not response and removeReflection:
11211127
page = removeReflectiveValues(page, payload)

lib/request/inject.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
432432
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
433433

434434
if time and (isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED)) and not found:
435+
kb.responseTimeMode = re.sub(r"(?i)[^a-z]", "", re.sub(r"'[^']+'", "", expression)) if re.search(r"(?i)SELECT.+FROM", expression) else None
436+
435437
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME):
436438
kb.technique = PAYLOAD.TECHNIQUE.TIME
437439
else:
@@ -441,14 +443,14 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
441443
value = _goBooleanProxy(booleanExpression)
442444
else:
443445
value = _goInferenceProxy(query, fromUser, batch, unpack, charsetType, firstChar, lastChar, dump)
444-
445446
else:
446447
errMsg = "none of the injection types identified can be "
447448
errMsg += "leveraged to retrieve queries output"
448449
raise SqlmapNotVulnerableException(errMsg)
449450

450451
finally:
451452
kb.resumeValues = True
453+
kb.responseTimeMode = None
452454

453455
conf.tbl = popValue()
454456
conf.db = popValue()

lib/techniques/blind/inference.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@
4747
from lib.core.settings import MIN_TIME_RESPONSES
4848
from lib.core.settings import MAX_BISECTION_LENGTH
4949
from lib.core.settings import MAX_TIME_REVALIDATION_STEPS
50+
from lib.core.settings import NULL
5051
from lib.core.settings import PARTIAL_HEX_VALUE_MARKER
5152
from lib.core.settings import PARTIAL_VALUE_MARKER
53+
from lib.core.settings import RANDOM_INTEGER_MARKER
5254
from lib.core.settings import VALID_TIME_CHARS_RUN_THRESHOLD
5355
from lib.core.threads import getCurrentThreadData
5456
from lib.core.threads import runThreads
@@ -261,29 +263,23 @@ def getChar(idx, charTbl=None, continuousOrder=True, expand=charsetType is None,
261263
while len(charTbl) != 1:
262264
position = (len(charTbl) >> 1)
263265
posValue = charTbl[position]
266+
falsePayload = None
264267

265268
if "'%s'" % CHAR_INFERENCE_MARK not in payload:
266269
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue))
270+
falsePayload = safeStringFormat(payload, (expressionUnescaped, idx, RANDOM_INTEGER_MARKER))
267271
else:
268272
# e.g.: ... > '%c' -> ... > ORD(..)
269273
markingValue = "'%s'" % CHAR_INFERENCE_MARK
270274
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
271275
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx)).replace(markingValue, unescapedCharValue)
276+
falsePayload = safeStringFormat(payload, (expressionUnescaped, idx)).replace(markingValue, NULL)
272277

273-
if timeBasedCompare and kb.whereCollectTimes:
274-
kb.responseTimes = []
275-
276-
warnMsg = "\n[%s] [WARNING] time-based comparison requires " % time.strftime("%X")
277-
warnMsg += "larger statistical model, please wait"
278-
dataToStdout(warnMsg)
279-
280-
while len(kb.responseTimes) < MIN_TIME_RESPONSES:
281-
falseWherePayload = re.sub(r"\b%s\b" % posValue, str(randomInt(6)), forgedPayload)
282-
Request.queryPage(falseWherePayload, content=True, raise404=False)
283-
dataToStdout('.')
284-
285-
dataToStdout("\n")
286-
kb.whereCollectTimes = False
278+
if timeBasedCompare:
279+
if kb.responseTimeMode:
280+
kb.responseTimePayload = falsePayload
281+
else:
282+
kb.responseTimePayload = None
287283

288284
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
289285
incrementCounter(kb.technique)

plugins/generic/entries.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,6 @@ def dumpTable(self, foundData=None):
236236

237237
query = whereQuery(query)
238238

239-
if conf.dumpWhere:
240-
kb.whereCollectTimes = True
241-
pushValue(kb.responseTimes)
242-
243239
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
244240

245241
lengths = {}
@@ -328,10 +324,6 @@ def dumpTable(self, foundData=None):
328324
warnMsg = "Ctrl+C detected in dumping phase"
329325
logger.warn(warnMsg)
330326

331-
if conf.dumpWhere:
332-
kb.responseTimes = popValue()
333-
kb.whereCollectTimes = False
334-
335327
for column, columnEntries in entries.items():
336328
length = max(lengths[column], len(column))
337329

0 commit comments

Comments
 (0)