diff --git a/lib/core/agent.py b/lib/core/agent.py index 509fdd2f8..aac2e3f9f 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -75,8 +75,21 @@ class Agent: elif kb.injection.place and kb.injection.parameter: paramString = conf.parameters[kb.injection.place] paramDict = conf.paramDict[kb.injection.place] - value = paramDict[kb.injection.parameter] - newValue = self.cleanupPayload(newValue, value) + origValue = paramDict[kb.injection.parameter] + + if kb.technique and kb.technique in kb.injection.data: + where = kb.injection.data[kb.technique].where + + if where == 1: + value = origValue + elif where == 2: + value = "-%s" % origValue + elif where == 3: + value = "" + else: + value = origValue + + newValue = self.cleanupPayload(newValue, origValue) if "POSTxml" in conf.paramDict and kb.injection.place == PLACE.POST: root = ET.XML(paramString) @@ -90,7 +103,7 @@ class Agent: retValue = paramString.replace("*", self.addPayloadDelimiters("%s%s" % (negValue, falseValue + newValue))) else: - retValue = paramString.replace("%s=%s" % (kb.injection.parameter, value), + retValue = paramString.replace("%s=%s" % (kb.injection.parameter, origValue), "%s=%s" % (kb.injection.parameter, self.addPayloadDelimiters(negValue + value + falseValue + newValue))) # Before identifing the injectable parameter @@ -135,8 +148,17 @@ class Agent: if conf.direct: return self.payloadDirect(string) - query = "%s " % kb.injection.prefix - query += string + if kb.technique == 4: + query = kb.injection.prefix + elif kb.technique and kb.technique in kb.injection.data: + where = kb.injection.data[kb.technique].where + + if where == 3: + query = kb.injection.prefix + else: + query = "%s " % kb.injection.prefix + + query = "%s%s" % (query, string) query = self.cleanupPayload(query) return query diff --git a/lib/core/option.py b/lib/core/option.py index 6974099ff..6c443995a 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -1175,6 +1175,7 @@ def __setKnowledgeBaseAttributes(): kb.tamperFunctions = [] kb.targetUrls = set() kb.testedParams = set() + kb.technique = None kb.unionComment = "" kb.unionCount = None kb.unionPosition = None diff --git a/lib/request/inject.py b/lib/request/inject.py index d8676d1a8..eac83bb39 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -29,7 +29,6 @@ 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 from lib.techniques.inband.union.use import unionUse @@ -309,6 +308,31 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r return returnValue +def __goError(expression, resumeValue=True): + """ + Retrieve the output of a SQL query taking advantage of an error-based + SQL injection vulnerability on the affected parameter. + """ + + result = None + + if conf.direct: + return direct(expression), None + + condition = ( + kb.resumedQueries and conf.url in kb.resumedQueries.keys() + and expression in kb.resumedQueries[conf.url].keys() + ) + + if condition and resumeValue: + result = resume(expression, None) + + if not result: + result = errorUse(expression) + dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injection.place, conf.parameters[kb.injection.place], expression, replaceNewlineTabs(result))) + + return result + def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True, dump=False): """ Retrieve the output of a SQL query taking advantage of an inband SQL @@ -359,6 +383,7 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex expression = expression.replace("DISTINCT ", "") if inband and kb.unionTest is not None: + kb.technique = 3 value = __goInband(expression, expected, sort, resumeValue, unpack, dump) if not value: @@ -373,7 +398,8 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex kb.unionNegative = False if error and kb.errorTest and not value: - value = goError(expression) + kb.technique = 2 + value = __goError(expression, resumeValue) if not value: warnMsg = "for some reason(s) it was not possible to retrieve " @@ -382,6 +408,7 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex logger.warn(warnMsg) if blind and kb.booleanTest and not value: + kb.technique = 1 value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar) kb.unionFalseCond = oldParamFalseCond @@ -400,6 +427,7 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex return value def goStacked(expression, silent=False): + kb.technique = 4 expression = cleanQuery(expression) if conf.direct: @@ -416,35 +444,3 @@ def goStacked(expression, silent=False): page, _ = Request.queryPage(payload, content=True, silent=silent) return payload, page - -def goError(expression, suppressOutput=False): - """ - Retrieve the output of a SQL query taking advantage of an error-based - SQL injection vulnerability on the affected parameter. - """ - - result = None - - if suppressOutput: - pushValue(conf.verbose) - conf.verbose = 0 - - if conf.direct: - return direct(expression), None - - condition = ( - kb.resumedQueries and conf.url in kb.resumedQueries.keys() - and expression in kb.resumedQueries[conf.url].keys() - ) - - if condition: - result = resume(expression, None) - - if not result: - result = errorUse(expression) - dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injection.place, conf.parameters[kb.injection.place], expression, replaceNewlineTabs(result))) - - if suppressOutput: - conf.verbose = popValue() - - return result