get operations with query parameters

This commit is contained in:
David Donn 2021-09-14 17:17:21 +10:00
parent 8f84b740da
commit 9a34282aa3
6 changed files with 96 additions and 5 deletions

View File

@ -36,6 +36,7 @@ import threading
import time import time
import types import types
import unicodedata import unicodedata
import json
from difflib import SequenceMatcher from difflib import SequenceMatcher
from math import sqrt from math import sqrt
@ -5362,6 +5363,53 @@ def parseRequestFile(reqFile, checkParams=True):
if not(conf.scope and not re.search(conf.scope, url, re.I)): if not(conf.scope and not re.search(conf.scope, url, re.I)):
yield (url, conf.method or method, data, cookie, tuple(headers)) yield (url, conf.method or method, data, cookie, tuple(headers))
def _parseSwagger(content):
"""
Parses Swagger OpenAPI 3.x.x JSON documents
"""
try:
swagger = json.loads(content)
logger.debug("swagger OpenAPI version '%s'" % swagger["openapi"])
for path in swagger["paths"]:
for operation in swagger["paths"][path]:
op = swagger["paths"][path][operation]
tags = conf.swaggerTags.split(",") if conf.swaggerTags is not None else None
if ((tags is None or any(tag in op["tags"] for tag in tags))
and operation == "get"):
url = None
method = None
data = None
cookie = None
url = "%s%s" % (swagger["servers"][0]["url"], path)
method = operation.upper()
q = list(filter(lambda p: (p["in"] == "query"), op["parameters"]))
qs = ""
for qp in q:
qs += "&%s=%s" %(qp["name"], qp["example"])
qs = qs.replace('&', '?', 1)
if op["parameters"] is not None and len(q) > 0:
url += qs
logger.debug("swagger url '%s', method '%s', data '%s', cookie '%s'" %(url, method, data, cookie))
yield (url, method, data, cookie, None)
else:
logger.info("excluding url '%s', method '%s' as target since there are no parameters to inject" %(url, method))
except json.decoder.JSONDecodeError:
errMsg = "swagger file is not valid JSON"
raise SqlmapSyntaxException(errMsg)
content = readCachedFileContent(reqFile) content = readCachedFileContent(reqFile)
if conf.scope: if conf.scope:
@ -5373,6 +5421,9 @@ def parseRequestFile(reqFile, checkParams=True):
for target in _parseWebScarabLog(content): for target in _parseWebScarabLog(content):
yield target yield target
for target in _parseSwagger(content):
yield target
def getSafeExString(ex, encoding=None): def getSafeExString(ex, encoding=None):
""" """
Safe way how to get the proper exception represtation as a string Safe way how to get the proper exception represtation as a string

View File

