mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-27 18:09:01 +00:00
Completed support to get the list of targets from WebScarab/Burp proxies
log file and updated the documentation
This commit is contained in:
@@ -92,25 +92,40 @@ def start():
|
||||
"""
|
||||
|
||||
if conf.url:
|
||||
kb.targetUrls[conf.url] = None
|
||||
kb.targetUrls.add(( conf.url, conf.method, conf.data, conf.cookie ))
|
||||
|
||||
if conf.configFile and not kb.targetUrls:
|
||||
errMsg = "you did not edit the configuration file properly, set "
|
||||
errMsg += "the target url, list of targets or google dork"
|
||||
logger.error(errMsg)
|
||||
|
||||
if kb.targetUrls and len(kb.targetUrls) > 1:
|
||||
infoMsg = "sqlmap got a total of %d targets" % len(kb.targetUrls)
|
||||
logger.info(infoMsg)
|
||||
|
||||
hostCount = 0
|
||||
injData = []
|
||||
receivedCookies = []
|
||||
cookieStr = ""
|
||||
setCookieAsInjectable = True
|
||||
|
||||
for targetUrl, targetData in kb.targetUrls.items():
|
||||
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
|
||||
conf.url = targetUrl
|
||||
conf.method = targetMethod
|
||||
conf.data = targetData
|
||||
conf.cookie = targetCookie
|
||||
injData = []
|
||||
|
||||
if conf.multipleTargets:
|
||||
hostCount += 1
|
||||
message = "url %d:\n%s %s" % (hostCount, conf.method, targetUrl)
|
||||
|
||||
message = "url %d: %s, " % (hostCount, targetUrl)
|
||||
message += "do you want to test this url? [Y/n/q] "
|
||||
if conf.cookie:
|
||||
message += "\nCookie: %s" % conf.cookie
|
||||
|
||||
if conf.data:
|
||||
message += "\nPOST data: %s" % conf.data
|
||||
|
||||
message += "\ndo you want to test this url? [Y/n/q] "
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if not test:
|
||||
@@ -123,10 +138,6 @@ def start():
|
||||
logMsg = "testing url %s" % targetUrl
|
||||
logger.info(logMsg)
|
||||
|
||||
if targetData:
|
||||
conf.method, conf.data, conf.cookie = targetData
|
||||
|
||||
conf.url = targetUrl
|
||||
initTargetEnv()
|
||||
|
||||
if not checkConnection() or not checkString():
|
||||
@@ -206,9 +217,14 @@ def start():
|
||||
|
||||
break
|
||||
else:
|
||||
warnMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
warnMsg += "injectable with %d parenthesis" % parenthesis
|
||||
logger.warn(warnMsg)
|
||||
infoMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
infoMsg += "injectable with %d parenthesis" % parenthesis
|
||||
logger.info(infoMsg)
|
||||
|
||||
if not injData:
|
||||
warnMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
warnMsg += "injectable"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
||||
if len(injData) == 1:
|
||||
@@ -230,6 +246,7 @@ def start():
|
||||
kb.injPlace, kb.injParameter, kb.injType = injDataSelected
|
||||
setInjection()
|
||||
|
||||
print kb.injPlace, kb.injParameter, kb.injType
|
||||
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:
|
||||
|
||||
@@ -75,7 +75,7 @@ def paramToDict(place, parameters=None):
|
||||
elem = element.split("=")
|
||||
|
||||
if len(elem) == 2:
|
||||
parameter = elem[0]
|
||||
parameter = elem[0].replace(" ", "")
|
||||
|
||||
condition = not conf.testParameter
|
||||
condition |= parameter in conf.testParameter
|
||||
|
||||
@@ -81,6 +81,111 @@ def __urllib2Opener():
|
||||
urllib2.install_opener(opener)
|
||||
|
||||
|
||||
def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||
fp = open(reqFile, "r")
|
||||
|
||||
fread = fp.read()
|
||||
fread = fread.replace("\r", "")
|
||||
|
||||
reqResList = fread.split("======================================================")
|
||||
|
||||
for request in reqResList:
|
||||
if not re.search ("^[\n]*(GET|POST).*?\sHTTP\/", request, re.I):
|
||||
continue
|
||||
|
||||
getPostReq = False
|
||||
url = None
|
||||
host = None
|
||||
method = None
|
||||
data = None
|
||||
cookie = None
|
||||
params = False
|
||||
lines = request.split("\n")
|
||||
|
||||
for line in lines:
|
||||
if len(line) == 0 or line == "\n":
|
||||
continue
|
||||
|
||||
if line.startswith("GET ") or line.startswith("POST "):
|
||||
if line.startswith("GET "):
|
||||
index = 4
|
||||
else:
|
||||
index = 5
|
||||
|
||||
url = line[index:line.index(" HTTP/")]
|
||||
method = line[:index-1]
|
||||
|
||||
if "?" in line and "=" in line:
|
||||
params = True
|
||||
|
||||
getPostReq = True
|
||||
|
||||
elif "?" in line and "=" in line and ": " not in line:
|
||||
data = line
|
||||
params = True
|
||||
|
||||
elif ": " in line:
|
||||
key, value = line.split(": ", 1)
|
||||
|
||||
if key.lower() == "cookie":
|
||||
cookie = value
|
||||
elif key.lower() == "host":
|
||||
host = value
|
||||
|
||||
if getPostReq and params:
|
||||
if not url.startswith("http"):
|
||||
url = "http://%s%s" % (host, url)
|
||||
|
||||
if not kb.targetUrls or url not in addedTargetUrls:
|
||||
kb.targetUrls.add(( url, method, data, cookie ))
|
||||
addedTargetUrls.add(url)
|
||||
|
||||
|
||||
def __setMultipleTargets():
|
||||
"""
|
||||
Define a configuration parameter if we are running in multiple target
|
||||
mode.
|
||||
"""
|
||||
|
||||
initialTargetsCount = len(kb.targetUrls)
|
||||
addedTargetUrls = set()
|
||||
|
||||
if not conf.list:
|
||||
return
|
||||
|
||||
debugMsg = "parsing targets list from '%s'" % conf.list
|
||||
logger.debug(debugMsg)
|
||||
|
||||
if not os.path.exists(conf.list):
|
||||
errMsg = "the specified list of targets does not exist"
|
||||
raise sqlmapFilePathException, errMsg
|
||||
|
||||
if os.path.isfile(conf.list):
|
||||
__feedTargetsDict(conf.list, addedTargetUrls)
|
||||
|
||||
elif os.path.isdir(conf.list):
|
||||
files = os.listdir(conf.list)
|
||||
files.sort()
|
||||
|
||||
for reqFile in files:
|
||||
if not re.search("([\d]+)\-request", reqFile):
|
||||
continue
|
||||
|
||||
__feedTargetsDict(os.path.join(conf.list, reqFile), addedTargetUrls)
|
||||
|
||||
else:
|
||||
errMsg = "the specified list of targets is not a file "
|
||||
errMsg += "nor a directory"
|
||||
raise sqlmapFilePathException, errMsg
|
||||
|
||||
updatedTargetsCount = len(kb.targetUrls)
|
||||
|
||||
if updatedTargetsCount > initialTargetsCount:
|
||||
infoMsg = "sqlmap parsed %d " % (updatedTargetsCount - initialTargetsCount)
|
||||
infoMsg += "testable requests from the targets list"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
||||
def __setGoogleDorking():
|
||||
"""
|
||||
This function checks if the way to request testable hosts is through
|
||||
@@ -109,7 +214,7 @@ def __setGoogleDorking():
|
||||
errMsg += "Google dork expression"
|
||||
raise sqlmapGenericException, errMsg
|
||||
|
||||
kb.targetUrls = googleObj.getTargetUrls()
|
||||
googleObj.getTargetUrls()
|
||||
|
||||
if kb.targetUrls:
|
||||
logMsg = "sqlmap got %d results for your " % len(matches)
|
||||
@@ -120,7 +225,7 @@ def __setGoogleDorking():
|
||||
else:
|
||||
logMsg += "%d " % len(kb.targetUrls)
|
||||
|
||||
logMsg += "of them are testable hosts"
|
||||
logMsg += "of them are testable targets"
|
||||
logger.info(logMsg)
|
||||
else:
|
||||
errMsg = "sqlmap got %d results " % len(matches)
|
||||
@@ -129,103 +234,6 @@ def __setGoogleDorking():
|
||||
raise sqlmapGenericException, errMsg
|
||||
|
||||
|
||||
def __feedTargetsDict(reqFile):
|
||||
fp = open(reqFile, "r")
|
||||
|
||||
fread = fp.read()
|
||||
fread = fread.replace("\r", "")
|
||||
|
||||
# TODO: fix for Burp log file
|
||||
reqResList = fread.split("\n\n======================================================\n\n\n\n")
|
||||
|
||||
for request in reqResList:
|
||||
url = None
|
||||
host = None
|
||||
method = None
|
||||
data = None
|
||||
cookie = None
|
||||
params = False
|
||||
lines = request.split("\n")
|
||||
|
||||
for line in lines:
|
||||
if len(line) == 0 or line == "\n":
|
||||
continue
|
||||
|
||||
if line.startswith("GET ") or line.startswith("POST "):
|
||||
if line.startswith("GET "):
|
||||
index = 4
|
||||
else:
|
||||
index = 5
|
||||
|
||||
url = line[index:line.index(" HTTP/")]
|
||||
method = line[:index-1]
|
||||
|
||||
if "?" in line and "=" in line:
|
||||
params = True
|
||||
|
||||
elif "?" in line and "=" in line:
|
||||
data = line
|
||||
params = True
|
||||
|
||||
elif ": " in line:
|
||||
key, value = line.split(": ", 1)
|
||||
|
||||
if key.lower() == "cookie":
|
||||
cookie = value
|
||||
elif key.lower() == "host":
|
||||
host = value
|
||||
|
||||
if params:
|
||||
if not url.startswith("http"):
|
||||
url = "http://%s%s" % (host, url)
|
||||
|
||||
# TODO: exclude duplicated urls
|
||||
kb.targetUrls[url] = ( method, data, cookie )
|
||||
|
||||
|
||||
def __setMultipleTargets():
|
||||
"""
|
||||
Define a configuration parameter if we are running in multiple target
|
||||
mode.
|
||||
"""
|
||||
|
||||
initialTargetsCount = len(kb.targetUrls)
|
||||
|
||||
if conf.googleDork or conf.list:
|
||||
conf.multipleTargets = True
|
||||
|
||||
if not conf.list:
|
||||
return
|
||||
|
||||
if not os.path.exists(conf.list):
|
||||
errMsg = "the specified list of target urls does not exist"
|
||||
raise sqlmapFilePathException, errMsg
|
||||
|
||||
if os.path.isfile(conf.list):
|
||||
__feedTargetsDict(conf.list)
|
||||
|
||||
elif os.path.isdir(conf.list):
|
||||
files = os.listdir(conf.list)
|
||||
files.sort()
|
||||
|
||||
for reqFile in files:
|
||||
if not re.search("([\d]+)\-request", reqFile):
|
||||
continue
|
||||
|
||||
__feedTargetsDict(os.path.join(conf.list, reqFile))
|
||||
|
||||
else:
|
||||
errMsg = "the specified list of target urls is not a file "
|
||||
errMsg += "nor a directory"
|
||||
raise sqlmapFilePathException, errMsg
|
||||
|
||||
updatedTargetsCount = len(kb.targetUrls)
|
||||
|
||||
if updatedTargetsCount > initialTargetsCount:
|
||||
infoMsg = "sqlmap parsed %d requests from the targets list" % (updatedTargetsCount - initialTargetsCount)
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
||||
def __setRemoteDBMS():
|
||||
"""
|
||||
Checks and set the back-end DBMS option.
|
||||
@@ -359,9 +367,6 @@ def __setHTTPMethod():
|
||||
"""
|
||||
|
||||
if conf.method:
|
||||
debugMsg = "setting the HTTP method to perform HTTP requests through"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
conf.method = conf.method.upper()
|
||||
|
||||
if conf.method not in ("GET", "POST"):
|
||||
@@ -374,6 +379,9 @@ def __setHTTPMethod():
|
||||
else:
|
||||
conf.method = "GET"
|
||||
|
||||
debugMsg = "setting the HTTP method to %s" % conf.method
|
||||
logger.debug(debugMsg)
|
||||
|
||||
|
||||
def __setHTTPStandardHeaders():
|
||||
conf.httpHeaders.append(("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"))
|
||||
@@ -509,6 +517,9 @@ def __cleanupOptions():
|
||||
if conf.delay:
|
||||
conf.delay = float(conf.delay)
|
||||
|
||||
if conf.googleDork or conf.list:
|
||||
conf.multipleTargets = True
|
||||
|
||||
|
||||
def __setConfAttributes():
|
||||
"""
|
||||
@@ -560,7 +571,7 @@ def __setKnowledgeBaseAttributes():
|
||||
kb.injType = None
|
||||
kb.parenthesis = None
|
||||
kb.resumedQueries = {}
|
||||
kb.targetUrls = {}
|
||||
kb.targetUrls = set()
|
||||
kb.timeTest = None
|
||||
kb.unionComment = ""
|
||||
kb.unionCount = None
|
||||
@@ -680,8 +691,8 @@ def init(inputOptions=advancedDict()):
|
||||
__setHTTPProxy()
|
||||
__setThreads()
|
||||
__setRemoteDBMS()
|
||||
__setMultipleTargets()
|
||||
__setGoogleDorking()
|
||||
__setMultipleTargets()
|
||||
__urllib2Opener()
|
||||
|
||||
update()
|
||||
|
||||
@@ -197,6 +197,20 @@ def initTargetEnv():
|
||||
Initialize target environment.
|
||||
"""
|
||||
|
||||
if conf.multipleTargets:
|
||||
conf.paramDict = {}
|
||||
conf.parameters = {}
|
||||
kb.dbms = None
|
||||
kb.dbmsDetected = False
|
||||
kb.dbmsVersion = None
|
||||
kb.injParameter = None
|
||||
kb.injPlace = None
|
||||
kb.injType = None
|
||||
kb.parenthesis = None
|
||||
kb.unionComment = ""
|
||||
kb.unionCount = None
|
||||
kb.unionPosition = None
|
||||
|
||||
parseTargetUrl()
|
||||
__setRequestParams()
|
||||
__setOutputResume()
|
||||
|
||||
@@ -37,7 +37,7 @@ def cmdLineParser():
|
||||
This function parses the command line parameters and arguments
|
||||
"""
|
||||
|
||||
usage = "sqlmap.py [options] {-u <URL> | -g <google dork> | -c <config file>}"
|
||||
usage = "sqlmap.py [options] {-u \"<URL>\" | -g \"<google dork>\" | -c \"<config file>\"}"
|
||||
parser = OptionParser(usage=usage, version=VERSION_STRING)
|
||||
|
||||
try:
|
||||
@@ -49,7 +49,7 @@ def cmdLineParser():
|
||||
|
||||
request.add_option("-u", "--url", dest="url", help="Target url")
|
||||
|
||||
request.add_option("-l", dest="list", help="List of target urls")
|
||||
request.add_option("-l", dest="list", help="List of targets")
|
||||
|
||||
request.add_option("-g", dest="googleDork",
|
||||
help="Process Google dork results as target urls")
|
||||
@@ -118,11 +118,11 @@ def cmdLineParser():
|
||||
|
||||
techniques.add_option("--union-test", dest="unionTest",
|
||||
action="store_true",
|
||||
help="Test for UNION SELECT (inband) SQL injection")
|
||||
help="Test for UNION query (inband) SQL injection")
|
||||
|
||||
techniques.add_option("--union-use", dest="unionUse",
|
||||
action="store_true",
|
||||
help="Use the UNION SELECT (inband) SQL injection "
|
||||
help="Use the UNION query (inband) SQL injection "
|
||||
"to retrieve the queries output. No "
|
||||
"need to go blind")
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import urllib2
|
||||
|
||||
from lib.core.convert import urlencode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.exception import sqlmapConnectionException
|
||||
from lib.core.exception import sqlmapRegExprException
|
||||
|
||||
@@ -68,17 +69,9 @@ class Google:
|
||||
your Google dork search results
|
||||
"""
|
||||
|
||||
targetUrls = {}
|
||||
targetUrlsSet = set()
|
||||
|
||||
for match in self.__matches:
|
||||
if re.search("(.*?)\?(.+)", match, re.I):
|
||||
targetUrlsSet.add(match)
|
||||
|
||||
for targetUrl in targetUrlsSet:
|
||||
targetUrls[targetUrl] = None
|
||||
|
||||
return targetUrls
|
||||
kb.targetUrls.add(( match, None, None, None ))
|
||||
|
||||
|
||||
def getCookie(self):
|
||||
|
||||
@@ -126,7 +126,7 @@ def resume(expression, payload):
|
||||
|
||||
# If we called this function without providing a payload it means that
|
||||
# we have called it from lib/request/inject __goInband() function
|
||||
# in UNION SELECT (inband) SQL injection so we return to the calling
|
||||
# in UNION query (inband) SQL injection so we return to the calling
|
||||
# function so that the query output will be retrieved taking advantage
|
||||
# of the inband SQL injection vulnerability.
|
||||
if not payload:
|
||||
|
||||
Reference in New Issue
Block a user