From aac817935a5d1037973333921c42bda6a23bd7fb Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Sun, 20 Feb 2011 22:41:42 +0000 Subject: [PATCH] further improvement of MaxDB support --- lib/core/dump.py | 7 ++- plugins/dbms/maxdb/enumeration.py | 91 ++++++++++++++++++++++-------- plugins/dbms/maxdb/fingerprint.py | 5 +- plugins/dbms/sybase/enumeration.py | 1 - plugins/generic/enumeration.py | 4 +- xml/queries.xml | 13 +++-- 6 files changed, 88 insertions(+), 33 deletions(-) diff --git a/lib/core/dump.py b/lib/core/dump.py index 318639ccd..e90842a9a 100644 --- a/lib/core/dump.py +++ b/lib/core/dump.py @@ -11,6 +11,7 @@ import codecs import re import os +from lib.core.common import Backend from lib.core.common import dataToDumpFile from lib.core.common import dataToStdout from lib.core.common import getUnicode @@ -19,6 +20,7 @@ from lib.core.common import restoreDumpMarkedChars from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.enums import DBMS from lib.core.replication import Replication from lib.core.settings import UNICODE_ENCODING @@ -101,7 +103,10 @@ class Dump: self.string("current user", data) def currentDb(self,data): - self.string("current database", data) + if Backend.getIdentifiedDbms() in (DBMS.MAXDB, DBMS.ORACLE): + self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data) + else: + self.string("current database", data) def dba(self,data): self.string("current user is DBA", data) diff --git a/plugins/dbms/maxdb/enumeration.py b/plugins/dbms/maxdb/enumeration.py index 70feb070c..98552c1d1 100644 --- a/plugins/dbms/maxdb/enumeration.py +++ b/plugins/dbms/maxdb/enumeration.py @@ -23,12 +23,6 @@ class Enumeration(GenericEnumeration): kb.data.processChar = lambda x: x.replace('_', ' ') if x else x - def getDbs(self): - warnMsg = "on SAP MaxDB it is not possible to enumerate databases" - logger.warn(warnMsg) - - return [] - def getPasswordHashes(self): warnMsg = "on SAP MaxDB it is not possible to enumerate the user password hashes" logger.warn(warnMsg) @@ -42,35 +36,82 @@ class Enumeration(GenericEnumeration): return [] def getColumns(self, onlyColNames=False): + if "." in conf.tbl: + conf.db, conf.tbl = conf.tbl.split(".") + self.forceDbmsEnum() rootQuery = queries[Backend.getIdentifiedDbms()].columns - condition = rootQuery.blind.condition if 'condition' in rootQuery.blind else None infoMsg = "fetching columns " infoMsg += "for table '%s' " % conf.tbl + if conf.db: + infoMsg += "on schema '%s'" % conf.db logger.info(infoMsg) - if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: - blinds = [False, True] - else: - blinds = [True] + randStr = randomStr() + query = rootQuery.inband.query % (conf.tbl, ("'%s'" % conf.db) if conf.db != "USER" else 'USER') + retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr,'%s.datatype' % randStr,'%s.len' % randStr], blind=True) - for blind in blinds: - randStr = randomStr() - query = rootQuery.inband.query % conf.tbl - retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr,'%s.datatype' % randStr,'%s.len' % randStr], blind=blind) + if retVal: + table = {} + columns = {} - if retVal: - table = {} - columns = {} + for columnname, datatype, length in zip(retVal[0]["%s.columnname" % randStr], retVal[0]["%s.datatype" % randStr], retVal[0]["%s.len" % randStr]): + columns[columnname] = "%s(%s)" % (datatype, length) - for columnname, datatype, length in zip(retVal[0]["%s.columnname" % randStr], retVal[0]["%s.datatype" % randStr], retVal[0]["%s.len" % randStr]): - columns[columnname] = "%s(%s)" % (datatype, length) - - table[conf.tbl] = columns - kb.data.cachedColumns[conf.db] = table - - break + table[conf.tbl] = columns + kb.data.cachedColumns[conf.db] = table return kb.data.cachedColumns + + def getTables(self, bruteForce=None): + self.forceDbmsEnum() + + infoMsg = "fetching tables" + if conf.db: + infoMsg += " for schema '%s'" % conf.db + logger.info(infoMsg) + + rootQuery = queries[Backend.getIdentifiedDbms()].tables + + if conf.db: + if "," in conf.db: + dbs = conf.db.split(",") + else: + dbs = [conf.db] + else: + if not len(kb.data.cachedDbs): + dbs = self.getDbs() + else: + dbs = kb.data.cachedDbs + + for db in dbs: + randStr = randomStr() + query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER') + retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.tablename' % randStr], blind=True) + + if retVal: + for table in retVal[0].values()[0]: + if not kb.data.cachedTables.has_key(db): + kb.data.cachedTables[db] = [table] + else: + kb.data.cachedTables[db].append(table) + + return kb.data.cachedTables + + def getDbs(self): + infoMsg = "fetching database names" + logger.info(infoMsg) + + rootQuery = queries[Backend.getIdentifiedDbms()].dbs + + randStr = randomStr() + query = rootQuery.inband.query + + retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.schemaname' % randStr], blind=True) + + if retVal: + kb.data.cachedDbs = retVal[0].values()[0] + + return kb.data.cachedDbs diff --git a/plugins/dbms/maxdb/fingerprint.py b/plugins/dbms/maxdb/fingerprint.py index 8d6d4ddbb..643c1c0de 100644 --- a/plugins/dbms/maxdb/fingerprint.py +++ b/plugins/dbms/maxdb/fingerprint.py @@ -135,7 +135,10 @@ class Fingerprint(GenericFingerprint): return False def forceDbmsEnum(self): - conf.db = "%s%s" % (DBMS.MAXDB, METADB_SUFFIX) + if conf.db: + conf.db = conf.db.upper() + else: + conf.db = "USER" if conf.tbl: conf.tbl = conf.tbl.upper() diff --git a/plugins/dbms/sybase/enumeration.py b/plugins/dbms/sybase/enumeration.py index d2bef3ddf..ec0fa9c7b 100644 --- a/plugins/dbms/sybase/enumeration.py +++ b/plugins/dbms/sybase/enumeration.py @@ -60,7 +60,6 @@ class Enumeration(GenericEnumeration): conf.db = self.getCurrentDb() rootQuery = queries[Backend.getIdentifiedDbms()].columns - condition = rootQuery.blind.condition if 'condition' in rootQuery.blind else None infoMsg = "fetching columns " infoMsg += "for table '%s' " % conf.tbl diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index d23433812..a5df1f77d 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -1386,10 +1386,12 @@ class Enumeration: try: if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB): - if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MAXDB): + if Backend.getIdentifiedDbms() == DBMS.ACCESS: table = conf.tbl elif Backend.getIdentifiedDbms() == DBMS.SYBASE: 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: diff --git a/xml/queries.xml b/xml/queries.xml index cd849d372..d5d9f9807 100644 --- a/xml/queries.xml +++ b/xml/queries.xml @@ -450,15 +450,20 @@ - - + + - - + + + + + + +