Update for an Issue #431

This commit is contained in:
Miroslav Stampar 2014-11-21 11:20:54 +01:00
parent 1fc4d0e3c4
commit f0802c6fb9
3 changed files with 38 additions and 28 deletions

View File

@ -85,6 +85,8 @@ def checkSqlInjection(place, parameter, value):
# Set the flag for SQL injection test mode # Set the flag for SQL injection test mode
kb.testMode = True kb.testMode = True
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
tests = getSortedInjectionTests() tests = getSortedInjectionTests()
while tests: while tests:
@ -403,7 +405,7 @@ def checkSqlInjection(place, parameter, value):
# Perform the test's False request # Perform the test's False request
if not falseResult: if not falseResult:
infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (place, parameter, title) infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (paramType, parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -414,7 +416,7 @@ def checkSqlInjection(place, parameter, value):
candidates = filter(None, (_.strip() if _.strip() in (kb.pageTemplate or "") and _.strip() not in falsePage and _.strip() not in threadData.lastComparisonHeaders else None for _ in (trueSet - falseSet))) candidates = filter(None, (_.strip() if _.strip() in (kb.pageTemplate or "") and _.strip() not in falsePage and _.strip() not in threadData.lastComparisonHeaders else None for _ in (trueSet - falseSet)))
if candidates: if candidates:
conf.string = candidates[0] conf.string = candidates[0]
infoMsg = "%s parameter '%s' seems to be '%s' injectable (with --string=\"%s\")" % (place, parameter, title, repr(conf.string).lstrip('u').strip("'")) infoMsg = "%s parameter '%s' seems to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'"))
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -437,7 +439,7 @@ def checkSqlInjection(place, parameter, value):
result = output == "1" result = output == "1"
if result: if result:
infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title) infoMsg = "%s parameter '%s' is '%s' injectable " % (paramType, parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -459,7 +461,7 @@ def checkSqlInjection(place, parameter, value):
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False) trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
if trueResult: if trueResult:
infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (place, parameter, title) infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (paramType, parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -495,7 +497,7 @@ def checkSqlInjection(place, parameter, value):
reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix) reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix)
if isinstance(reqPayload, basestring): if isinstance(reqPayload, basestring):
infoMsg = "%s parameter '%s' is '%s' injectable" % (place, parameter, title) infoMsg = "%s parameter '%s' is '%s' injectable" % (paramType, parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -787,6 +789,8 @@ def heuristicCheckSqlInjection(place, parameter):
origValue = conf.paramDict[place][parameter] origValue = conf.paramDict[place][parameter]
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
prefix = "" prefix = ""
suffix = "" suffix = ""
@ -812,8 +816,8 @@ def heuristicCheckSqlInjection(place, parameter):
parseFilePaths(page) parseFilePaths(page)
result = wasLastResponseDBMSError() result = wasLastResponseDBMSError()
infoMsg = "heuristic (basic) test shows that %s " % place infoMsg = "heuristic (basic) test shows that %s parameter " % paramType
infoMsg += "parameter '%s' might " % parameter infoMsg += "'%s' might " % parameter
def _(page): def _(page):
return any(_ in (page or "") for _ in FORMAT_EXCEPTION_STRINGS) return any(_ in (page or "") for _ in FORMAT_EXCEPTION_STRINGS)
@ -861,9 +865,11 @@ def heuristicCheckSqlInjection(place, parameter):
payload = agent.payload(place, parameter, newValue=payload) payload = agent.payload(place, parameter, newValue=payload)
page, _ = Request.queryPage(payload, place, content=True, raise404=False) page, _ = Request.queryPage(payload, place, content=True, raise404=False)
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
if value in (page or ""): if value in (page or ""):
infoMsg = "heuristic (XSS) test shows that %s " % place infoMsg = "heuristic (XSS) test shows that %s parameter " % paramType
infoMsg += "parameter '%s' might " % parameter infoMsg += "'%s' might " % parameter
infoMsg += "be vulnerable to XSS attacks" infoMsg += "be vulnerable to XSS attacks"
logger.info(infoMsg) logger.info(infoMsg)
@ -885,7 +891,9 @@ def checkDynParam(place, parameter, value):
dynResult = None dynResult = None
randInt = randomInt() randInt = randomInt()
infoMsg = "testing if %s parameter '%s' is dynamic" % (place, parameter) paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
infoMsg = "testing if %s parameter '%s' is dynamic" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
try: try:
@ -893,7 +901,7 @@ def checkDynParam(place, parameter, value):
dynResult = Request.queryPage(payload, place, raise404=False) dynResult = Request.queryPage(payload, place, raise404=False)
if not dynResult: if not dynResult:
infoMsg = "confirming that %s parameter '%s' is dynamic" % (place, parameter) infoMsg = "confirming that %s parameter '%s' is dynamic" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
randInt = randomInt() randInt = randomInt()

View File

@ -311,13 +311,13 @@ def start():
if conf.forms: if conf.forms:
message = "[#%d] form:\n%s %s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl) message = "[#%d] form:\n%s %s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl)
else: else:
message = "URL %d:\n%s %s%s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl, " (PageRank: %s)" % get_pagerank(targetUrl) if conf.googleDork and conf.pageRank else "") message = "URL %d:\n%s %s%s" % (hostCount, HTTPMETHOD.GET, targetUrl, " (PageRank: %s)" % get_pagerank(targetUrl) if conf.googleDork and conf.pageRank else "")
if conf.cookie: if conf.cookie:
message += "\nCookie: %s" % conf.cookie message += "\nCookie: %s" % conf.cookie
if conf.data is not None: if conf.data is not None:
message += "\nPOST data: %s" % urlencode(conf.data) if conf.data else "" message += "\n%s data: %s" % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST, urlencode(conf.data) if conf.data else "")
if conf.forms: if conf.forms:
if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1: if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1:
@ -327,13 +327,13 @@ def start():
test = readInput(message, default="Y") test = readInput(message, default="Y")
if not test or test[0] in ("y", "Y"): if not test or test[0] in ("y", "Y"):
if conf.method == HTTPMETHOD.POST: if conf.method != HTTPMETHOD.GET:
message = "Edit POST data [default: %s]%s: " % (urlencode(conf.data) if conf.data else "None", " (Warning: blank fields detected)" if conf.data and extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data) else "") message = "Edit %s data [default: %s]%s: " % (conf.method, urlencode(conf.data) if conf.data else "None", " (Warning: blank fields detected)" if conf.data and extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data) else "")
conf.data = readInput(message, default=conf.data) conf.data = readInput(message, default=conf.data)
conf.data = _randomFillBlankFields(conf.data) conf.data = _randomFillBlankFields(conf.data)
conf.data = urldecode(conf.data) if conf.data and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in conf.data else conf.data conf.data = urldecode(conf.data) if conf.data and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in conf.data else conf.data
elif conf.method == HTTPMETHOD.GET: else:
if targetUrl.find("?") > -1: if targetUrl.find("?") > -1:
firstPart = targetUrl[:targetUrl.find("?")] firstPart = targetUrl[:targetUrl.find("?")]
secondPart = targetUrl[targetUrl.find("?") + 1:] secondPart = targetUrl[targetUrl.find("?") + 1:]
@ -428,6 +428,8 @@ def start():
paramDict = conf.paramDict[place] paramDict = conf.paramDict[place]
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
for parameter, value in paramDict.items(): for parameter, value in paramDict.items():
if not proceed: if not proceed:
break break
@ -439,7 +441,7 @@ def start():
if paramKey in kb.testedParams: if paramKey in kb.testedParams:
testSqlInj = False testSqlInj = False
infoMsg = "skipping previously processed %s parameter '%s'" % (place, parameter) infoMsg = "skipping previously processed %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif parameter in conf.testParameter: elif parameter in conf.testParameter:
@ -448,13 +450,13 @@ def start():
elif parameter == conf.rParam: elif parameter == conf.rParam:
testSqlInj = False testSqlInj = False
infoMsg = "skipping randomizing %s parameter '%s'" % (place, parameter) infoMsg = "skipping randomizing %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif parameter in conf.skip: elif parameter in conf.skip:
testSqlInj = False testSqlInj = False
infoMsg = "skipping %s parameter '%s'" % (place, parameter) infoMsg = "skipping %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif parameter == conf.csrfToken: elif parameter == conf.csrfToken:
@ -467,18 +469,18 @@ def start():
elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)): elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)):
testSqlInj = False testSqlInj = False
infoMsg = "ignoring %s parameter '%s'" % (place, parameter) infoMsg = "ignoring %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif PAYLOAD.TECHNIQUE.BOOLEAN in conf.tech: elif PAYLOAD.TECHNIQUE.BOOLEAN in conf.tech:
check = checkDynParam(place, parameter, value) check = checkDynParam(place, parameter, value)
if not check: if not check:
warnMsg = "%s parameter '%s' does not appear dynamic" % (place, parameter) warnMsg = "%s parameter '%s' does not appear dynamic" % (paramType, parameter)
logger.warn(warnMsg) logger.warn(warnMsg)
else: else:
infoMsg = "%s parameter '%s' is dynamic" % (place, parameter) infoMsg = "%s parameter '%s' is dynamic" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
kb.testedParams.add(paramKey) kb.testedParams.add(paramKey)
@ -488,11 +490,11 @@ def start():
if check != HEURISTIC_TEST.POSITIVE: if check != HEURISTIC_TEST.POSITIVE:
if conf.smart or (kb.ignoreCasted and check == HEURISTIC_TEST.CASTED): if conf.smart or (kb.ignoreCasted and check == HEURISTIC_TEST.CASTED):
infoMsg = "skipping %s parameter '%s'" % (place, parameter) infoMsg = "skipping %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
continue continue
infoMsg = "testing for SQL injection on %s " % place infoMsg = "testing for SQL injection on %s " % paramType
infoMsg += "parameter '%s'" % parameter infoMsg += "parameter '%s'" % parameter
logger.info(infoMsg) logger.info(infoMsg)
@ -515,7 +517,7 @@ def start():
paramKey = (conf.hostname, conf.path, None, None) paramKey = (conf.hostname, conf.path, None, None)
kb.testedParams.add(paramKey) kb.testedParams.add(paramKey)
else: else:
warnMsg = "%s parameter '%s' is not " % (place, parameter) warnMsg = "%s parameter '%s' is not " % (paramType, parameter)
warnMsg += "injectable" warnMsg += "injectable"
logger.warn(warnMsg) logger.warn(warnMsg)

