From 472f4465a698fb19057170ae33f38f8f7bf25d4b Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Sun, 28 Nov 2010 21:27:47 +0000 Subject: [PATCH] Prioritize DBMS fingerprint based on DBMS () identified during the detection phase. Minor bug fix to properly handle the case that no injections are found. Nicer display of injection vulnerabilities detected. Minor code refactoring. --- lib/controller/checks.py | 5 ++++- lib/controller/controller.py | 23 ++++++++++------------- lib/controller/handler.py | 12 ++++++++++-- lib/core/dump.py | 2 +- lib/core/option.py | 2 +- lib/request/inject.py | 9 +++++++-- 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/lib/controller/checks.py b/lib/controller/checks.py index e85c6d54e..c77f85220 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -306,7 +306,10 @@ def checkSqlInjection(place, parameter, value): break - return injection + if injection.place is not None and injection.parameter is not None: + return injection + else: + return None def heuristicCheckSqlInjection(place, parameter, value): if kb.nullConnection: diff --git a/lib/controller/controller.py b/lib/controller/controller.py index eb2ef04d9..5e709c72d 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -126,22 +126,23 @@ def __selectInjection(): kb.injection = kb.injections[index] def __formatInjection(inj): - header = "Place: %s\n" % inj.place - header += "Parameter: %s\n" % inj.parameter - data = "" + data = "Place: %s\n" % inj.place + data += "Parameter: %s\n" % inj.parameter for stype, sdata in inj.data.items(): - data += "Type: %s\n" % PAYLOAD.SQLINJECTION[stype] - data += "Payload: %s\n\n" % sdata[3] + data += " Type: %s\n" % PAYLOAD.SQLINJECTION[stype] + data += " Payload: %s\n\n" % sdata[3] - return header, data + return data def __showInjections(): - dataToStdout("sqlmap identified the following injection points:\n") + header = "sqlmap identified the following injection points" + data = "" for inj in kb.injections: - header, data = __formatInjection(inj) - dumper.technic(header, data) + data += __formatInjection(inj) + + dumper.technic(header, data) def start(): """ @@ -318,9 +319,6 @@ def start(): for parameter, value in paramDict.items(): testSqlInj = True - # TODO: with the new detection engine, review this - # part. Perhaps dynamicity test will not be of any - # use paramKey = (conf.hostname, conf.path, place, parameter) if paramKey in kb.testedParams: @@ -337,7 +335,6 @@ def start(): elif not checkDynParam(place, parameter, value): warnMsg = "%s parameter '%s' is not dynamic" % (place, parameter) logger.warn(warnMsg) - testSqlInj = False else: logMsg = "%s parameter '%s' is dynamic" % (place, parameter) diff --git a/lib/controller/handler.py b/lib/controller/handler.py index daca6edaa..f79dc8109 100644 --- a/lib/controller/handler.py +++ b/lib/controller/handler.py @@ -63,15 +63,23 @@ def setHandler(): ] if kb.htmlFp: + inferencedDbms = kb.htmlFp[-1] + elif hasattr(kb.injection, "dbms"): + inferencedDbms = kb.injection.dbms + else: + inferencedDbms = None + + if inferencedDbms is not None: for i in xrange(len(dbmsMap)): dbmsAliases, _, _ = dbmsMap[i] - if kb.htmlFp[-1].lower() in dbmsAliases: + + if inferencedDbms.lower() in dbmsAliases: if i > 0: pushValue(dbmsMap[i]) dbmsMap.remove(dbmsMap[i]) dbmsMap.insert(0, popValue()) - break + break for dbmsAliases, dbmsMap, dbmsConn in dbmsMap: if conf.dbms and conf.dbms not in dbmsAliases: diff --git a/lib/core/dump.py b/lib/core/dump.py index b4c802123..e939cbd0f 100644 --- a/lib/core/dump.py +++ b/lib/core/dump.py @@ -89,7 +89,7 @@ class Dump: if elements: self.__write("") - def technic(self,header,data): + def technic(self, header, data): self.string(header, data) def banner(self,data): diff --git a/lib/core/option.py b/lib/core/option.py index 49f3e8071..c772be2b5 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -1129,6 +1129,7 @@ def __setKnowledgeBaseAttributes(): kb.errorTest = None kb.stackedTest = None kb.timeTest = None + kb.unionTest = None # Basic back-end DBMS fingerprint kb.dbms = None @@ -1180,7 +1181,6 @@ def __setKnowledgeBaseAttributes(): kb.unionPosition = None kb.unionNegative = False kb.unionFalseCond = False - kb.unionTest = None kb.userAgents = None kb.valueStack = [] diff --git a/lib/request/inject.py b/lib/request/inject.py index d30e866dd..c4a3f483a 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -28,6 +28,7 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries from lib.core.enums import DBMS +from lib.core.exception import sqlmapNotVulnerableException from lib.core.unescaper import unescaper from lib.request.connect import Connect as Request from lib.request.direct import direct @@ -346,7 +347,7 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex if conf.direct: value = direct(expression) - else: + elif kb.booleanTest or kb.errorTest or kb.unionTest: expression = cleanQuery(expression) expression = expandAsteriskForColumns(expression) value = None @@ -376,7 +377,7 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex kb.unionFalseCond = False kb.unionNegative = False - if blind and not value: + if blind and kb.booleanTest and not value: value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar) kb.unionFalseCond = oldParamFalseCond @@ -384,6 +385,10 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex if value and isinstance(value, basestring): value = value.strip() + else: + errMsg = "none of the injection types identified can be " + errMsg += "leveraged to retrieve queries output" + raise sqlmapNotVulnerableException, errMsg if suppressOutput: conf.verbose = popValue()