sqlmap/lib/controller/controller.py

621 lines
26 KiB
Python
Raw Normal View History

2008-10-15 19:38:22 +04:00
#!/usr/bin/env python
"""
2012-07-12 21:38:03 +04:00
Copyright (c) 2006-2012 sqlmap developers (http://sqlmap.org/)
2010-10-15 03:18:29 +04:00
See the file 'doc/COPYING' for copying permission
2008-10-15 19:38:22 +04:00
"""
import os
2010-10-15 04:34:16 +04:00
import re
2008-10-15 19:38:22 +04:00
from lib.controller.action import action
from lib.controller.checks import checkSqlInjection
from lib.controller.checks import checkDynParam
from lib.controller.checks import checkStability
from lib.controller.checks import checkString
from lib.controller.checks import checkRegexp
2008-10-15 19:38:22 +04:00
from lib.controller.checks import checkConnection
2010-09-16 12:43:10 +04:00
from lib.controller.checks import checkNullConnection
from lib.controller.checks import checkWaf
from lib.controller.checks import heuristicCheckSqlInjection
from lib.core.agent import agent
from lib.core.common import extractRegexResult
2011-01-14 19:12:44 +03:00
from lib.core.common import getFilteredPageContent
from lib.core.common import getPublicTypeMembers
2010-06-02 16:45:40 +04:00
from lib.core.common import getUnicode
from lib.core.common import hashDBRetrieve
from lib.core.common import hashDBWrite
from lib.core.common import intersect
2010-03-05 18:25:53 +03:00
from lib.core.common import parseTargetUrl
from lib.core.common import randomStr
2008-10-15 19:38:22 +04:00
from lib.core.common import readInput
from lib.core.common import showHttpErrorCodes
2012-07-31 13:03:44 +04:00
from lib.core.common import urlencode
from lib.core.common import urldecode
2008-10-15 19:38:22 +04:00
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
2011-12-28 17:50:03 +04:00
from lib.core.enums import HASHDB_KEYS
from lib.core.enums import HEURISTIC_TEST
2011-11-29 23:17:07 +04:00
from lib.core.enums import HTTPHEADER
2010-11-08 12:44:32 +03:00
from lib.core.enums import HTTPMETHOD
from lib.core.enums import PAYLOAD
2010-11-08 12:44:32 +03:00
from lib.core.enums import PLACE
from lib.core.exception import exceptionsTuple
2011-05-24 21:15:25 +04:00
from lib.core.exception import sqlmapNoneDataException
2008-10-15 19:38:22 +04:00
from lib.core.exception import sqlmapNotVulnerableException
from lib.core.exception import sqlmapSilentQuitException
from lib.core.exception import sqlmapValueException
2010-09-30 23:45:23 +04:00
from lib.core.exception import sqlmapUserQuitException
2012-10-19 13:02:14 +04:00
from lib.core.settings import ASP_NET_CONTROL_REGEX
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
2011-11-22 01:31:08 +04:00
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import EMPTY_FORM_FIELDS_REGEX
from lib.core.settings import IGNORE_PARAMETERS
from lib.core.settings import LOW_TEXT_PERCENT
from lib.core.settings import HOST_ALIASES
from lib.core.settings import REFERER_ALIASES
from lib.core.settings import USER_AGENT_ALIASES
2010-03-15 14:55:13 +03:00
from lib.core.target import initTargetEnv
from lib.core.target import setupTargetEnv
2012-07-14 19:01:04 +04:00
from thirdparty.pagerank.pagerank import get_pagerank
2008-10-15 19:38:22 +04:00
def __selectInjection():
2008-10-15 19:38:22 +04:00
"""
Selection function for injection place, parameters and type.
"""
points = {}
2008-10-15 19:38:22 +04:00
for injection in kb.injections:
place = injection.place
parameter = injection.parameter
ptype = injection.ptype
2008-10-15 19:38:22 +04:00
point = (place, parameter, ptype)
2008-10-15 19:38:22 +04:00
if point not in points:
points[point] = injection
else:
for key in points[point].keys():
if key != 'data':
points[point][key] = points[point][key] or injection[key]
points[point]['data'].update(injection['data'])
2008-10-15 19:38:22 +04:00
if len(points) == 1:
kb.injection = kb.injections[0]
2010-11-30 17:48:13 +03:00
elif len(points) > 1:
message = "there were multiple injection points, please select "
message += "the one to use for following injections:\n"
2008-10-15 19:38:22 +04:00
points = []
2008-10-15 19:38:22 +04:00
for i in xrange(0, len(kb.injections)):
place = kb.injections[i].place
parameter = kb.injections[i].parameter
ptype = kb.injections[i].ptype
point = (place, parameter, ptype)
2008-10-15 19:38:22 +04:00
if point not in points:
points.append(point)
ptype = PAYLOAD.PARAMETER[ptype] if isinstance(ptype, int) else ptype
2008-10-15 19:38:22 +04:00
message += "[%d] place: %s, parameter: " % (i, place)
message += "%s, type: %s" % (parameter, ptype)
2008-10-15 19:38:22 +04:00
if i == 0:
message += " (default)"
2008-10-15 19:38:22 +04:00
message += "\n"
message += "[q] Quit"
select = readInput(message, default="0")
if select.isdigit() and int(select) < len(kb.injections) and int(select) >= 0:
index = int(select)
elif select[0] in ( "Q", "q" ):
raise sqlmapUserQuitException
else:
errMsg = "invalid choice"
2010-11-29 02:33:51 +03:00
raise sqlmapValueException, errMsg
kb.injection = kb.injections[index]
def __formatInjection(inj):
data = "Place: %s\n" % inj.place
data += "Parameter: %s\n" % inj.parameter
for stype, sdata in inj.data.items():
title = sdata.title
2012-02-10 19:34:04 +04:00
vector = sdata.vector
comment = sdata.comment
if stype == PAYLOAD.TECHNIQUE.UNION:
2012-05-09 18:58:16 +04:00
count = re.sub(r"(?i)(\(.+\))|(\blimit[^A-Za-z]+)", "", sdata.payload).count(',') + 1
title = re.sub(r"\d+ to \d+", str(count), title)
vector = agent.forgeInbandQuery("[QUERY]", vector[0], vector[1], vector[2], None, None, vector[5], vector[6])
if count == 1:
title = title.replace("columns", "column")
elif comment:
vector = "%s%s" % (vector, comment)
2010-12-03 19:11:35 +03:00
data += " Type: %s\n" % PAYLOAD.SQLINJECTION[stype]
data += " Title: %s\n" % title
data += " Payload: %s\n" % agent.adjustLateValues(sdata.payload)
2012-02-10 19:34:04 +04:00
data += " Vector: %s\n\n" % vector if conf.verbose > 1 else "\n"
return data
def __showInjections():
header = "sqlmap identified the following injection points with "
header += "a total of %d HTTP(s) requests" % kb.testQueryCount
data = "".join(set(map(lambda x: __formatInjection(x), kb.injections))).rstrip("\n")
2010-11-30 17:48:13 +03:00
conf.dumper.technic(header, data)
2008-10-15 19:38:22 +04:00
2011-06-09 13:58:42 +04:00
if conf.tamper:
infoMsg = "changes made by tampering scripts are not "
infoMsg += "included in shown payload content(s)"
logger.info(infoMsg)
def __randomFillBlankFields(value):
retVal = value
if extractRegexResult(EMPTY_FORM_FIELDS_REGEX, value):
message = "do you want to fill blank fields with random values? [Y/n] "
test = readInput(message, default="Y")
if not test or test[0] in ("y", "Y"):
2012-09-06 16:13:54 +04:00
for match in re.finditer(EMPTY_FORM_FIELDS_REGEX, retVal):
item = match.group("result")
2012-10-19 13:02:14 +04:00
if not any(_ in item for _ in IGNORE_PARAMETERS) and not re.search(ASP_NET_CONTROL_REGEX, item):
2012-09-06 16:13:54 +04:00
if item[-1] == DEFAULT_GET_POST_DELIMITER:
retVal = retVal.replace(item, "%s%s%s" % (item[:-1], randomStr(), DEFAULT_GET_POST_DELIMITER))
else:
retVal = retVal.replace(item, "%s%s" % (item, randomStr()))
return retVal
def __saveToHashDB():
2012-02-27 19:28:36 +04:00
injections = hashDBRetrieve(HASHDB_KEYS.KB_INJECTIONS, True) or []
injections.extend(_ for _ in kb.injections if _ and _.place is not None and _.parameter is not None)
_ = dict()
for injection in injections:
key = (injection.place, injection.parameter, injection.ptype)
if key not in _:
_[key] = injection
else:
_[key].data.update(injection.data)
hashDBWrite(HASHDB_KEYS.KB_INJECTIONS, _.values(), True)
2012-02-27 17:44:07 +04:00
_ = hashDBRetrieve(HASHDB_KEYS.KB_ABS_FILE_PATHS, True) or set()
2011-12-28 17:50:03 +04:00
_.update(kb.absFilePaths)
hashDBWrite(HASHDB_KEYS.KB_ABS_FILE_PATHS, _, True)
2011-12-28 17:50:03 +04:00
if not hashDBRetrieve(HASHDB_KEYS.KB_CHARS):
hashDBWrite(HASHDB_KEYS.KB_CHARS, kb.chars, True)
2012-02-28 18:04:13 +04:00
if not hashDBRetrieve(HASHDB_KEYS.KB_DYNAMIC_MARKINGS):
hashDBWrite(HASHDB_KEYS.KB_DYNAMIC_MARKINGS, kb.dynamicMarkings, True)
def __saveToResultsFile():
if not conf.resultsFP:
return
found = False
results = {}
2011-06-08 19:31:27 +04:00
techniques = dict(map(lambda x: (x[1], x[0]), getPublicTypeMembers(PAYLOAD.TECHNIQUE)))
for inj in kb.injections:
if inj.place is None or inj.parameter is None:
continue
key = (inj.place, inj.parameter)
if key not in results:
results[key] = []
results[key].extend(inj.data.keys())
for key, value in results.items():
place, parameter = key
line = "%s,%s,%s,%s%s" % (conf.url, place, parameter, "".join(map(lambda x: techniques[x][0].upper(), sorted(value))), os.linesep)
conf.resultsFP.writelines(line)
if not results:
line = "%s,,,%s" % (conf.url, os.linesep)
conf.resultsFP.writelines(line)
2011-06-08 18:15:34 +04:00
2008-10-15 19:38:22 +04:00
def start():
"""
This function calls a function that performs checks on both URL
stability and all GET, POST, Cookie and User-Agent parameters to
check if they are dynamic and SQL injection affected
"""
if not conf.start:
2010-09-26 18:56:55 +04:00
return False
if conf.direct:
initTargetEnv()
setupTargetEnv()
action()
2010-09-26 18:56:55 +04:00
return True
2012-08-22 18:50:01 +04:00
if conf.url and not any((conf.forms, conf.crawlDepth)):
2012-08-15 18:37:18 +04:00
kb.targetUrls.add((conf.url, conf.method, conf.data, conf.cookie))
2008-10-15 19:38:22 +04:00
if conf.configFile and not kb.targetUrls:
2011-04-30 17:20:05 +04:00
errMsg = "you did not edit the configuration file properly, set "
errMsg += "the target url, list of targets or google dork"
2008-10-15 19:38:22 +04:00
logger.error(errMsg)
2010-09-26 18:56:55 +04:00
return False
2008-10-15 19:38:22 +04:00
if kb.targetUrls and len(kb.targetUrls) > 1:
infoMsg = "sqlmap got a total of %d targets" % len(kb.targetUrls)
logger.info(infoMsg)
2011-04-30 17:20:05 +04:00
hostCount = 0
cookieStr = ""
2008-10-15 19:38:22 +04:00
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
try:
2011-04-30 17:20:05 +04:00
conf.url = targetUrl
conf.method = targetMethod
2011-04-30 17:20:05 +04:00
conf.data = targetData
conf.cookie = targetCookie
2010-10-15 13:54:29 +04:00
2010-10-15 04:34:16 +04:00
initTargetEnv()
parseTargetUrl()
2010-10-15 13:54:29 +04:00
2010-10-15 04:34:16 +04:00
testSqlInj = False
2011-04-22 01:15:23 +04:00
2011-09-20 17:08:35 +04:00
if PLACE.GET in conf.parameters and not any([conf.data, conf.testParameter]):
2011-10-07 02:29:49 +04:00
for parameter in re.findall(r"([^=]+)=([^%s]+%s?|\Z)" % (conf.pDel or ";", conf.pDel or ";"), conf.parameters[PLACE.GET]):
paramKey = (conf.hostname, conf.path, PLACE.GET, parameter[0])
2011-04-22 01:15:23 +04:00
2010-10-15 04:34:16 +04:00
if paramKey not in kb.testedParams:
testSqlInj = True
break
2010-10-15 13:54:29 +04:00
else:
paramKey = (conf.hostname, conf.path, None, None)
if paramKey not in kb.testedParams:
testSqlInj = True
testSqlInj &= (conf.hostname, conf.path, None, None) not in kb.testedParams
2012-08-22 18:50:01 +04:00
testSqlInj &= conf.hostname not in kb.vulnHosts
2011-01-07 18:41:09 +03:00
2010-10-15 04:34:16 +04:00
if not testSqlInj:
infoMsg = "skipping '%s'" % targetUrl
logger.info(infoMsg)
continue
if conf.multipleTargets:
hostCount += 1
2011-04-22 01:15:23 +04:00
2010-11-15 14:50:33 +03:00
if conf.forms:
2010-11-29 15:46:18 +03:00
message = "[#%d] form:\n%s %s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl)
2010-11-15 14:50:33 +03:00
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 "")
if conf.cookie:
message += "\nCookie: %s" % conf.cookie
if conf.data:
2011-03-03 13:39:04 +03:00
message += "\nPOST data: %s" % urlencode(conf.data) if conf.data else ""
if conf.forms:
if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1:
continue
message += "\ndo you want to test this form? [Y/n/q] "
test = readInput(message, default="Y")
if not test or test[0] in ("y", "Y"):
if conf.method == HTTPMETHOD.POST:
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 "")
conf.data = readInput(message, default=conf.data)
conf.data = __randomFillBlankFields(conf.data)
2011-11-22 01:31:08 +04:00
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:
if targetUrl.find("?") > -1:
firstPart = targetUrl[:targetUrl.find("?")]
secondPart = targetUrl[targetUrl.find("?")+1:]
message = "Edit GET data [default: %s]: " % secondPart
test = readInput(message, default=secondPart)
test = __randomFillBlankFields(test)
conf.url = "%s?%s" % (firstPart, test)
parseTargetUrl()
elif test[0] in ("n", "N"):
continue
elif test[0] in ("q", "Q"):
break
2008-10-15 19:38:22 +04:00
2010-12-20 13:48:53 +03:00
else:
message += "\ndo you want to test this url? [Y/n/q]"
test = readInput(message, default="Y")
if not test or test[0] in ("y", "Y"):
pass
elif test[0] in ("n", "N"):
continue
elif test[0] in ("q", "Q"):
break
2008-10-15 19:38:22 +04:00
2012-09-26 17:03:12 +04:00
infoMsg = "testing url '%s'" % targetUrl
2011-04-30 19:29:59 +04:00
logger.info(infoMsg)
setupTargetEnv()
2010-12-03 16:19:34 +03:00
if not checkConnection(suppressOutput=conf.forms) or not checkString() or not checkRegexp():
2008-10-15 19:38:22 +04:00
continue
if conf.checkWaf:
checkWaf()
if conf.nullConnection:
checkNullConnection()
2010-09-16 12:43:10 +04:00
2011-05-11 01:33:06 +04:00
if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) \
and (kb.injection.place is None or kb.injection.parameter is None):
2011-05-05 20:38:46 +04:00
2012-07-26 14:06:02 +04:00
if not any((conf.string, conf.notString, conf.regexp)) and PAYLOAD.TECHNIQUE.BOOLEAN in conf.tech:
# NOTE: this is not needed anymore, leaving only to display
# a warning message to the user in case the page is not stable
checkStability()
2010-11-08 02:37:15 +03:00
# Do a little prioritization reorder of a testable parameter list
parameters = conf.parameters.keys()
# Order of testing list (last to first)
orderList = (PLACE.URI, PLACE.GET, PLACE.POST, PLACE.CUSTOM_POST)
for place in orderList:
2010-11-08 02:37:15 +03:00
if place in parameters:
parameters.remove(place)
parameters.insert(0, place)
proceed = True
2010-11-08 02:37:15 +03:00
for place in parameters:
# Test User-Agent and Referer headers only if
# --level >= 3
2012-07-26 14:26:57 +04:00
skip = (place == PLACE.USER_AGENT and conf.level < 3)
skip |= (place == PLACE.REFERER and conf.level < 3)
# Test Host header only if
# --level >= 5
skip |= (place == PLACE.HOST and conf.level < 5)
# Test Cookie header only if --level >= 2
skip |= (place == PLACE.COOKIE and conf.level < 2)
2012-07-26 14:26:57 +04:00
skip |= (place == PLACE.USER_AGENT and intersect(USER_AGENT_ALIASES, conf.skip, True) not in ([], None))
2011-08-29 17:47:32 +04:00
skip |= (place == PLACE.REFERER and intersect(REFERER_ALIASES, conf.skip, True) not in ([], None))
2012-02-12 23:22:33 +04:00
skip |= (place == PLACE.COOKIE and intersect(PLACE.COOKIE, conf.skip, True) not in ([], None))
2011-08-29 17:47:32 +04:00
2012-07-26 14:26:57 +04:00
skip &= not (place == PLACE.USER_AGENT and intersect(USER_AGENT_ALIASES, conf.testParameter, True))
2011-08-29 17:47:32 +04:00
skip &= not (place == PLACE.REFERER and intersect(REFERER_ALIASES, conf.testParameter, True))
skip &= not (place == PLACE.HOST and intersect(HOST_ALIASES, conf.testParameter, True))
if skip:
continue
2012-07-14 13:01:30 +04:00
if place not in conf.paramDict:
continue
paramDict = conf.paramDict[place]
for parameter, value in paramDict.items():
2010-12-31 18:00:19 +03:00
if not proceed:
break
2011-05-24 21:15:25 +04:00
kb.vainRun = False
testSqlInj = True
2011-06-08 19:31:27 +04:00
paramKey = (conf.hostname, conf.path, place, parameter)
2011-05-24 21:15:25 +04:00
if paramKey in kb.testedParams:
testSqlInj = False
2010-10-15 04:34:16 +04:00
infoMsg = "skipping previously processed %s parameter '%s'" % (place, parameter)
logger.info(infoMsg)
2011-08-29 17:29:42 +04:00
elif parameter in conf.testParameter:
pass
elif parameter == conf.rParam:
testSqlInj = False
infoMsg = "skipping randomizing %s parameter '%s'" % (place, parameter)
logger.info(infoMsg)
2011-08-29 17:29:42 +04:00
elif parameter in conf.skip:
testSqlInj = False
infoMsg = "skipping %s parameter '%s'" % (place, parameter)
logger.info(infoMsg)
2011-06-16 18:11:30 +04:00
2011-08-02 21:35:43 +04:00
# Ignore session-like parameters for --level < 4
elif conf.level < 4 and parameter.upper() in IGNORE_PARAMETERS:
testSqlInj = False
infoMsg = "ignoring %s parameter '%s'" % (place, parameter)
logger.info(infoMsg)
2011-10-22 02:21:41 +04:00
elif PAYLOAD.TECHNIQUE.BOOLEAN in conf.tech:
2012-08-20 14:14:01 +04:00
check = checkDynParam(place, parameter, value)
if not check:
2012-10-04 13:34:14 +04:00
warnMsg = "%s parameter '%s' does not appear dynamic" % (place, parameter)
2011-10-22 02:21:41 +04:00
logger.warn(warnMsg)
2010-10-15 04:34:16 +04:00
2011-10-22 02:21:41 +04:00
else:
infoMsg = "%s parameter '%s' is dynamic" % (place, parameter)
logger.info(infoMsg)
2008-10-15 19:38:22 +04:00
kb.testedParams.add(paramKey)
if testSqlInj:
2011-01-15 16:15:10 +03:00
check = heuristicCheckSqlInjection(place, parameter)
if check != HEURISTIC_TEST.POSITIVE:
if conf.smart or (kb.ignoreCasted and check == HEURISTIC_TEST.CASTED):
2011-07-10 19:16:58 +04:00
infoMsg = "skipping %s parameter '%s'" % (place, parameter)
logger.info(infoMsg)
continue
2010-10-15 04:34:16 +04:00
2012-06-19 12:33:51 +04:00
infoMsg = "testing for SQL injection on %s " % place
2011-04-30 19:29:59 +04:00
infoMsg += "parameter '%s'" % parameter
logger.info(infoMsg)
2010-10-15 04:34:16 +04:00
injection = checkSqlInjection(place, parameter, value)
2010-12-22 02:55:55 +03:00
proceed = not kb.endDetection
if injection is not None and injection.place is not None:
kb.injections.append(injection)
# In case when user wants to end detection phase (Ctrl+C)
if not proceed:
break
msg = "%s parameter '%s' " % (injection.place, injection.parameter)
2012-02-13 15:18:47 +04:00
msg += "is vulnerable. Do you want to keep testing the others (if any)? [y/N] "
test = readInput(msg, default="N")
2012-02-13 15:18:47 +04:00
if test[0] not in ("y", "Y"):
proceed = False
paramKey = (conf.hostname, conf.path, None, None)
kb.testedParams.add(paramKey)
else:
warnMsg = "%s parameter '%s' is not " % (place, parameter)
warnMsg += "injectable"
logger.warn(warnMsg)
if len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None):
2011-05-24 21:15:25 +04:00
if kb.vainRun and not conf.multipleTargets:
2011-11-15 15:17:39 +04:00
errMsg = "no parameter(s) found for testing in the provided data "
2011-05-24 21:15:25 +04:00
errMsg += "(e.g. GET parameter 'id' in 'www.site.com/index.php?id=1')"
raise sqlmapNoneDataException, errMsg
2012-08-20 13:40:49 +04:00
else:
2012-08-22 14:00:17 +04:00
errMsg = "all tested parameters appear to be not injectable."
if conf.level < 5 or conf.risk < 3:
2012-07-23 15:57:38 +04:00
errMsg += " Try to increase '--level'/'--risk' values "
errMsg += "to perform more tests."
if isinstance(conf.tech, list) and len(conf.tech) < 5:
2012-02-01 18:49:42 +04:00
errMsg += " Rerun without providing the option '--technique'."
2011-01-16 02:11:36 +03:00
2011-01-14 19:12:44 +03:00
if not conf.textOnly and kb.originalPage:
2011-01-16 21:11:35 +03:00
percent = (100.0 * len(getFilteredPageContent(kb.originalPage)) / len(kb.originalPage))
2012-08-20 13:28:41 +04:00
if kb.dynamicMarkings:
2012-07-23 15:57:38 +04:00
errMsg += " You can give it a go with the switch '--text-only' "
errMsg += "if the target page has a low percentage "
errMsg += "of textual content (~%.2f%% of " % percent
2012-08-20 13:29:23 +04:00
errMsg += "page content is text)."
2011-05-27 12:21:02 +04:00
elif percent < LOW_TEXT_PERCENT and not kb.errorIsNone:
2012-07-23 15:57:38 +04:00
errMsg += " Please retry with the switch '--text-only' "
errMsg += "(along with --technique=BU) as this case "
errMsg += "looks like a perfect candidate "
errMsg += "(low textual content along with inability "
errMsg += "of comparison engine to detect at least "
2012-08-20 13:29:23 +04:00
errMsg += "one dynamic parameter)."
if kb.heuristicTest == HEURISTIC_TEST.POSITIVE:
errMsg += " As heuristic test turned out positive you are "
errMsg += "strongly advised to continue on with the tests. "
errMsg += "Please, consider usage of tampering scripts as "
errMsg += "your target might filter the queries."
2012-07-26 14:06:02 +04:00
if not conf.string and not conf.notString and not conf.regexp:
errMsg += " Also, you can try to rerun by providing "
2012-07-23 15:57:38 +04:00
errMsg += "either a valid value for option '--string' "
errMsg += "(or '--regexp')"
elif conf.string:
errMsg += " Also, you can try to rerun by providing a "
2012-07-23 15:57:38 +04:00
errMsg += "valid value for option '--string' as perhaps the string you "
errMsg += "have choosen does not match "
errMsg += "exclusively True responses"
elif conf.regexp:
errMsg += " Also, you can try to rerun by providing a "
2012-07-23 15:57:38 +04:00
errMsg += "valid value for option '--regexp' as perhaps the regular "
errMsg += "expression that you have choosen "
errMsg += "does not match exclusively True responses"
2011-01-16 02:11:36 +03:00
2011-01-14 19:12:44 +03:00
raise sqlmapNotVulnerableException, errMsg
else:
# Flush the flag
kb.testMode = False
__saveToResultsFile()
__saveToHashDB()
__showInjections()
__selectInjection()
2008-10-15 19:38:22 +04:00
if kb.injection.place is not None and kb.injection.parameter is not None:
2012-08-20 13:40:49 +04:00
if conf.multipleTargets:
message = "do you want to exploit this SQL injection? [Y/n] "
exploit = readInput(message, default="Y")
2008-10-15 19:38:22 +04:00
condition = not exploit or exploit[0] in ("y", "Y")
else:
condition = True
if condition:
action()
except KeyboardInterrupt:
2010-11-05 19:03:12 +03:00
if conf.multipleTargets:
2011-04-08 14:39:07 +04:00
warnMsg = "user aborted in multiple target mode"
2010-11-05 19:03:12 +03:00
logger.warn(warnMsg)
2010-11-07 19:23:03 +03:00
message = "do you want to skip to the next target in list? [Y/n/q]"
2010-11-05 19:03:12 +03:00
test = readInput(message, default="Y")
2010-11-05 19:03:12 +03:00
if not test or test[0] in ("y", "Y"):
pass
elif test[0] in ("n", "N"):
return False
elif test[0] in ("q", "Q"):
raise sqlmapUserQuitException
else:
raise
2010-09-30 23:45:23 +04:00
except sqlmapUserQuitException:
raise
2010-11-10 22:44:51 +03:00
except sqlmapSilentQuitException:
raise
except exceptionsTuple, e:
2010-06-02 16:45:40 +04:00
e = getUnicode(e)
2008-10-15 19:38:22 +04:00
if conf.multipleTargets:
2010-11-15 15:19:22 +03:00
e += ", skipping to the next %s" % ("form" if conf.forms else "url")
logger.error(e)
else:
2010-09-27 17:41:18 +04:00
logger.critical(e)
2010-09-26 18:56:55 +04:00
return False
2008-10-15 19:38:22 +04:00
finally:
showHttpErrorCodes()
if kb.maxConnectionsFlag:
warnMsg = "it appears that the target "
warnMsg += "has a maximum connections "
warnMsg += "constraint"
logger.warn(warnMsg)
2011-05-11 00:44:36 +04:00
if kb.dataOutputFlag and not conf.multipleTargets:
logger.info("fetched data logged to text files under '%s'" % conf.outputPath)
if conf.multipleTargets and conf.resultsFilename:
2011-06-08 19:31:27 +04:00
infoMsg = "you can find results of scanning in multiple targets "
infoMsg += "mode inside the CSV file '%s'" % conf.resultsFilename
logger.info(infoMsg)
2010-09-26 18:56:55 +04:00
return True