From 6fa2fd139c3e26c5c9d9ccf6fd673232e6d750d5 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Fri, 8 Apr 2011 15:17:57 +0000 Subject: [PATCH] implemented support for __pivotDumpTable on MSSQL as normal tables tend to not play well with normal TOP 1 ..NOT IN..ORDER BY mechanism if the argument for ORDER BY is not the unique one (returns only number of rows equal to the number of distinct values for that field) --- lib/techniques/error/use.py | 2 +- lib/techniques/inband/union/use.py | 2 +- plugins/generic/enumeration.py | 29 ++++++++++++++--------------- xml/queries.xml | 3 +-- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py index 70135ce21..141c3de3e 100644 --- a/lib/techniques/error/use.py +++ b/lib/techniques/error/use.py @@ -195,7 +195,7 @@ def errorUse(expression, expected=None, resumeValue=True, dump=False): or (Backend.getIdentifiedDbms() in FROM_TABLE and not \ expression.upper().endswith(FROM_TABLE[Backend.getIdentifiedDbms()]))) \ and ("(CASE" not in expression.upper() or ("(CASE" in expression.upper() and "WHEN use" in expression))) \ - and not any(map(lambda x: x in expression.upper(), ["COUNT(*)", "EXISTS(", "MAX(", "MIN("])): + and not any(map(lambda x: x in expression.upper(), ["COUNT(*)", "EXISTS(", "MAX(", "MIN(", "COUNT(DISTINCT"])): limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I) topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I) diff --git a/lib/techniques/inband/union/use.py b/lib/techniques/inband/union/use.py index 194beff6c..2700ce963 100644 --- a/lib/techniques/inband/union/use.py +++ b/lib/techniques/inband/union/use.py @@ -137,7 +137,7 @@ def unionUse(expression, unpack=True, dump=False): " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() \ not in FROM_TABLE) or (Backend.getIdentifiedDbms() in FROM_TABLE \ and not expression.upper().endswith(FROM_TABLE[Backend.getIdentifiedDbms()]))) \ - and not any(map(lambda x: x in expression.upper(), ["(CASE", "COUNT(*)", "EXISTS(", "MAX(", "MIN("])): + and not any(map(lambda x: x in expression.upper(), ["(CASE", "COUNT(*)", "EXISTS(", "MAX(", "MIN(", "COUNT(DISTINCT"])): limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I) topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I) diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index a7bc8a3fc..eec7aac84 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -1304,10 +1304,14 @@ class Enumeration: query = rootQuery.inband.query % (colString, conf.tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), conf.tbl.upper()))) elif Backend.getIdentifiedDbms() == DBMS.SQLITE: query = rootQuery.inband.query % (colString, conf.tbl) - elif Backend.getIdentifiedDbms() == DBMS.SYBASE: - table = "%s..%s" % (conf.db, conf.tbl) - entries, _ = self.__pivotDumpTable(table, colList, blind=False) - entries = zip(*[entries[colName] for colName in colList]) + elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL): + # Partial inband and error + if not (isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL): + table = "%s.%s" % (conf.db, conf.tbl) + entries, _ = self.__pivotDumpTable(table, colList, blind=False) + entries = zip(*[entries[colName] for colName in colList]) + else: + query = rootQuery.inband.query % (colString, conf.db, conf.tbl) else: query = rootQuery.inband.query % (colString, conf.db, conf.tbl) @@ -1358,8 +1362,8 @@ class Enumeration: query = rootQuery.blind.count % (conf.tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), conf.tbl.upper()))) elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD): query = rootQuery.blind.count % conf.tbl - elif Backend.getIdentifiedDbms() == DBMS.SYBASE: - query = rootQuery.blind.count % ("%s..%s" % (conf.db, conf.tbl)) + elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL): + query = rootQuery.blind.count % ("%s.%s" % (conf.db, conf.tbl)) elif Backend.getIdentifiedDbms() == DBMS.MAXDB: query = rootQuery.blind.count % ("%s" % conf.tbl) else: @@ -1381,17 +1385,17 @@ class Enumeration: entries = {} try: - if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB): + if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB, DBMS.MSSQL): if Backend.getIdentifiedDbms() == DBMS.ACCESS: table = conf.tbl - elif Backend.getIdentifiedDbms() == DBMS.SYBASE: - table = "%s..%s" % (conf.db, conf.tbl) + elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL): + table = "%s.%s" % (conf.db, conf.tbl) elif Backend.getIdentifiedDbms() == DBMS.MAXDB: table = "%s.%s" % (conf.db, conf.tbl) entries, lengths = self.__pivotDumpTable(table, colList, count, blind=True) else: - if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.MSSQL, DBMS.SYBASE): + if Backend.getIdentifiedDbms() == DBMS.ORACLE: plusOne = True else: plusOne = False @@ -1412,11 +1416,6 @@ class Enumeration: query = rootQuery.blind.query % (column, column, conf.tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), conf.tbl.upper())), index) - elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE): - query = rootQuery.blind.query % (column, index, conf.db, - conf.tbl, colList[0], - colList[0], colList[0]) - elif Backend.getIdentifiedDbms() == DBMS.SQLITE: query = rootQuery.blind.query % (column, conf.tbl, index) diff --git a/xml/queries.xml b/xml/queries.xml index 8988ceb4c..fddb0a286 100644 --- a/xml/queries.xml +++ b/xml/queries.xml @@ -193,8 +193,7 @@ - - +