2008-10-15 19:38:22 +04:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
"""
|
2008-10-15 19:56:32 +04:00
|
|
|
$Id$
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-10-14 18:41:14 +04:00
|
|
|
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
2010-10-15 03:18:29 +04:00
|
|
|
See the file 'doc/COPYING' for copying permission
|
2008-10-15 19:38:22 +04:00
|
|
|
"""
|
|
|
|
|
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
|
2010-10-11 16:26:35 +04:00
|
|
|
from lib.controller.checks import heuristicCheckSqlInjection
|
2008-10-15 19:38:22 +04:00
|
|
|
from lib.controller.checks import checkDynParam
|
|
|
|
from lib.controller.checks import checkStability
|
|
|
|
from lib.controller.checks import checkString
|
2008-12-12 22:06:31 +03:00
|
|
|
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
|
2010-11-28 21:10:54 +03:00
|
|
|
from lib.core.agent import agent
|
|
|
|
from lib.core.common import dataToStdout
|
2010-06-02 16:45:40 +04:00
|
|
|
from lib.core.common import getUnicode
|
2008-10-15 19:38:22 +04:00
|
|
|
from lib.core.common import paramToDict
|
2010-03-05 18:25:53 +03:00
|
|
|
from lib.core.common import parseTargetUrl
|
2008-10-15 19:38:22 +04:00
|
|
|
from lib.core.common import readInput
|
|
|
|
from lib.core.data import conf
|
|
|
|
from lib.core.data import kb
|
|
|
|
from lib.core.data import logger
|
2010-11-08 12:44:32 +03:00
|
|
|
from lib.core.enums import HTTPMETHOD
|
2010-11-28 21:10:54 +03:00
|
|
|
from lib.core.enums import PAYLOAD
|
2010-11-08 12:44:32 +03:00
|
|
|
from lib.core.enums import PLACE
|
2010-03-16 15:14:02 +03:00
|
|
|
from lib.core.exception import exceptionsTuple
|
2008-10-15 19:38:22 +04:00
|
|
|
from lib.core.exception import sqlmapNotVulnerableException
|
2010-10-12 19:49:04 +04:00
|
|
|
from lib.core.exception import sqlmapSilentQuitException
|
2010-11-28 21:10:54 +03:00
|
|
|
from lib.core.exception import sqlmapValueException
|
2010-09-30 23:45:23 +04:00
|
|
|
from lib.core.exception import sqlmapUserQuitException
|
2008-10-15 19:38:22 +04:00
|
|
|
from lib.core.session import setInjection
|
2010-03-15 14:55:13 +03:00
|
|
|
from lib.core.target import initTargetEnv
|
|
|
|
from lib.core.target import setupTargetEnv
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
def __selectInjection():
|
2008-10-15 19:38:22 +04:00
|
|
|
"""
|
|
|
|
Selection function for injection place, parameters and type.
|
|
|
|
"""
|
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
points = []
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
for i in xrange(0, len(kb.injections)):
|
|
|
|
place = kb.injections[i].place
|
|
|
|
parameter = kb.injections[i].parameter
|
|
|
|
ptype = kb.injections[i].ptype
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
point = (place, parameter, ptype)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
if point not in points:
|
|
|
|
points.append(point)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
if len(points) == 1:
|
|
|
|
kb.injection = kb.injections[0]
|
2010-11-30 17:48:13 +03:00
|
|
|
|
2010-11-28 21:10:54 +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
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
points = []
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03: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
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
if point not in points:
|
|
|
|
points.append(point)
|
2010-11-29 04:04:42 +03:00
|
|
|
ptype = PAYLOAD.PARAMETER[ptype] if isinstance(ptype, int) else ptype
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
message += "[%d] place: %s, parameter: " % (i, place)
|
2010-11-29 04:04:42 +03:00
|
|
|
message += "%s, type: %s" % (parameter, ptype)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
if i == 0:
|
|
|
|
message += " (default)"
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-28 21:10:54 +03: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
|
2010-11-28 21:10:54 +03:00
|
|
|
|
|
|
|
kb.injection = kb.injections[index]
|
|
|
|
|
|
|
|
def __formatInjection(inj):
|
2010-11-29 00:27:47 +03:00
|
|
|
data = "Place: %s\n" % inj.place
|
|
|
|
data += "Parameter: %s\n" % inj.parameter
|
2010-11-28 21:10:54 +03:00
|
|
|
|
|
|
|
for stype, sdata in inj.data.items():
|
2010-12-03 19:11:35 +03:00
|
|
|
data += " Type: %s\n" % PAYLOAD.SQLINJECTION[stype]
|
2010-12-01 20:09:52 +03:00
|
|
|
data += " Title: %s\n" % sdata.title
|
|
|
|
data += " Payload: %s\n\n" % sdata.payload
|
2010-11-28 21:10:54 +03:00
|
|
|
|
2010-11-29 00:27:47 +03:00
|
|
|
return data
|
2010-11-28 21:10:54 +03:00
|
|
|
|
|
|
|
def __showInjections():
|
2010-12-07 15:33:47 +03:00
|
|
|
header = "sqlmap identified the following injection points "
|
2010-12-07 16:34:06 +03:00
|
|
|
header += "with %d HTTP(s) requests" % kb.testQueryCount
|
2010-11-29 00:27:47 +03:00
|
|
|
data = ""
|
2010-11-28 21:10:54 +03:00
|
|
|
|
|
|
|
for inj in kb.injections:
|
2010-11-29 00:27:47 +03:00
|
|
|
data += __formatInjection(inj)
|
|
|
|
|
2010-11-30 17:48:13 +03:00
|
|
|
data = data.rstrip("\n")
|
|
|
|
|
2011-01-01 15:23:02 +03:00
|
|
|
conf.dumper.technic(header, data)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-11-29 20:18:38 +03:00
|
|
|
def __saveToSessionFile():
|
|
|
|
for inj in kb.injections:
|
2010-12-01 01:40:25 +03:00
|
|
|
if inj.place is None or inj.parameter is None:
|
|
|
|
continue
|
|
|
|
|
2010-11-29 20:18:38 +03:00
|
|
|
setInjection(inj)
|
|
|
|
|
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
|
|
|
|
"""
|
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if not conf.start:
|
2010-09-26 18:56:55 +04:00
|
|
|
return False
|
2010-03-16 15:14:02 +03:00
|
|
|
|
2010-03-27 02:23:25 +03:00
|
|
|
if conf.direct:
|
|
|
|
initTargetEnv()
|
|
|
|
setupTargetEnv()
|
|
|
|
action()
|
2010-09-26 18:56:55 +04:00
|
|
|
return True
|
2010-03-27 02:23:25 +03:00
|
|
|
|
2010-11-15 14:34:57 +03:00
|
|
|
if conf.url and not conf.forms:
|
|
|
|
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:
|
|
|
|
errMsg = "you did not edit the configuration file properly, set "
|
2008-11-20 20:56:09 +03:00
|
|
|
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
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
if kb.targetUrls and len(kb.targetUrls) > 1:
|
|
|
|
infoMsg = "sqlmap got a total of %d targets" % len(kb.targetUrls)
|
|
|
|
logger.info(infoMsg)
|
|
|
|
|
2010-03-27 02:23:25 +03:00
|
|
|
hostCount = 0
|
|
|
|
cookieStr = ""
|
|
|
|
setCookieAsInjectable = True
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
|
2010-03-16 15:14:02 +03:00
|
|
|
try:
|
|
|
|
conf.url = targetUrl
|
|
|
|
conf.method = targetMethod
|
|
|
|
conf.data = targetData
|
|
|
|
conf.cookie = targetCookie
|
|
|
|
injData = []
|
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
|
2010-11-08 12:44:32 +03:00
|
|
|
if PLACE.GET in conf.parameters:
|
|
|
|
for parameter in re.findall(r"([^=]+)=[^&]+&?", conf.parameters[PLACE.GET]):
|
|
|
|
paramKey = (conf.hostname, conf.path, PLACE.GET, parameter)
|
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
|
|
|
|
|
2010-12-23 14:28:13 +03:00
|
|
|
testSqlInj &= (conf.hostname, conf.path, None, None) not in kb.testedParams
|
2010-10-15 04:34:16 +04:00
|
|
|
if not testSqlInj:
|
|
|
|
infoMsg = "skipping '%s'" % targetUrl
|
|
|
|
logger.info(infoMsg)
|
|
|
|
continue
|
2010-03-16 15:14:02 +03:00
|
|
|
|
|
|
|
if conf.multipleTargets:
|
|
|
|
hostCount += 1
|
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 = "%s %d:\n%s %s" % ("url", hostCount, conf.method or HTTPMETHOD.GET, targetUrl)
|
2008-11-28 01:33:33 +03:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if conf.cookie:
|
|
|
|
message += "\nCookie: %s" % conf.cookie
|
2008-11-28 01:33:33 +03:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if conf.data:
|
2010-11-15 14:34:57 +03:00
|
|
|
message += "\nPOST data: %s" % repr(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]: " % (conf.data if conf.data else "")
|
|
|
|
conf.data = readInput(message, default=conf.data)
|
|
|
|
|
|
|
|
elif conf.method == HTTPMETHOD.GET:
|
|
|
|
if conf.url.find("?") > -1:
|
|
|
|
firstPart = conf.url[:conf.url.find("?")]
|
|
|
|
secondPart = conf.url[conf.url.find("?")+1:]
|
|
|
|
message = "Edit GET data [default: %s]: " % secondPart
|
|
|
|
test = readInput(message, default=secondPart)
|
|
|
|
conf.url = "%s?%s" % (firstPart, test)
|
|
|
|
|
|
|
|
elif test[0] in ("n", "N"):
|
|
|
|
continue
|
|
|
|
elif test[0] in ("q", "Q"):
|
|
|
|
break
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-12-23 17:06:22 +03:00
|
|
|
elif conf.realTest:
|
2010-12-20 13:48:53 +03:00
|
|
|
logger.info(message)
|
|
|
|
else:
|
2010-11-15 14:34:57 +03:00
|
|
|
message += "\ndo you want to test this url? [Y/n/q]"
|
|
|
|
test = readInput(message, default="Y")
|
2008-11-28 01:33:33 +03:00
|
|
|
|
2010-11-15 14:34:57 +03:00
|
|
|
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
|
|
|
|
2010-11-15 14:34:57 +03:00
|
|
|
logMsg = "testing url %s" % targetUrl
|
|
|
|
logger.info(logMsg)
|
2010-03-16 18:21:42 +03:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
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
|
|
|
|
|
2010-10-17 01:52:16 +04:00
|
|
|
if conf.nullConnection:
|
2010-09-16 14:01:33 +04:00
|
|
|
checkNullConnection()
|
2010-09-16 12:43:10 +04:00
|
|
|
|
2010-09-26 18:02:13 +04:00
|
|
|
if not conf.dropSetCookie and conf.cj:
|
2010-03-16 15:14:02 +03:00
|
|
|
for _, cookie in enumerate(conf.cj):
|
2010-06-02 16:45:40 +04:00
|
|
|
cookie = getUnicode(cookie)
|
2010-03-16 15:14:02 +03:00
|
|
|
index = cookie.index(" for ")
|
2010-03-16 18:21:42 +03:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
cookieStr += "%s;" % cookie[8:index]
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if cookieStr:
|
|
|
|
cookieStr = cookieStr[:-1]
|
2010-03-16 18:21:42 +03:00
|
|
|
|
2010-11-08 12:44:32 +03:00
|
|
|
if PLACE.COOKIE in conf.parameters:
|
2010-03-16 15:14:02 +03:00
|
|
|
message = "you provided an HTTP Cookie header value. "
|
|
|
|
message += "The target url provided its own Cookie within "
|
|
|
|
message += "the HTTP Set-Cookie header. Do you want to "
|
|
|
|
message += "continue using the HTTP Cookie values that "
|
|
|
|
message += "you provided? [Y/n] "
|
|
|
|
test = readInput(message, default="Y")
|
2010-03-16 18:21:42 +03:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if not test or test[0] in ("y", "Y"):
|
|
|
|
setCookieAsInjectable = False
|
2010-03-16 18:21:42 +03:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if setCookieAsInjectable:
|
2010-11-08 16:26:45 +03:00
|
|
|
conf.httpHeaders.append(("Cookie", cookieStr))
|
2010-11-08 12:44:32 +03:00
|
|
|
conf.parameters[PLACE.COOKIE] = cookieStr
|
|
|
|
__paramDict = paramToDict(PLACE.COOKIE, cookieStr)
|
2010-03-16 18:21:42 +03:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if __paramDict:
|
2010-11-08 12:44:32 +03:00
|
|
|
conf.paramDict[PLACE.COOKIE] = __paramDict
|
2010-03-21 03:39:44 +03:00
|
|
|
# TODO: consider the following line in __setRequestParams()
|
2010-03-16 15:14:02 +03:00
|
|
|
__testableParameters = True
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-12-01 20:09:52 +03: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):
|
2010-03-16 15:14:02 +03:00
|
|
|
if not conf.string and not conf.regexp and not conf.eRegexp:
|
|
|
|
# NOTE: this is not needed anymore, leaving only to display
|
|
|
|
# a warning message to the user in case the page is not stable
|
|
|
|
checkStability()
|
2009-04-22 15:48:07 +04:00
|
|
|
|
2010-11-08 02:37:15 +03:00
|
|
|
# Do a little prioritization reorder of a testable parameter list
|
|
|
|
parameters = conf.parameters.keys()
|
2010-11-08 15:36:48 +03:00
|
|
|
|
2010-11-08 12:44:32 +03:00
|
|
|
for place in (PLACE.URI, PLACE.POST, PLACE.GET):
|
2010-11-08 02:37:15 +03:00
|
|
|
if place in parameters:
|
|
|
|
parameters.remove(place)
|
|
|
|
parameters.insert(0, place)
|
|
|
|
|
2010-12-01 01:40:25 +03:00
|
|
|
proceed = True
|
|
|
|
|
2010-11-08 02:37:15 +03:00
|
|
|
for place in parameters:
|
2010-11-29 19:33:20 +03:00
|
|
|
# Test User-Agent header only if --level >= 4
|
|
|
|
condition = (place == "User-Agent" and conf.level < 4)
|
|
|
|
# Test Cookie header only if --level >= 3
|
|
|
|
condition |= (place == "Cookie" and conf.level < 3)
|
|
|
|
|
|
|
|
if condition:
|
|
|
|
continue
|
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if not conf.paramDict.has_key(place):
|
|
|
|
continue
|
2009-04-22 15:48:07 +04:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
paramDict = conf.paramDict[place]
|
|
|
|
for parameter, value in paramDict.items():
|
2010-12-31 18:00:19 +03:00
|
|
|
if not proceed:
|
|
|
|
break
|
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
testSqlInj = True
|
2010-11-28 21:10:54 +03:00
|
|
|
|
2010-10-15 04:34:16 +04:00
|
|
|
paramKey = (conf.hostname, conf.path, place, parameter)
|
2010-03-16 15:14:02 +03:00
|
|
|
|
2010-07-30 00:01:04 +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)
|
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
# Avoid dinamicity test if the user provided the
|
|
|
|
# parameter manually
|
2010-07-30 00:01:04 +04:00
|
|
|
elif parameter in conf.testParameter:
|
2010-03-16 15:14:02 +03:00
|
|
|
pass
|
2010-10-15 04:34:16 +04:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
elif not checkDynParam(place, parameter, value):
|
|
|
|
warnMsg = "%s parameter '%s' is not dynamic" % (place, parameter)
|
|
|
|
logger.warn(warnMsg)
|
2010-10-15 04:34:16 +04:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
else:
|
|
|
|
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
|
2008-10-15 19:38:22 +04:00
|
|
|
logger.info(logMsg)
|
|
|
|
|
2010-07-30 00:01:04 +04:00
|
|
|
kb.testedParams.add(paramKey)
|
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if testSqlInj:
|
2010-12-20 13:13:14 +03:00
|
|
|
check = heuristicCheckSqlInjection(place, parameter, value)
|
2010-12-23 17:06:22 +03:00
|
|
|
if not check and conf.realTest:
|
2010-12-20 13:13:14 +03:00
|
|
|
continue
|
2010-10-15 04:34:16 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
logMsg = "testing sql injection on %s " % place
|
|
|
|
logMsg += "parameter '%s'" % parameter
|
|
|
|
logger.info(logMsg)
|
2010-10-15 04:34:16 +04:00
|
|
|
|
2010-11-28 21:10:54 +03:00
|
|
|
injection = checkSqlInjection(place, parameter, value)
|
2010-12-22 02:55:55 +03:00
|
|
|
|
|
|
|
proceed = not kb.endDetection
|
|
|
|
|
2010-12-01 01:40:25 +03:00
|
|
|
if injection is not None and injection.place is not None:
|
2010-11-28 21:10:54 +03:00
|
|
|
kb.injections.append(injection)
|
2010-12-01 01:40:25 +03:00
|
|
|
|
2010-12-22 16:15:44 +03:00
|
|
|
# In case when user wants to end detection phase (Ctrl+C)
|
|
|
|
if not proceed:
|
|
|
|
break
|
|
|
|
|
2010-12-01 01:40:25 +03:00
|
|
|
msg = "%s parameter '%s' " % (injection.place, injection.parameter)
|
|
|
|
msg += "is vulnerable. Do you want to keep testing the others? [y/N] "
|
|
|
|
test = readInput(msg, default="N")
|
|
|
|
|
|
|
|
if test[0] in ("n", "N"):
|
|
|
|
proceed = False
|
2010-12-23 14:28:13 +03:00
|
|
|
paramKey = (conf.hostname, conf.path, None, None)
|
|
|
|
kb.testedParams.add(paramKey)
|
2010-11-28 21:10:54 +03:00
|
|
|
else:
|
2010-03-16 15:14:02 +03:00
|
|
|
warnMsg = "%s parameter '%s' is not " % (place, parameter)
|
|
|
|
warnMsg += "injectable"
|
|
|
|
logger.warn(warnMsg)
|
2008-11-22 04:57:22 +03:00
|
|
|
|
2010-12-01 01:40:25 +03:00
|
|
|
if len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None):
|
2010-12-23 17:06:22 +03:00
|
|
|
if not conf.realTest:
|
2010-12-21 03:25:03 +03:00
|
|
|
errMsg = "all parameters are not injectable, try "
|
2010-12-31 15:42:12 +03:00
|
|
|
errMsg += "a higher --level/--risk and/or --text-only switch"
|
2010-12-21 03:25:03 +03:00
|
|
|
raise sqlmapNotVulnerableException, errMsg
|
|
|
|
else:
|
|
|
|
errMsg = "it seems that all parameters are not injectable"
|
|
|
|
raise sqlmapNotVulnerableException, errMsg
|
2010-11-28 21:10:54 +03:00
|
|
|
else:
|
|
|
|
__saveToSessionFile()
|
|
|
|
__showInjections()
|
|
|
|
__selectInjection()
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-12-01 20:09:52 +03:00
|
|
|
if kb.injection.place is not None and kb.injection.parameter is not None:
|
2011-01-02 00:11:29 +03:00
|
|
|
if kb.testQueryCount == 0 and conf.realTest:
|
|
|
|
condition = False
|
|
|
|
elif conf.multipleTargets:
|
2010-03-16 15:14:02 +03:00
|
|
|
message = "do you want to exploit this SQL injection? [Y/n] "
|
|
|
|
exploit = readInput(message, default="Y")
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
condition = not exploit or exploit[0] in ("y", "Y")
|
|
|
|
else:
|
|
|
|
condition = True
|
|
|
|
|
|
|
|
if condition:
|
|
|
|
action()
|
|
|
|
|
2010-11-05 18:59:25 +03:00
|
|
|
except KeyboardInterrupt:
|
2010-11-05 19:03:12 +03:00
|
|
|
if conf.multipleTargets:
|
2010-11-05 19:08:42 +03:00
|
|
|
warnMsg = "Ctrl+C detected in multiple target mode"
|
2010-11-05 19:03:12 +03:00
|
|
|
logger.warn(warnMsg)
|
2010-11-05 18:59:25 +03:00
|
|
|
|
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 18:59:25 +03:00
|
|
|
|
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-11-05 18:59:25 +03:00
|
|
|
|
2010-09-30 23:45:23 +04:00
|
|
|
except sqlmapUserQuitException:
|
|
|
|
raise
|
|
|
|
|
2010-11-10 22:44:51 +03:00
|
|
|
except sqlmapSilentQuitException:
|
|
|
|
raise
|
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
except exceptionsTuple, e:
|
2010-06-02 16:45:40 +04:00
|
|
|
e = getUnicode(e)
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2010-03-16 15:14:02 +03:00
|
|
|
if conf.multipleTargets:
|
2010-11-15 15:19:22 +03:00
|
|
|
e += ", skipping to the next %s" % ("form" if conf.forms else "url")
|
2010-03-16 15:14:02 +03:00
|
|
|
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
|
|
|
|
|
|
|
if conf.loggedToOut:
|
|
|
|
logger.info("Fetched data logged to text files under '%s'" % conf.outputPath)
|
2010-11-03 13:08:27 +03:00
|
|
|
|
2010-09-26 18:56:55 +04:00
|
|
|
return True
|