From 8bdb7ec58ca0eaafb7bac5e2639a34ca366aad72 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Wed, 12 Jan 2011 00:47:39 +0000 Subject: [PATCH] Ahead with UNION exploitation after UNION test moved to detection phase - a lot to do yet. --- lib/controller/checks.py | 9 +++--- lib/core/agent.py | 15 +++++----- lib/core/session.py | 43 ----------------------------- lib/techniques/inband/union/test.py | 2 +- lib/techniques/inband/union/use.py | 6 ++-- plugins/generic/enumeration.py | 6 +--- 6 files changed, 16 insertions(+), 65 deletions(-) diff --git a/lib/controller/checks.py b/lib/controller/checks.py index 8a4b26895..ba112bcff 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -280,6 +280,7 @@ def checkSqlInjection(place, parameter, value): # For each test's for where in test.where: templatePayload = None + vector = None # Threat the parameter original value according to the # test's tag @@ -380,7 +381,7 @@ def checkSqlInjection(place, parameter, value): configUnion(test.request.char, test.request.columns) dbmsToUnescape = dbms if dbms is not None else injection.dbms - reqPayload, unionVector = unionTest(comment, place, parameter, value, prefix, suffix, dbmsToUnescape) + reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix, dbmsToUnescape) if isinstance(reqPayload, basestring): infoMsg = "%s parameter '%s' is '%s' injectable" % (place, parameter, title) @@ -405,17 +406,15 @@ def checkSqlInjection(place, parameter, value): injection.suffix = suffix injection.clause = clause - if "vector" in test and test.vector is not None: + if vector is None and "vector" in test and test.vector is not None: vector = "%s%s" % (test.vector, comment) - else: - vector = None # Feed with test details every time a test is successful injection.data[stype] = advancedDict() injection.data[stype].title = title injection.data[stype].payload = agent.removePayloadDelimiters(reqPayload, False) injection.data[stype].where = where - injection.data[stype].vector = agent.cleanupPayload(vector, unionVector=unionVector) + injection.data[stype].vector = vector injection.data[stype].comment = comment injection.data[stype].matchRatio = kb.matchRatio injection.data[stype].templatePayload = templatePayload diff --git a/lib/core/agent.py b/lib/core/agent.py index 7ab35af5b..89855b8d9 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -108,7 +108,6 @@ class Agent: retValue = paramString.replace("%s=%s" % (parameter, origValue), "%s=%s" % (parameter, self.addPayloadDelimiters(newValue))) -# print "retValue:", retValue return retValue def fullPayload(self, query): @@ -180,7 +179,7 @@ class Agent: return string.rstrip() - def cleanupPayload(self, payload, origvalue=None, unionVector=None): + def cleanupPayload(self, payload, origvalue=None, unionVector=None, query=None): if payload is None: return @@ -199,6 +198,9 @@ class Agent: payload = payload.replace("[SLEEPTIME]", str(conf.timeSec)) payload = payload.replace("[UNION]", str(unionVector)) + if query is not None: + payload = payload.replace("[QUERY]", query.lstrip()) + if origvalue is not None: payload = payload.replace("[ORIGVALUE]", origvalue) @@ -220,11 +222,10 @@ class Agent: inferenceQuery = queries[kb.misc.testedDbms].inference.query payload = payload.replace("[INFERENCE]", inferenceQuery) - # NOTE: Leave this commented for the time being - #else: - # errMsg = "invalid usage of inference payload without " - # errMsg += "knowledge of underlying DBMS" - # raise sqlmapNoneDataException, errMsg + else: + errMsg = "invalid usage of inference payload without " + errMsg += "knowledge of underlying DBMS" + raise sqlmapNoneDataException, errMsg return payload diff --git a/lib/core/session.py b/lib/core/session.py index 33f114abc..673575fdd 100644 --- a/lib/core/session.py +++ b/lib/core/session.py @@ -215,9 +215,6 @@ def setUnion(comment=None, count=None, position=None, negative=False, char=None, if negative: kb.unionNegative = True - if payload: - kb.unionTest = payload - def setRemoteTempPath(): condition = ( not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and @@ -390,46 +387,6 @@ def resumeConfKb(expression, url, value): kb.brute.columns.append((db, table, colName, colType)) - elif expression == "Union comment" and url == conf.url: - kb.unionComment = unSafeFormatString(value[:-1]) - - logMsg = "resuming union comment " - logMsg += "'%s' from session file" % kb.unionComment - logger.info(logMsg) - - elif expression == "Union count" and url == conf.url: - kb.unionCount = int(value[:-1]) - - logMsg = "resuming union count " - logMsg += "%s from session file" % kb.unionCount - logger.info(logMsg) - - elif expression == "Union position" and url == conf.url: - kb.unionPosition = int(value[:-1]) - - logMsg = "resuming union position " - logMsg += "%s from session file" % kb.unionPosition - logger.info(logMsg) - - elif expression == "Union negative" and url == conf.url: - kb.unionNegative = True if value[:-1] == "Yes" else False - - logMsg = "resuming union negative from session file" - logger.info(logMsg) - - elif expression == "Union char" and url == conf.url: - conf.uChar = value[:-1] - - logMsg = "resuming union char %s from session file" % conf.uChar - logger.info(logMsg) - - elif expression == "Union payload" and url == conf.url: - kb.unionTest = value[:-1] - - logMsg = "resuming union payload " - logMsg += "%s from session file" % kb.unionTest - logger.info(logMsg) - elif expression == "Remote temp path" and url == conf.url: conf.tmpPath = unSafeFormatString(value[:-1]) diff --git a/lib/techniques/inband/union/test.py b/lib/techniques/inband/union/test.py index 05d44ff3d..80386026a 100644 --- a/lib/techniques/inband/union/test.py +++ b/lib/techniques/inband/union/test.py @@ -52,7 +52,7 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, coun if resultPage and randQuery in resultPage and " UNION ALL SELECT " not in resultPage: setUnion(position=exprPosition) validPayload = payload - unionVector = agent.forgeInbandQuery("[PAYLOAD]", exprPosition, count=count, comment=comment, prefix=prefix, suffix=suffix) + unionVector = agent.forgeInbandQuery("[QUERY]", exprPosition, count=count, comment=comment, prefix=prefix, suffix=suffix) if where == 1: # Prepare expression with delimiters diff --git a/lib/techniques/inband/union/use.py b/lib/techniques/inband/union/use.py index 3bebc1f85..f7c0cb4a9 100644 --- a/lib/techniques/inband/union/use.py +++ b/lib/techniques/inband/union/use.py @@ -211,12 +211,10 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh else: # Forge the inband SQL injection request - query = agent.forgeInbandQuery(expression, nullChar=nullChar) + query = unescaper.unescape(expression) + query = agent.cleanupPayload(kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector, query=query) payload = agent.payload(newValue=query) - debugMsg = "query: %s" % query - logger.debug(debugMsg) - # Perform the request resultPage, _ = Request.queryPage(payload, content=True) reqCount += 1 diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index ff4ec0a1e..69d9f91e2 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -52,7 +52,6 @@ from lib.request import inject from lib.request.connect import Connect as Request from lib.techniques.brute.use import columnExists from lib.techniques.brute.use import tableExists -from lib.techniques.inband.union.test import unionTest from lib.utils.hash import attackDumpedTable from lib.utils.hash import attackCachedUsersPasswords @@ -87,10 +86,7 @@ class Enumeration: infoMsg = "fetching banner" logger.info(infoMsg) - if conf.unionTest: - conf.dumper.technic("inband injection payload", unionTest()) - - query = queries[kb.dbms].banner.query + query = queries[kb.dbms].banner.query kb.data.banner = inject.getValue(query) bannerParser(kb.data.banner)