View File

@ -285,7 +285,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
line = line.strip('\r') line = line.strip('\r')
match = re.search(r"\A(%s) (.+) HTTP/[\d.]+\Z" % "|".join(getPublicTypeMembers(HTTPMETHOD, True)), line) if not method else None match = re.search(r"\A(%s) (.+) HTTP/[\d.]+\Z" % "|".join(getPublicTypeMembers(HTTPMETHOD, True)), line) if not method else None
if len(line) == 0 and method in (HTTPMETHOD.POST, HTTPMETHOD.PUT) and data is None: if len(line) == 0 and method and method != HTTPMETHOD.GET and data is None:
data = "" data = ""
params = True params = True
@ -1780,11 +1780,11 @@ def _useWizardInterface():
message = "Please enter full target URL (-u): " message = "Please enter full target URL (-u): "
conf.url = readInput(message, default=None) conf.url = readInput(message, default=None)
message = "POST data (--data) [Enter for None]: " message = "%s data (--data) [Enter for None]: " % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST)
conf.data = readInput(message, default=None) conf.data = readInput(message, default=None)
if not (filter(lambda _: '=' in unicode(_), (conf.url, conf.data)) or '*' in conf.url): if not (filter(lambda _: '=' in unicode(_), (conf.url, conf.data)) or '*' in conf.url):
warnMsg = "no GET and/or POST parameter(s) found for testing " warnMsg = "no GET and/or %s parameter(s) found for testing " % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST)
warnMsg += "(e.g. GET parameter 'id' in 'http://www.site.com/vuln.php?id=1'). " warnMsg += "(e.g. GET parameter 'id' in 'http://www.site.com/vuln.php?id=1'). "
if not conf.crawlDepth and not conf.forms: if not conf.crawlDepth and not conf.forms:
warnMsg += "Will search for forms" warnMsg += "Will search for forms"