mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 01:26:42 +03:00
Fixes #177 - Don't exit at exception if in "multiple targets" mode (-l or -g)
This commit is contained in:
parent
6d0ea86414
commit
323cf2b7f2
|
@ -302,11 +302,11 @@ def checkStability():
|
||||||
logMsg = "url is stable"
|
logMsg = "url is stable"
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
else:
|
else:
|
||||||
exceptionMsg = "there was an error checking the stability of page "
|
errMsg = "there was an error checking the stability of page "
|
||||||
exceptionMsg += "because of lack of content. please check the "
|
errMsg += "because of lack of content. please check the "
|
||||||
exceptionMsg += "page request results (and probable errors) by "
|
errMsg += "page request results (and probable errors) by "
|
||||||
exceptionMsg += "using higher verbosity levels"
|
errMsg += "using higher verbosity levels"
|
||||||
raise sqlmapNoneDataException, exceptionMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
elif not condition:
|
elif not condition:
|
||||||
warnMsg = "url is not stable, sqlmap will base the page "
|
warnMsg = "url is not stable, sqlmap will base the page "
|
||||||
|
@ -387,15 +387,8 @@ def checkConnection():
|
||||||
page, _ = Request.getPage()
|
page, _ = Request.getPage()
|
||||||
conf.seqMatcher.set_seq1(page)
|
conf.seqMatcher.set_seq1(page)
|
||||||
|
|
||||||
except sqlmapConnectionException, exceptionMsg:
|
except sqlmapConnectionException, errMsg:
|
||||||
exceptionMsg = str(exceptionMsg)
|
errMsg = str(errMsg)
|
||||||
|
raise sqlmapConnectionException, errMsg
|
||||||
if conf.multipleTargets:
|
|
||||||
exceptionMsg += ", skipping to next url"
|
|
||||||
logger.warn(exceptionMsg)
|
|
||||||
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
raise sqlmapConnectionException, exceptionMsg
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -35,6 +35,7 @@ from lib.core.common import readInput
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
from lib.core.exception import exceptionsTuple
|
||||||
from lib.core.exception import sqlmapNotVulnerableException
|
from lib.core.exception import sqlmapNotVulnerableException
|
||||||
from lib.core.session import setInjection
|
from lib.core.session import setInjection
|
||||||
from lib.core.target import initTargetEnv
|
from lib.core.target import initTargetEnv
|
||||||
|
@ -88,6 +89,9 @@ def start():
|
||||||
check if they are dynamic and SQL injection affected
|
check if they are dynamic and SQL injection affected
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not conf.start:
|
||||||
|
return
|
||||||
|
|
||||||
if conf.url:
|
if conf.url:
|
||||||
kb.targetUrls.add(( conf.url, conf.method, conf.data, conf.cookie ))
|
kb.targetUrls.add(( conf.url, conf.method, conf.data, conf.cookie ))
|
||||||
|
|
||||||
|
@ -105,158 +109,165 @@ def start():
|
||||||
setCookieAsInjectable = True
|
setCookieAsInjectable = True
|
||||||
|
|
||||||
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
|
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
|
||||||
conf.url = targetUrl
|
try:
|
||||||
conf.method = targetMethod
|
conf.url = targetUrl
|
||||||
conf.data = targetData
|
conf.method = targetMethod
|
||||||
conf.cookie = targetCookie
|
conf.data = targetData
|
||||||
injData = []
|
conf.cookie = targetCookie
|
||||||
|
injData = []
|
||||||
|
|
||||||
if conf.multipleTargets:
|
if conf.multipleTargets:
|
||||||
hostCount += 1
|
hostCount += 1
|
||||||
message = "url %d:\n%s %s" % (hostCount, conf.method or "GET", targetUrl)
|
message = "url %d:\n%s %s" % (hostCount, conf.method or "GET", targetUrl)
|
||||||
|
|
||||||
if conf.cookie:
|
if conf.cookie:
|
||||||
message += "\nCookie: %s" % conf.cookie
|
message += "\nCookie: %s" % conf.cookie
|
||||||
|
|
||||||
if conf.data:
|
if conf.data:
|
||||||
message += "\nPOST data: %s" % conf.data
|
message += "\nPOST data: %s" % conf.data
|
||||||
|
|
||||||
message += "\ndo you want to test this url? [Y/n/q]"
|
message += "\ndo you want to test this url? [Y/n/q]"
|
||||||
test = readInput(message, default="Y")
|
test = readInput(message, default="Y")
|
||||||
|
|
||||||
if not test:
|
if not test:
|
||||||
pass
|
pass
|
||||||
elif test[0] in ("n", "N"):
|
elif test[0] in ("n", "N"):
|
||||||
continue
|
|
||||||
elif test[0] in ("q", "Q"):
|
|
||||||
break
|
|
||||||
|
|
||||||
logMsg = "testing url %s" % targetUrl
|
|
||||||
logger.info(logMsg)
|
|
||||||
|
|
||||||
initTargetEnv()
|
|
||||||
parseTargetUrl()
|
|
||||||
setupTargetEnv()
|
|
||||||
|
|
||||||
if not checkConnection() or not checkString() or not checkRegexp():
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not conf.dropSetCookie:
|
|
||||||
for _, cookie in enumerate(conf.cj):
|
|
||||||
cookie = str(cookie)
|
|
||||||
index = cookie.index(" for ")
|
|
||||||
|
|
||||||
cookieStr += "%s;" % cookie[8:index]
|
|
||||||
|
|
||||||
if cookieStr:
|
|
||||||
cookieStr = cookieStr[:-1]
|
|
||||||
|
|
||||||
if "Cookie" in conf.parameters:
|
|
||||||
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")
|
|
||||||
|
|
||||||
if not test or test[0] in ("y", "Y"):
|
|
||||||
setCookieAsInjectable = False
|
|
||||||
|
|
||||||
if setCookieAsInjectable:
|
|
||||||
conf.httpHeaders.append(("Cookie", cookieStr))
|
|
||||||
conf.parameters["Cookie"] = cookieStr
|
|
||||||
__paramDict = paramToDict("Cookie", cookieStr)
|
|
||||||
|
|
||||||
if __paramDict:
|
|
||||||
conf.paramDict["Cookie"] = __paramDict
|
|
||||||
__testableParameters = True
|
|
||||||
|
|
||||||
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
|
||||||
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()
|
|
||||||
|
|
||||||
for place in conf.parameters.keys():
|
|
||||||
if not conf.paramDict.has_key(place):
|
|
||||||
continue
|
continue
|
||||||
|
elif test[0] in ("q", "Q"):
|
||||||
|
break
|
||||||
|
|
||||||
paramDict = conf.paramDict[place]
|
logMsg = "testing url %s" % targetUrl
|
||||||
|
logger.info(logMsg)
|
||||||
|
|
||||||
|
initTargetEnv()
|
||||||
|
parseTargetUrl()
|
||||||
|
setupTargetEnv()
|
||||||
|
|
||||||
for parameter, value in paramDict.items():
|
if not checkConnection() or not checkString() or not checkRegexp():
|
||||||
testSqlInj = True
|
continue
|
||||||
|
|
||||||
# Avoid dinamicity test if the user provided the
|
if not conf.dropSetCookie:
|
||||||
# parameter manually
|
for _, cookie in enumerate(conf.cj):
|
||||||
if parameter in conf.testParameter:
|
cookie = str(cookie)
|
||||||
pass
|
index = cookie.index(" for ")
|
||||||
|
|
||||||
|
cookieStr += "%s;" % cookie[8:index]
|
||||||
|
|
||||||
elif not checkDynParam(place, parameter, value):
|
if cookieStr:
|
||||||
warnMsg = "%s parameter '%s' is not dynamic" % (place, parameter)
|
cookieStr = cookieStr[:-1]
|
||||||
logger.warn(warnMsg)
|
|
||||||
testSqlInj = False
|
if "Cookie" in conf.parameters:
|
||||||
|
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")
|
||||||
|
|
||||||
|
if not test or test[0] in ("y", "Y"):
|
||||||
|
setCookieAsInjectable = False
|
||||||
|
|
||||||
|
if setCookieAsInjectable:
|
||||||
|
conf.httpHeaders.append(("Cookie", cookieStr))
|
||||||
|
conf.parameters["Cookie"] = cookieStr
|
||||||
|
__paramDict = paramToDict("Cookie", cookieStr)
|
||||||
|
|
||||||
|
if __paramDict:
|
||||||
|
conf.paramDict["Cookie"] = __paramDict
|
||||||
|
__testableParameters = True
|
||||||
|
|
||||||
else:
|
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
||||||
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
|
if not conf.string and not conf.regexp and not conf.eRegexp:
|
||||||
logger.info(logMsg)
|
# NOTE: this is not needed anymore, leaving only to display
|
||||||
|
# a warning message to the user in case the page is not stable
|
||||||
|
checkStability()
|
||||||
|
|
||||||
if testSqlInj:
|
for place in conf.parameters.keys():
|
||||||
for parenthesis in range(0, 4):
|
if not conf.paramDict.has_key(place):
|
||||||
logMsg = "testing sql injection on %s " % place
|
continue
|
||||||
logMsg += "parameter '%s' with " % parameter
|
|
||||||
logMsg += "%d parenthesis" % parenthesis
|
paramDict = conf.paramDict[place]
|
||||||
|
|
||||||
|
for parameter, value in paramDict.items():
|
||||||
|
testSqlInj = True
|
||||||
|
|
||||||
|
# Avoid dinamicity test if the user provided the
|
||||||
|
# parameter manually
|
||||||
|
if parameter in conf.testParameter:
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif not checkDynParam(place, parameter, value):
|
||||||
|
warnMsg = "%s parameter '%s' is not dynamic" % (place, parameter)
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
testSqlInj = False
|
||||||
|
|
||||||
|
else:
|
||||||
|
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
injType = checkSqlInjection(place, parameter, value, parenthesis)
|
if testSqlInj:
|
||||||
|
for parenthesis in range(0, 4):
|
||||||
|
logMsg = "testing sql injection on %s " % place
|
||||||
|
logMsg += "parameter '%s' with " % parameter
|
||||||
|
logMsg += "%d parenthesis" % parenthesis
|
||||||
|
logger.info(logMsg)
|
||||||
|
|
||||||
if injType:
|
injType = checkSqlInjection(place, parameter, value, parenthesis)
|
||||||
injData.append((place, parameter, injType))
|
|
||||||
|
|
||||||
break
|
if injType:
|
||||||
else:
|
injData.append((place, parameter, injType))
|
||||||
infoMsg = "%s parameter '%s' is not " % (place, parameter)
|
|
||||||
infoMsg += "injectable with %d parenthesis" % parenthesis
|
|
||||||
logger.info(infoMsg)
|
|
||||||
|
|
||||||
if not injData:
|
break
|
||||||
warnMsg = "%s parameter '%s' is not " % (place, parameter)
|
else:
|
||||||
warnMsg += "injectable"
|
infoMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||||
logger.warn(warnMsg)
|
infoMsg += "injectable with %d parenthesis" % parenthesis
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
if not injData:
|
||||||
if len(injData) == 1:
|
warnMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||||
injDataSelected = injData[0]
|
warnMsg += "injectable"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
elif len(injData) > 1:
|
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
||||||
injDataSelected = __selectInjection(injData)
|
if len(injData) == 1:
|
||||||
|
injDataSelected = injData[0]
|
||||||
|
|
||||||
elif conf.multipleTargets:
|
elif len(injData) > 1:
|
||||||
continue
|
injDataSelected = __selectInjection(injData)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return
|
raise sqlmapNotVulnerableException, "all parameters are not injectable"
|
||||||
|
return
|
||||||
|
|
||||||
if injDataSelected == "Quit":
|
if injDataSelected == "Quit":
|
||||||
return
|
return
|
||||||
|
|
||||||
else:
|
else:
|
||||||
kb.injPlace, kb.injParameter, kb.injType = injDataSelected
|
kb.injPlace, kb.injParameter, kb.injType = injDataSelected
|
||||||
setInjection()
|
setInjection()
|
||||||
|
|
||||||
|
elif kb.injPlace and kb.injParameter and kb.injType:
|
||||||
|
if conf.multipleTargets:
|
||||||
|
message = "do you want to exploit this SQL injection? [Y/n] "
|
||||||
|
exploit = readInput(message, default="Y")
|
||||||
|
|
||||||
|
condition = not exploit or exploit[0] in ("y", "Y")
|
||||||
|
else:
|
||||||
|
condition = True
|
||||||
|
|
||||||
|
if condition:
|
||||||
|
checkForParenthesis()
|
||||||
|
action()
|
||||||
|
|
||||||
|
except exceptionsTuple, e:
|
||||||
|
e = str(e)
|
||||||
|
|
||||||
if not conf.multipleTargets and ( not kb.injPlace or not kb.injParameter or not kb.injType ):
|
|
||||||
raise sqlmapNotVulnerableException, "all parameters are not injectable"
|
|
||||||
elif kb.injPlace and kb.injParameter and kb.injType:
|
|
||||||
if conf.multipleTargets:
|
if conf.multipleTargets:
|
||||||
message = "do you want to exploit this SQL injection? [Y/n] "
|
e += ", skipping to next url"
|
||||||
exploit = readInput(message, default="Y")
|
logger.error(e)
|
||||||
|
|
||||||
condition = not exploit or exploit[0] in ("y", "Y")
|
|
||||||
else:
|
else:
|
||||||
condition = True
|
logger.error(e)
|
||||||
|
return
|
||||||
if condition:
|
|
||||||
checkForParenthesis()
|
|
||||||
action()
|
|
||||||
|
|
||||||
if conf.loggedToOut:
|
if conf.loggedToOut:
|
||||||
logger.info("Fetched data logged to text files under '%s'" % conf.outputPath)
|
logger.info("Fetched data logged to text files under '%s'" % conf.outputPath)
|
||||||
|
|
|
@ -178,12 +178,12 @@ class Connect:
|
||||||
|
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
if e.code == 401:
|
if e.code == 401:
|
||||||
exceptionMsg = "not authorized, try to provide right HTTP "
|
errMsg = "not authorized, try to provide right HTTP "
|
||||||
exceptionMsg += "authentication type and valid credentials"
|
errMsg += "authentication type and valid credentials"
|
||||||
raise sqlmapConnectionException, exceptionMsg
|
raise sqlmapConnectionException, errMsg
|
||||||
elif e.code == 404 and raise404:
|
elif e.code == 404 and raise404:
|
||||||
exceptionMsg = "page not found"
|
errMsg = "page not found"
|
||||||
raise sqlmapConnectionException, exceptionMsg
|
raise sqlmapConnectionException, errMsg
|
||||||
else:
|
else:
|
||||||
page = e.read()
|
page = e.read()
|
||||||
code = e.code
|
code = e.code
|
||||||
|
@ -210,12 +210,6 @@ class Connect:
|
||||||
if "BadStatusLine" not in tbMsg:
|
if "BadStatusLine" not in tbMsg:
|
||||||
warnMsg += " or proxy"
|
warnMsg += " or proxy"
|
||||||
|
|
||||||
if conf.multipleTargets:
|
|
||||||
warnMsg += ", skipping to next url"
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
|
|
||||||
return None, None
|
|
||||||
|
|
||||||
if silent:
|
if silent:
|
||||||
return None, None
|
return None, None
|
||||||
elif conf.retriesCount < conf.retries:
|
elif conf.retriesCount < conf.retries:
|
||||||
|
|
|
@ -72,11 +72,10 @@ def main():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
init(cmdLineOptions)
|
init(cmdLineOptions)
|
||||||
|
start()
|
||||||
if conf.start:
|
|
||||||
start()
|
|
||||||
|
|
||||||
except exceptionsTuple, e:
|
except exceptionsTuple, e:
|
||||||
|
e = str(e)
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -90,6 +89,7 @@ def main():
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
|
print
|
||||||
errMsg = unhandledException()
|
errMsg = unhandledException()
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user