From a58b36fe0792b4382c04b73b95774ce9d3f150f6 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Tue, 12 Jan 2010 13:11:26 +0000 Subject: [PATCH] code commit regarding Feature #119 --- lib/core/option.py | 117 +++++++++++++++++++++++++++++++++++++++++ lib/core/optiondict.py | 6 ++- lib/parse/cmdline.py | 9 ++-- sqlmap.conf | 4 +- 4 files changed, 130 insertions(+), 6 deletions(-) diff --git a/lib/core/option.py b/lib/core/option.py index 19a442de4..a904419a1 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -267,6 +267,121 @@ def __setGoogleDorking(): errMsg += "have GET parameters to test for SQL injection" raise sqlmapGenericException, errMsg +def __setRequestFromFile(): + """ + This function checks if the way to make a HTTP request is through supplied + textual file, parses it and saves the information into the knowledge base. + """ + + if not conf.requestFile: + return + + conf.requestFile = os.path.expanduser(conf.requestFile) + + debugMsg = "parsing HTTP request from '%s'" % conf.requestFile + logger.debug(debugMsg) + + if not os.path.isfile(conf.requestFile): + errMsg = "the specified HTTP request file " + errMsg += "'%s' does not exist" % conf.requestFile + raise sqlmapFilePathException, errMsg + + fp = open(conf.requestFile, "r") + fread = fp.read() + fread = fread.replace("\r", "") + fp.close() + + lines = fread.split("\n") + + if len(lines) == 0: + errMsg = "the specified HTTP request file " + errMsg += "'%s' has no content" % conf.requestFile + raise sqlmapFilePathException, errMsg + + if not (lines[0].startswith("GET ") or lines[0].startswith("POST ")): + errMsg = "the specified HTTP request file " + errMsg += "doesn't start with GET or POST keyword" + raise sqlmapFilePathException, errMsg + + + if lines[0].upper().startswith("GET "): + index = 4 + else: + index = 5 + + if lines[0].find(" HTTP/") == -1: + errMsg = "the specified HTTP request file " + errMsg += "has a syntax error at line: 1" + raise sqlmapFilePathException, errMsg + + host = None + headers = "" + page = lines[0][index:lines[0].index(" HTTP/")] + + if conf.method: + warnMsg = "HTTP method previously set. overriding it with " + warnMsg += "the value supplied from the HTTP request file" + logger.warn(warnMsg) + conf.method = lines[0][:index-1] + + for index in xrange(1, len(lines) - 1): + line = lines[index] + valid = True + + if len(line) == 0: + break + + headers += line + "\n" + + items = line.split(': ') + if len(items) != 2: + valid = False + else: + if items[0].upper() == "HOST": + host = items[1] + + if not valid: + errMsg = "the specified HTTP request file" + errMsg += "has a syntax error at line: %d" % (index + 1) + raise sqlmapFilePathException, errMsg + + if conf.headers and headers: + warnMsg = "HTTP headers previously set. overriding it with " + warnMsg += "the value(s) supplied from the HTTP request file" + logger.warn(warnMsg) + conf.headers = headers.strip("\n") + + if fread.find("\n\n") != -1: + if conf.data: + warnMsg = "HTTP POST data previously set. overriding it with " + warnMsg += "the value supplied from the HTTP request file" + logger.warn(warnMsg) + conf.data = fread[fread.index('\n\n')+2:].strip("\n") + + if conf.url: + warnMsg = "target url previously set. overriding it with " + warnMsg += "the value supplied from the HTTP request file" + logger.warn(warnMsg) + + if host: + conf.url = "%s%s" % (host, page) + elif conf.url: #insert page into here + index = conf.url.find("://") + if index != -1: + index += len("://") + else: + index = 0 + + index = conf.url.find("/", index) + if index != -1: + conf.url = "%s%s" % (conf.url[:conf.url.find("/", index)], page) + else: + conf.url = "%s%s" % (conf.url, page) + pass #mirek + else: + errMsg = "target url is not known" + raise sqlmapFilePathException, errMsg + def __setMetasploit(): if not conf.osPwn and not conf.osSmb and not conf.osBof: return @@ -1004,6 +1119,8 @@ def init(inputOptions=advancedDict()): __setKnowledgeBaseAttributes() __cleanupOptions() + __setRequestFromFile() + parseTargetUrl() __setHTTPTimeout() diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index ea07a6a25..39d9d3e6e 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -27,7 +27,8 @@ optDict = { "Target": { "url": "string", "list": "string", - "googleDork": "string" + "googleDork": "string", + "configFile": "string" }, "Request": { @@ -47,7 +48,8 @@ optDict = { "delay": "float", "timeout": "float", "retries": "integer", - "scope": "string" + "scope": "string", + "requestFile": "string" }, "Injection": { diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index 7328d6293..71463c6c0 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -58,7 +58,7 @@ def cmdLineParser(): target.add_option("-c", dest="configFile", help="Load options from a configuration INI file") - + # Request options request = OptionGroup(parser, "Request", "These options can be used " "to specify how to connect to the target url.") @@ -121,6 +121,9 @@ def cmdLineParser(): request.add_option("--scope", dest="scope", help="Regexp to filter targets from provided proxy log") + request.add_option("-r", dest="requestFile", + help="Load HTTP request from a file") + # Injection options injection = OptionGroup(parser, "Injection", "These options can be " "used to specify which parameters to test " @@ -421,8 +424,8 @@ def cmdLineParser(): (args, _) = parser.parse_args() - if not args.url and not args.list and not args.googleDork and not args.configFile and not args.updateAll: - errMsg = "missing a mandatory parameter ('-u', '-l', '-g', '-c' or '--update'), " + if not args.url and not args.list and not args.googleDork and not args.configFile and not args.requestFile and not args.updateAll: + errMsg = "missing a mandatory parameter ('-u', '-l', '-g', '-c', '-r' or '--update'), " errMsg += "-h for help" parser.error(errMsg) diff --git a/sqlmap.conf b/sqlmap.conf index 6091fd1a0..615ea0d2e 100644 --- a/sqlmap.conf +++ b/sqlmap.conf @@ -17,7 +17,6 @@ list = # Example: +ext:php +inurl:"&id=" +intext:"powered by " googleDork = - [Request] # HTTP method to perform HTTP requests. @@ -100,6 +99,9 @@ retries = 3 # Example: (google|yahoo) scope = +# Load HTTP request from a file +# Example (file content): POST /login.jsp HTTP/1.1\nUser-Agent: Mozilla/4.0\n\nuserid=joe&password=guessme +requestFile = [Injection]