From 36c544f440eb0fd5e5f6e7426e283250b167ba02 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Mon, 15 Nov 2010 11:34:57 +0000 Subject: [PATCH] update (--forms acts now more like -g switch) --- lib/controller/controller.py | 58 +++++++++++++++++++++++++----------- lib/core/option.py | 30 +++++++++++++++++-- lib/core/target.py | 40 ------------------------- 3 files changed, 68 insertions(+), 60 deletions(-) diff --git a/lib/controller/controller.py b/lib/controller/controller.py index 1164c82ea..73a24ef67 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -35,7 +35,6 @@ from lib.core.session import setInjection from lib.core.session import setMatchRatio from lib.core.target import initTargetEnv from lib.core.target import setupTargetEnv -from lib.core.target import findPageForms from lib.utils.parenthesis import checkForParenthesis def __selectInjection(injData): @@ -94,11 +93,8 @@ def start(): action() return True - if conf.url: - if conf.forms: - findPageForms() - else: - kb.targetUrls.add(( conf.url, conf.method, conf.data, conf.cookie )) + if conf.url and not conf.forms: + 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 " @@ -144,26 +140,52 @@ def start(): if conf.multipleTargets: hostCount += 1 - message = "url %d:\n%s %s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl) + message = "%s %d:\n%s %s" % ("form" if conf.forms else "url", hostCount, conf.method or HTTPMETHOD.GET, targetUrl) if conf.cookie: message += "\nCookie: %s" % conf.cookie if conf.data: - message += "\nPOST data: %s" % conf.data + message += "\nPOST data: %s" % repr(conf.data) if conf.data else "" - message += "\ndo you want to test this url? [Y/n/q]" - test = readInput(message, default="Y") + if conf.forms: + if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1: + continue - if not test: - pass - elif test[0] in ("n", "N"): - continue - elif test[0] in ("q", "Q"): - break + message += "\ndo you want to test this form? [Y/n/q] " + test = readInput(message, default="Y") - logMsg = "testing url %s" % targetUrl - logger.info(logMsg) + 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 + + else: + message += "\ndo you want to test this url? [Y/n/q]" + test = readInput(message, default="Y") + + if not test or test[0] in ("y", "Y"): + pass + elif test[0] in ("n", "N"): + continue + elif test[0] in ("q", "Q"): + break + + logMsg = "testing url %s" % targetUrl + logger.info(logMsg) setupTargetEnv() diff --git a/lib/core/option.py b/lib/core/option.py index 226c04e7e..3afd6ac39 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -20,6 +20,7 @@ import threading import urllib2 import urlparse +from extra.clientform.clientform import ParseResponse from extra.keepalive import keepalive from extra.xmlobject import xmlobject from lib.core.common import getConsoleWidth @@ -62,6 +63,7 @@ from lib.core.settings import SUPPORTED_OS from lib.core.settings import VERSION_STRING from lib.core.update import update from lib.parse.configfile import configFileParser +from lib.request.connect import Connect as Request from lib.request.proxy import ProxyHTTPSHandler from lib.request.certhandler import HTTPSCertAuthHandler from lib.request.rangehandler import HTTPRangeHandler @@ -346,6 +348,21 @@ def __setGoogleDorking(): errMsg += "have GET parameters to test for SQL injection" raise sqlmapGenericException, errMsg +def __findPageForms(): + infoMsg = "searching for forms" + logger.info(infoMsg) + + response, _ = Request.queryPage(response=True) + forms = ParseResponse(response, backwards_compat=False) + + for form in forms: + request = form.click() + url = request.get_full_url() + method = request.get_method() + data = request.get_data() if request.has_data() else None + + kb.targetUrls.add((url, method, data, conf.cookie)) + def __setMetasploit(): if not conf.osPwn and not conf.osSmb and not conf.osBof: return @@ -995,7 +1012,7 @@ def __cleanupOptions(): if conf.tmpPath: conf.tmpPath = ntToPosixSlashes(normalizePath(conf.tmpPath)) - if conf.googleDork or conf.list: + if conf.googleDork or conf.list or conf.forms: conf.multipleTargets = True if conf.optimize: @@ -1271,6 +1288,14 @@ def __basicOptionValidation(): errMsg = "switch --predict-output is incompatible with switch --threads" raise sqlmapSyntaxException, errMsg + if conf.forms and not conf.url: + errMsg = "switch --forms requires usage of -u (--url) switch" + raise sqlmapSyntaxException, errMsg + + if conf.forms and (conf.list or conf.direct or conf.requestFile or conf.googleDork): + errMsg = "switch --forms is compatible only with -u (--url) target switch" + raise sqlmapSyntaxException, errMsg + def init(inputOptions=advancedDict()): """ Set attributes into both configuration and knowledge base singletons @@ -1292,7 +1317,7 @@ def init(inputOptions=advancedDict()): parseTargetUrl() parseTargetDirect() - if conf.url or conf.list or conf.requestFile or conf.googleDork or conf.liveTest: + if conf.url or conf.list or conf.requestFile or conf.googleDork or conf.liveTest or conf.forms: __setHTTPTimeout() __setHTTPExtraHeaders() __setHTTPCookies() @@ -1304,6 +1329,7 @@ def init(inputOptions=advancedDict()): __setSafeUrl() __setUnionTech() __setGoogleDorking() + __findPageForms() __urllib2Opener() __setDBMS() diff --git a/lib/core/target.py b/lib/core/target.py index f3de02425..5bde0cea3 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -12,7 +12,6 @@ import os import re import time -from extra.clientform.clientform import ParseResponse from lib.core.common import dataToSessionFile from lib.core.common import paramToDict from lib.core.common import readInput @@ -123,45 +122,6 @@ def __setRequestParams(): errMsg += "within the GET, POST and Cookie parameters" raise sqlmapGenericException, errMsg -def findPageForms(): - infoMsg = "searching for forms" - logger.info(infoMsg) - - response, _ = Request.queryPage(response=True) - forms = ParseResponse(response, backwards_compat=False) - - count = 1 - for form in forms: - request = form.click() - url = request.get_full_url() - method = request.get_method() - data = request.get_data() if request.has_data() else None - - if form.name is None: - name = "" - else: - name = " '%s'" % form.name - - message = "[#%d] Do you want to test form%s (%s, %s%s) [Y/n] " % (count, name, method, url, ", %s" % repr(data) if data else "") - test = readInput(message, default="Y") - - if not test or test[0] in ("y", "Y"): - if method == HTTPMETHOD.POST: - message = "Edit POST data [default: %s]: " % (data if data else "") - test = readInput(message, default=data) - - elif method == HTTPMETHOD.GET: - if url.find("?") > -1: - firstPart = url[:url.find("?")] - secondPart = url[url.find("?")+1:] - message = "Edit GET data [default: %s]: " % secondPart - test = readInput(message, default=secondPart) - url = "%s?%s" % (firstPart, test) - - kb.targetUrls.add((url, method, data, conf.cookie)) - - count +=1 - def __setOutputResume(): """ Check and set the output text file and the resume functionality.