further improvement of MaxDB support

This commit is contained in:
Miroslav Stampar 2011-02-20 22:41:42 +00:00
parent a3ba8b6928
commit aac817935a
6 changed files with 88 additions and 33 deletions

View File

@ -11,6 +11,7 @@ import codecs
import re import re
import os import os
from lib.core.common import Backend
from lib.core.common import dataToDumpFile from lib.core.common import dataToDumpFile
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getUnicode 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 conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS
from lib.core.replication import Replication from lib.core.replication import Replication
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
@ -101,7 +103,10 @@ class Dump:
self.string("current user", data) self.string("current user", data)
def currentDb(self,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): def dba(self,data):
self.string("current user is DBA", data) self.string("current user is DBA", data)

View File

@ -23,12 +23,6 @@ class Enumeration(GenericEnumeration):
kb.data.processChar = lambda x: x.replace('_', ' ') if x else x 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): def getPasswordHashes(self):
warnMsg = "on SAP MaxDB it is not possible to enumerate the user password hashes" warnMsg = "on SAP MaxDB it is not possible to enumerate the user password hashes"
logger.warn(warnMsg) logger.warn(warnMsg)
@ -42,35 +36,82 @@ class Enumeration(GenericEnumeration):
return [] return []
def getColumns(self, onlyColNames=False): def getColumns(self, onlyColNames=False):
if "." in conf.tbl:
conf.db, conf.tbl = conf.tbl.split(".")
self.forceDbmsEnum() self.forceDbmsEnum()
rootQuery = queries[Backend.getIdentifiedDbms()].columns rootQuery = queries[Backend.getIdentifiedDbms()].columns
condition = rootQuery.blind.condition if 'condition' in rootQuery.blind else None
infoMsg = "fetching columns " infoMsg = "fetching columns "
infoMsg += "for table '%s' " % conf.tbl infoMsg += "for table '%s' " % conf.tbl
if conf.db:
infoMsg += "on schema '%s'" % conf.db
logger.info(infoMsg) logger.info(infoMsg)
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) or conf.direct: randStr = randomStr()
blinds = [False, True] query = rootQuery.inband.query % (conf.tbl, ("'%s'" % conf.db) if conf.db != "USER" else 'USER')
else: retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr,'%s.datatype' % randStr,'%s.len' % randStr], blind=True)
blinds = [True]
for blind in blinds: if retVal:
randStr = randomStr() table = {}
query = rootQuery.inband.query % conf.tbl columns = {}
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr,'%s.datatype' % randStr,'%s.len' % randStr], blind=blind)
if retVal: for columnname, datatype, length in zip(retVal[0]["%s.columnname" % randStr], retVal[0]["%s.datatype" % randStr], retVal[0]["%s.len" % randStr]):
table = {} columns[columnname] = "%s(%s)" % (datatype, length)
columns = {}
for columnname, datatype, length in zip(retVal[0]["%s.columnname" % randStr], retVal[0]["%s.datatype" % randStr], retVal[0]["%s.len" % randStr]): table[conf.tbl] = columns
columns[columnname] = "%s(%s)" % (datatype, length) kb.data.cachedColumns[conf.db] = table
table[conf.tbl] = columns
kb.data.cachedColumns[conf.db] = table
break
return kb.data.cachedColumns 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

View File

@ -135,7 +135,10 @@ class Fingerprint(GenericFingerprint):
return False return False
def forceDbmsEnum(self): 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: if conf.tbl:
conf.tbl = conf.tbl.upper() conf.tbl = conf.tbl.upper()

View File

@ -60,7 +60,6 @@ class Enumeration(GenericEnumeration):
conf.db = self.getCurrentDb() conf.db = self.getCurrentDb()
rootQuery = queries[Backend.getIdentifiedDbms()].columns rootQuery = queries[Backend.getIdentifiedDbms()].columns
condition = rootQuery.blind.condition if 'condition' in rootQuery.blind else None
infoMsg = "fetching columns " infoMsg = "fetching columns "
infoMsg += "for table '%s' " % conf.tbl infoMsg += "for table '%s' " % conf.tbl

View File

@ -1386,10 +1386,12 @@ class Enumeration:
try: try:
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB): 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 table = conf.tbl
elif Backend.getIdentifiedDbms() == DBMS.SYBASE: elif Backend.getIdentifiedDbms() == DBMS.SYBASE:
table = "%s..%s" % (conf.db, conf.tbl) 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) entries, lengths = self.__pivotDumpTable(table, colList, count, blind=True)
else: else:

View File

@ -450,15 +450,20 @@
<blind query="SELECT MIN(username) FROM domain.users WHERE username > '%s'" count="SELECT CHR(COUNT(*)) FROM domain.users"/> <blind query="SELECT MIN(username) FROM domain.users WHERE username > '%s'" count="SELECT CHR(COUNT(*)) FROM domain.users"/>
</users> </users>
<columns> <columns>
<inband query="SELECT columnname, datatype, len FROM domain.columns WHERE tablename = '%s' AND schemaname=user"/> <inband query="SELECT columnname, datatype, len FROM domain.columns WHERE tablename='%s' AND schemaname=%s"/>
<blind query="SELECT columnname FROM domain.columns WHERE tablename = '%s' AND schemaname=user ORDER BY pos" query2="SELECT datatype FROM domain.columns WHERE tablename = '%s' AND schemaname=user ORDER BY pos"/> <blind/>
</columns> </columns>
<tables> <tables>
<inband query="SELECT tablename FROM domain.tables WHERE schemaname='%s' AND type='TABLE'"/> <inband query="SELECT tablename FROM domain.tables WHERE schemaname=%s AND type='TABLE'"/>
<blind query="SELECT MIN(tablename) FROM domain.tables WHERE schemaname=user AND type='TABLE' AND name > '%s'" count="SELECT CHR(COUNT(*)) FROM domain.tables WHERE schemaname=user AND type='TABLE'"/> <blind/>
</tables> </tables>
<dbs>
<inband query="SELECT DISTINCT(schemaname) FROM domain.tables"/>
<blind/>
</dbs>
<roles> <roles>
<inband query="SELECT owner, role FROM domain.roles" condition="owner"/> <inband query="SELECT owner, role FROM domain.roles" condition="owner"/>
<blind/>
</roles> </roles>
<dump_table> <dump_table>
<inband query="SELECT %s FROM %%s"/> <inband query="SELECT %s FROM %%s"/>