diff --git a/lib/controller/action.py b/lib/controller/action.py index 2bf8c57c2..f3a527a70 100644 --- a/lib/controller/action.py +++ b/lib/controller/action.py @@ -16,6 +16,7 @@ from lib.core.data import paths from lib.core.exception import sqlmapUnsupportedDBMSException from lib.core.settings import SUPPORTED_DBMS from lib.techniques.blind.timebased import timeTest +from lib.techniques.error.error import errorTest from lib.techniques.inband.union.test import unionTest from lib.techniques.outband.stacked import stackedTest @@ -57,6 +58,9 @@ def action(): if conf.stackedTest: conf.dumper.technic("stacked queries support", stackedTest()) + if conf.errorTest: + conf.dumper.technic("error based injection support", errorTest()) + if conf.timeTest: conf.dumper.technic("time based blind sql injection payload", timeTest()) diff --git a/lib/core/option.py b/lib/core/option.py index e20cce350..1eac060cf 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -1050,6 +1050,7 @@ def __setKnowledgeBaseAttributes(): kb.dep = None kb.docRoot = None kb.dynamicContent = [] + kb.errorTest = None kb.headersCount = 0 kb.headersFp = {} kb.hintValue = None diff --git a/lib/core/session.py b/lib/core/session.py index ca5a40ea1..79a3a9c29 100644 --- a/lib/core/session.py +++ b/lib/core/session.py @@ -196,6 +196,15 @@ def setStacked(): if condition: dataToSessionFile("[%s][%s][%s][Stacked queries][%s]\n" % (conf.url, kb.injPlace, safeFormatString(conf.parameters[kb.injPlace]), kb.stackedTest)) +def setError(): + condition = ( + not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and + not kb.resumedQueries[conf.url].has_key("Error based injection") ) + ) + + if condition: + dataToSessionFile("[%s][%s][%s][Error based injection][Yes]\n" % (conf.url, kb.injPlace, safeFormatString(conf.parameters[kb.injPlace]))) + def setUnion(comment=None, count=None, position=None, negative=False, falseCond=False): """ @param comment: union comment to save in session file diff --git a/lib/core/target.py b/lib/core/target.py index b8c9e02da..5daa30f52 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -282,25 +282,28 @@ def initTargetEnv(): if conf.cj: conf.cj.clear() - conf.paramDict = {} - conf.parameters = {} - conf.sessionFile = None + conf.paramDict = {} + conf.parameters = {} + conf.sessionFile = None - kb.authHeader = None - kb.dbms = None - kb.dbmsDetected = False - kb.dbmsVersion = [ "Unknown" ] - kb.htmlFp = [] - kb.lastErrorPage = None - kb.injParameter = None - kb.injPlace = None - kb.injType = None - kb.nullConnection = None - kb.parenthesis = None + kb.authHeader = None + kb.dbms = None + kb.dbmsDetected = False + kb.dbmsVersion = [ "Unknown" ] + kb.errorTest = None + kb.htmlFp = [] + kb.lastErrorPage = None + kb.injParameter = None + kb.injPlace = None + kb.injType = None + kb.nullConnection = None + kb.parenthesis = None kb.proxyAuthHeader = None - kb.unionComment = "" - kb.unionCount = None - kb.unionPosition = None + kb.stackedTest = None + kb.timeTest = None + kb.unionComment = "" + kb.unionCount = None + kb.unionPosition = None def setupTargetEnv(): __createTargetDirs() diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index 654db722b..87ae267ad 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -491,6 +491,10 @@ def cmdLineParser(): parser.add_option("--error", dest="error", action="store_true", default=False, help=SUPPRESS_HELP) + parser.add_option("--error-test", dest="errorTest", + action="store_true", default=False, + help=SUPPRESS_HELP) + parser.add_option("--cpu-throttle", dest="cpuThrottle", type="int", default=10, help=SUPPRESS_HELP) diff --git a/lib/request/inject.py b/lib/request/inject.py index d734c3c61..ac7ea712e 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -445,3 +445,13 @@ def goStacked(expression, silent=False): page, _ = Request.queryPage(payload, content=True, silent=silent) return payload, page + +def goError(expression): + #expression = cleanQuery(expression) + + if conf.direct: + return direct(expression), None + + result = __goError(expression) + + return result diff --git a/lib/techniques/blind/timebased.py b/lib/techniques/blind/timebased.py index 3626f9d2f..b1013226f 100644 --- a/lib/techniques/blind/timebased.py +++ b/lib/techniques/blind/timebased.py @@ -20,7 +20,7 @@ from lib.request.connect import Connect as Request def timeTest(): infoMsg = "testing time based blind sql injection on parameter " - infoMsg += "'%s' with AND condition syntax" % kb.injParameter + infoMsg += "'%s' with %s condition syntax" % (kb.injParameter, conf.logic) logger.info(infoMsg) timeQuery = getDelayQuery(andCond=True) diff --git a/lib/techniques/error/error.py b/lib/techniques/error/error.py new file mode 100644 index 000000000..f4933e64d --- /dev/null +++ b/lib/techniques/error/error.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +""" +$Id$ + +Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) +See the file 'doc/COPYING' for copying permission +""" + +import time + +from lib.core.common import getUnicode +from lib.core.common import randomInt +from lib.core.data import conf +from lib.core.data import kb +from lib.core.data import logger +from lib.core.data import queries +from lib.core.session import setError +from lib.request import inject + +def errorTest(): + if conf.direct: + return + + if kb.errorTest is not None: + return kb.errorTest + + infoMsg = "testing error based sql injection on parameter " + infoMsg += "'%s' with %s condition syntax" % (kb.injParameter, conf.logic) + logger.info(infoMsg) + + randInt = getUnicode(randomInt(1)) + query = queries[kb.dbms].case % ("%s=%s" % (randInt, randInt)) + result = inject.goError(query) + + if result: + infoMsg = "the web application supports error based injection " + infoMsg += "on parameter '%s'" % kb.injParameter + logger.info(infoMsg) + + kb.errorTest = True + else: + warnMsg = "the web application does not support error based injection " + warnMsg += "on parameter '%s'" % kb.injParameter + logger.warn(warnMsg) + + kb.errorTest = False + + setError() + + return kb.errorTest