@ -477,6 +477,31 @@ def _setBulkMultipleTargets():
warnMsg = "no usable links found (with GET parameters)" warnMsg = "no usable links found (with GET parameters)"
logger.warn(warnMsg) logger.warn(warnMsg)
def _setSwaggerMultipleTargets():
if not conf.swaggerFile:
return
infoMsg = "parsing multiple targets from swagger '%s'" % conf.swaggerFile
logger.info(infoMsg)
if not os.path.exists(conf.swaggerFile):
errMsg = "the specified list of targets does not exist"
raise SqlmapFilePathException(errMsg)
if checkFile(conf.swaggerFile, False):
debugMsg = "swagger file '%s' checks out" % conf.swaggerFile
logger.debug(debugMsg)
for target in parseRequestFile(conf.swaggerFile):
kb.targets.add(target)
else:
errMsg = "the specified list of targets is not a file "
errMsg += "nor a directory"
raise SqlmapFilePathException(errMsg)
def _findPageForms(): def _findPageForms():
if not conf.forms or conf.crawlDepth: if not conf.forms or conf.crawlDepth:
return return
@ -2677,7 +2702,7 @@ def _basicOptionValidation():
errMsg = "maximum number of used threads is %d avoiding potential connection issues" % MAX_NUMBER_OF_THREADS errMsg = "maximum number of used threads is %d avoiding potential connection issues" % MAX_NUMBER_OF_THREADS
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.forms and not any((conf.url, conf.googleDork, conf.bulkFile)): if conf.forms and not any((conf.url, conf.googleDork, conf.bulkFile, conf.swaggerFile)):
errMsg = "switch '--forms' requires usage of option '-u' ('--url'), '-g' or '-m'" errMsg = "switch '--forms' requires usage of option '-u' ('--url'), '-g' or '-m'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@ -2787,7 +2812,7 @@ def _basicOptionValidation():
errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)" errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.hashFile and any((conf.direct, conf.url, conf.logFile, conf.bulkFile, conf.googleDork, conf.configFile, conf.requestFile, conf.updateAll, conf.smokeTest, conf.wizard, conf.dependencies, conf.purge, conf.listTampers)): if conf.hashFile and any((conf.direct, conf.url, conf.logFile, conf.bulkFile, conf.swaggerFile, conf.googleDork, conf.configFile, conf.requestFile, conf.updateAll, conf.smokeTest, conf.wizard, conf.dependencies, conf.purge, conf.listTampers)):
errMsg = "option '--crack' should be used as a standalone" errMsg = "option '--crack' should be used as a standalone"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@ -2855,7 +2880,7 @@ def init():
parseTargetDirect() parseTargetDirect()
if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork, conf.stdinPipe)): if any((conf.url, conf.logFile, conf.bulkFile, conf.swaggerFile, conf.requestFile, conf.googleDork, conf.stdinPipe)):
_setHostname() _setHostname()
_setHTTPTimeout() _setHTTPTimeout()
_setHTTPExtraHeaders() _setHTTPExtraHeaders()
@ -2871,6 +2896,7 @@ def init():
_doSearch() _doSearch()
_setStdinPipeTargets() _setStdinPipeTargets()
_setBulkMultipleTargets() _setBulkMultipleTargets()
_setSwaggerMultipleTargets()
_checkTor() _checkTor()
_setCrawler() _setCrawler()
_findPageForms() _findPageForms()

View File

@ -18,6 +18,8 @@ optDict = {
"requestFile": "string", "requestFile": "string",
"sessionFile": "string", "sessionFile": "string",
"googleDork": "string", "googleDork": "string",
"swaggerFile": "string",
"swaggerTags": "string",
"configFile": "string", "configFile": "string",
}, },

View File

@ -141,6 +141,12 @@ def cmdLineParser(argv=None):
target.add_argument("-g", dest="googleDork", target.add_argument("-g", dest="googleDork",
help="Process Google dork results as target URLs") help="Process Google dork results as target URLs")
target.add_argument("--swaggerFile", dest="swaggerFile",
help="Parse target(s) from a Swagger OpenAPI 3.x.x JSON file ")
target.add_argument("--swaggerTags", dest="swaggerTags",
help="Only process swagger operations that include one of these tags")
target.add_argument("-c", dest="configFile", target.add_argument("-c", dest="configFile",
help="Load options from a configuration INI file") help="Load options from a configuration INI file")

View File

@ -79,14 +79,14 @@ def configFileParser(configFile):
mandatory = False mandatory = False
for option in ("direct", "url", "logFile", "bulkFile", "googleDork", "requestFile", "wizard"): for option in ("direct", "url", "logFile", "bulkFile", "googleDork", "requestFile", "wizard", "swaggerFile"):
if config.has_option("Target", option) and config.get("Target", option) or cmdLineOptions.get(option): if config.has_option("Target", option) and config.get("Target", option) or cmdLineOptions.get(option):
mandatory = True mandatory = True
break break
if not mandatory: if not mandatory:
errMsg = "missing a mandatory option in the configuration file " errMsg = "missing a mandatory option in the configuration file "
errMsg += "(direct, url, logFile, bulkFile, googleDork, requestFile or wizard)" errMsg += "(direct, url, logFile, bulkFile, googleDork, requestFile, wizard or swaggerFile)"
raise SqlmapMissingMandatoryOptionException(errMsg) raise SqlmapMissingMandatoryOptionException(errMsg)
for family, optionData in optDict.items(): for family, optionData in optDict.items():

View File

@ -32,6 +32,12 @@ requestFile =
# Example: +ext:php +inurl:"&id=" +intext:"powered by " # Example: +ext:php +inurl:"&id=" +intext:"powered by "
googleDork = googleDork =
# Parse target(s) for a Swagger OpenAPI 3.x.x JSON file
swaggerFile =
# Only process swagger operations that have one of these tags (e.g. tagA,tagB)
swaggerTags =
# These options can be used to specify how to connect to the target URL. # These options can be used to specify how to connect to the target URL.
[Request] [Request]