More improvements

This commit is contained in:
Miroslav Stampar 2016-06-03 15:51:52 +02:00
parent 350baf0a0a
commit 78fdb27a0b
2 changed files with 48 additions and 27 deletions

View File

@ -446,12 +446,12 @@ def checkSqlInjection(place, parameter, value):
kb.matchRatio = None
kb.negativeLogic = (where == PAYLOAD.WHERE.NEGATIVE)
Request.queryPage(genCmpPayload(), place, raise404=False)
falsePage, falseHeaders = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders
falsePage, falseHeaders, falseCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
falseRawResponse = "%s%s" % (falseHeaders, falsePage)
# Perform the test's True request
trueResult = Request.queryPage(reqPayload, place, raise404=False)
truePage, trueHeaders = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders
truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
trueRawResponse = "%s%s" % (trueHeaders, truePage)
if trueResult and not(truePage == falsePage and not kb.nullConnection):
@ -473,32 +473,52 @@ def checkSqlInjection(place, parameter, value):
kb.matchRatio = _
logger.debug("adjusting match ratio for current parameter to %.3f" % kb.matchRatio)
injectable = True
if injectable and kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
if all((falseCode, trueCode)) and falseCode != trueCode:
conf.code = trueCode
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --code=%d)" % (paramType, parameter, title, conf.code)
logger.info(infoMsg)
else:
trueSet = set(extractTextTagContent(trueRawResponse))
trueSet = trueSet.union(__ for _ in trueSet for __ in _.split())
falseSet = set(extractTextTagContent(falseRawResponse))
falseSet = falseSet.union(__ for _ in falseSet for __ in _.split())
candidates = filter(None, (_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet)))
if candidates:
candidates = sorted(candidates, key=lambda _: len(_))
for candidate in candidates:
if re.match(r"\A\w+\Z", candidate):
break
conf.string = candidate
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'"))
logger.info(infoMsg)
if not any((conf.string, conf.notString)):
candidates = filter(None, (_.strip() if _.strip() in falseRawResponse and _.strip() not in trueRawResponse else None for _ in (falseSet - trueSet)))
if candidates:
candidates = sorted(candidates, key=lambda _: len(_))
for candidate in candidates:
if re.match(r"\A\w+\Z", candidate):
break
conf.notString = candidate
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --not-string=\"%s\")" % (paramType, parameter, title, repr(conf.notString).lstrip('u').strip("'"))
logger.info(infoMsg)
if not any((conf.string, conf.notString, conf.code)):
infoMsg = "%s parameter '%s' appears to be '%s' injectable " % (paramType, parameter, title)
logger.info(infoMsg)
injectable = True
if not any((conf.string, conf.notString, conf.regexp, conf.code)) and kb.pageStable and injectable:
trueSet = set(extractTextTagContent(trueRawResponse))
trueSet = trueSet.union(__ for _ in trueSet for __ in _.split())
falseSet = set(extractTextTagContent(falseRawResponse))
falseSet = falseSet.union(__ for _ in falseSet for __ in _.split())
candidates = filter(None, (_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet)))
if candidates:
candidates = sorted(candidates, key=lambda _: len(_))
for candidate in candidates:
if re.match(r"\A\w+\Z", candidate):
break
conf.string = candidate
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'"))
logger.info(infoMsg)
injectable = True
# In case of error-based SQL injection
elif method == PAYLOAD.METHOD.GREP:
# Perform the test's request and grep the response
@ -648,6 +668,7 @@ def checkSqlInjection(place, parameter, value):
injection.conf.textOnly = conf.textOnly
injection.conf.titles = conf.titles
injection.conf.code = conf.code
injection.conf.string = conf.string
injection.conf.notString = conf.notString
injection.conf.regexp = conf.regexp

View File

@ -19,7 +19,7 @@ from lib.core.enums import OS
from lib.core.revision import getRevisionNumber
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.0.6.22"
VERSION = "1.0.6.23"
REVISION = getRevisionNumber()
STABLE = VERSION.count('.') <= 2
VERSION_STRING = "sqlmap/%s#%s" % (VERSION, "stable" if STABLE else "dev")
@ -540,7 +540,7 @@ HASHDB_FLUSH_RETRIES = 3
HASHDB_END_TRANSACTION_RETRIES = 3
# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism)
HASHDB_MILESTONE_VALUE = "ERqvmQHalF" # "".join(random.sample(string.ascii_letters, 10))
HASHDB_MILESTONE_VALUE = "pGBhWXgbtJ" # import random, string; print "".join(random.sample(string.ascii_letters, 10))
# Warn user of possible delay due to large page dump in full UNION query injections
LARGE_OUTPUT_THRESHOLD = 1024 ** 2