From 90d990037153f403cbb254e51349b6d44f9e34f6 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Fri, 30 Apr 2010 15:48:40 +0000 Subject: [PATCH] Minor bug fix to consider --start and --stop also in partial UNION query SQL injection --- lib/request/inject.py | 8 ++++---- lib/techniques/inband/union/use.py | 20 +++++++++++--------- plugins/generic/enumeration.py | 16 ++++++---------- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/lib/request/inject.py b/lib/request/inject.py index 4068e4f22..88c631f60 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -314,7 +314,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r return returnValue -def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True): +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 injection vulnerability on the affected parameter. @@ -336,14 +336,14 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr partial = True if not output: - output = unionUse(expression, resetCounter=True, unpack=unpack) + output = unionUse(expression, resetCounter=True, unpack=unpack, dump=dump) if output: data = parseUnionPage(output, expression, partial, condition, sort) return data -def getValue(expression, blind=True, inband=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None): +def getValue(expression, blind=True, inband=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False): """ Called each time sqlmap inject a SQL query on the SQL injection affected parameter. It can call a function to retrieve the output @@ -361,7 +361,7 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None, expression = expression.replace("DISTINCT ", "") if inband and kb.unionPosition: - value = __goInband(expression, expected, sort, resumeValue, unpack) + value = __goInband(expression, expected, sort, resumeValue, unpack, dump) if not value: warnMsg = "for some reasons it was not possible to retrieve " diff --git a/lib/techniques/inband/union/use.py b/lib/techniques/inband/union/use.py index 06f91223f..e3a96ec40 100644 --- a/lib/techniques/inband/union/use.py +++ b/lib/techniques/inband/union/use.py @@ -39,7 +39,7 @@ from lib.utils.resume import resume reqCount = 0 -def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullChar="NULL", unpack=True): +def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullChar="NULL", unpack=True, dump=False): """ This function tests for an inband SQL injection on the target url then call its subsidiary function to effectively perform an @@ -73,13 +73,6 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh if ( kb.unionNegative or kb.unionFalseCond ) and not direct: _, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr) - if len(expressionFieldsList) > 1: - infoMsg = "the SQL query provided has more than a field. " - infoMsg += "sqlmap will now unpack it into distinct queries " - infoMsg += "to be able to retrieve the output even if we " - infoMsg += "are in front of a partial inband sql injection" - logger.info(infoMsg) - # We have to check if the SQL query might return multiple entries # and in such case forge the SQL limiting the query output one # entry per time @@ -130,6 +123,11 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh elif kb.dbms == "Microsoft SQL Server": stopLimit += startLimit + elif dump: + if conf.limitStart: + startLimit = conf.limitStart + if conf.limitStop: + stopLimit = conf.limitStop if not stopLimit or stopLimit <= 1: if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"): @@ -194,10 +192,14 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh field = None limitedExpr = agent.limitQuery(num, expression, field) - output = unionUse(limitedExpr, direct=True, unescape=False) + output = resume(limitedExpr, None) + + if not output: + output = unionUse(limitedExpr, direct=True, unescape=False) if output: value += output + parseUnionPage(output, limitedExpr) return value diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index c4a515281..68caff95a 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -1331,7 +1331,7 @@ class Enumeration: query = rootQuery["inband"]["query"] % (colString, conf.tbl) else: query = rootQuery["inband"]["query"] % (colString, conf.db, conf.tbl) - entries = inject.getValue(query, blind=False) + entries = inject.getValue(query, blind=False, dump=True) if entries: if isinstance(entries, str): @@ -1432,19 +1432,15 @@ class Enumeration: else: length = lengths[column] - kb.data.dumpedTable[column] = { - "length": length, - "values": columnEntries, - } + kb.data.dumpedTable[column] = { "length": length, + "values": columnEntries } entriesCount = len(columnEntries) if kb.data.dumpedTable: - kb.data.dumpedTable["__infos__"] = { - "count": entriesCount, - "table": conf.tbl, - "db": conf.db - } + kb.data.dumpedTable["__infos__"] = { "count": entriesCount, + "table": conf.tbl, + "db": conf.db } else: warnMsg = "unable to retrieve the entries of " if conf.col: