Major code refactoring - moved to one location only (getIdentifiedDBMS() in common.py) the retrieval of identified/fingerprinted DBMS.

Minor bug fixes thanks to previous refactoring too.
This commit is contained in:
Bernardo Damele
2011-01-13 17:36:54 +00:00
parent a1d1f69c3f
commit 2ac8debea0
37 changed files with 342 additions and 314 deletions

View File

@@ -14,6 +14,7 @@ from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getCurrentThreadData
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.common import randomInt
from lib.core.common import randomStr
from lib.core.common import wasLastRequestDBMSError
@@ -148,7 +149,7 @@ class Fingerprint(GenericFingerprint):
return value
def checkDbms(self):
if (kb.dbms is not None and kb.dbms.lower() in ACCESS_ALIASES) or conf.dbms in ACCESS_ALIASES:
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in ACCESS_ALIASES) or conf.dbms in ACCESS_ALIASES:
setDbms(DBMS.ACCESS)
if not conf.extensiveFp:

View File

@@ -13,6 +13,7 @@ from lib.core.agent import agent
from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getUnicode
from lib.core.common import randomInt
from lib.core.common import randomRange
@@ -97,13 +98,13 @@ class Fingerprint(GenericFingerprint):
def __dialectCheck(self):
retVal = None
if kb.dbms:
if getIdentifiedDBMS():
result = inject.checkBooleanExpression("EXISTS(SELECT CURRENT_DATE FROM RDB$DATABASE)")
retVal = "dialect 3" if result else "dialect 1"
return retVal
def checkDbms(self):
if (kb.dbms is not None and kb.dbms.lower() in FIREBIRD_ALIASES) or conf.dbms in FIREBIRD_ALIASES:
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in FIREBIRD_ALIASES) or conf.dbms in FIREBIRD_ALIASES:
setDbms(DBMS.FIREBIRD)
self.getBanner()

View File

@@ -13,6 +13,7 @@ from lib.core.agent import agent
from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.common import randomInt
from lib.core.common import randomRange
from lib.core.data import conf
@@ -100,7 +101,7 @@ class Fingerprint(GenericFingerprint):
return value
def checkDbms(self):
if (kb.dbms is not None and kb.dbms.lower() in MAXDB_ALIASES) or conf.dbms in MAXDB_ALIASES:
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in MAXDB_ALIASES) or conf.dbms in MAXDB_ALIASES:
setDbms(DBMS.MAXDB)
self.getBanner()

View File

@@ -9,6 +9,7 @@ See the file 'doc/COPYING' for copying permission
from lib.core.agent import agent
from lib.core.common import arrayizeValue
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getRange
from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable
@@ -40,7 +41,7 @@ class Enumeration(GenericEnumeration):
infoMsg += " for database '%s'" % conf.db
logger.info(infoMsg)
rootQuery = queries[kb.dbms].tables
rootQuery = queries[getIdentifiedDBMS()].tables
if not conf.db:
if not len(kb.data.cachedDbs):
@@ -110,7 +111,7 @@ class Enumeration(GenericEnumeration):
return kb.data.cachedTables
def searchTable(self):
rootQuery = queries[kb.dbms].search_table
rootQuery = queries[getIdentifiedDBMS()].search_table
foundTbls = {}
tblList = conf.tbl.split(",")
tblCond = rootQuery.inband.condition
@@ -194,7 +195,7 @@ class Enumeration(GenericEnumeration):
return foundTbls
def searchColumn(self):
rootQuery = queries[kb.dbms].search_column
rootQuery = queries[getIdentifiedDBMS()].search_column
foundCols = {}
dbs = {}
colList = conf.col.split(",")

View File

@@ -11,6 +11,7 @@ from lib.core.agent import agent
from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getUnicode
from lib.core.common import randomInt
from lib.core.data import conf
@@ -72,7 +73,7 @@ class Fingerprint(GenericFingerprint):
return value
def checkDbms(self):
if ((kb.dbms is not None and kb.dbms.lower() in MSSQL_ALIASES) \
if ((getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in MSSQL_ALIASES) \
or conf.dbms in MSSQL_ALIASES) and kb.dbmsVersion and \
kb.dbmsVersion[0].isdigit():
setDbms("%s %s" % (DBMS.MSSQL, kb.dbmsVersion[0]))

View File

@@ -13,6 +13,7 @@ from lib.core.agent import agent
from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getUnicode
from lib.core.common import randomInt
from lib.core.data import conf
@@ -151,7 +152,7 @@ class Fingerprint(GenericFingerprint):
* http://dev.mysql.com/doc/refman/6.0/en/news-6-0-x.html (manual has been withdrawn)
"""
if ((kb.dbms is not None and kb.dbms.lower() in MYSQL_ALIASES) \
if ((getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in MYSQL_ALIASES) \
or conf.dbms in MYSQL_ALIASES) and kb.dbmsVersion and \
kb.dbmsVersion[0] != UNKNOWN_DBMS_VERSION:
kb.dbmsVersion[0] = kb.dbmsVersion[0].replace(">", "")

View File

@@ -8,6 +8,7 @@ See the file 'doc/COPYING' for copying permission
"""
from lib.core.agent import agent
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getRange
from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable
@@ -29,7 +30,7 @@ class Enumeration(GenericEnumeration):
def getRoles(self, query2=False):
infoMsg = "fetching database users roles"
rootQuery = queries[kb.dbms].roles
rootQuery = queries[getIdentifiedDBMS()].roles
if conf.user == "CU":
infoMsg += " for current user"
@@ -178,7 +179,7 @@ class Enumeration(GenericEnumeration):
return []
def searchColumn(self):
rootQuery = queries[kb.dbms].search_column
rootQuery = queries[getIdentifiedDBMS()].search_column
foundCols = {}
dbs = { "USERS": {} }
colList = conf.col.split(",")

View File

@@ -13,6 +13,7 @@ from lib.core.agent import agent
from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@@ -64,7 +65,7 @@ class Fingerprint(GenericFingerprint):
return value
def checkDbms(self):
if (kb.dbms is not None and kb.dbms.lower() in ORACLE_ALIASES) or conf.dbms in ORACLE_ALIASES:
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in ORACLE_ALIASES) or conf.dbms in ORACLE_ALIASES:
setDbms(DBMS.ORACLE)
self.getBanner()

View File

@@ -13,6 +13,7 @@ from lib.core.agent import agent
from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getUnicode
from lib.core.common import randomInt
from lib.core.data import conf
@@ -73,7 +74,7 @@ class Fingerprint(GenericFingerprint):
* http://www.postgresql.org/docs/8.4/interactive/release.html (up to 8.4.2)
"""
if (kb.dbms is not None and kb.dbms.lower() in PGSQL_ALIASES) or conf.dbms in PGSQL_ALIASES:
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in PGSQL_ALIASES) or conf.dbms in PGSQL_ALIASES:
setDbms(DBMS.PGSQL)
self.getBanner()

View File

@@ -11,6 +11,7 @@ from lib.core.agent import agent
from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@@ -70,7 +71,7 @@ class Fingerprint(GenericFingerprint):
* http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions
"""
if (kb.dbms is not None and kb.dbms.lower() in SQLITE_ALIASES) or conf.dbms in SQLITE_ALIASES:
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in SQLITE_ALIASES) or conf.dbms in SQLITE_ALIASES:
setDbms(DBMS.SQLITE)
self.getBanner()

View File

@@ -11,6 +11,7 @@ from lib.core.agent import agent
from lib.core.common import formatDBMSfp
from lib.core.common import formatFingerprint
from lib.core.common import getErrorParsedDBMSesFormatted
from lib.core.common import getIdentifiedDBMS
from lib.core.common import randomInt
from lib.core.data import conf
from lib.core.data import kb
@@ -63,7 +64,7 @@ class Fingerprint(GenericFingerprint):
return value
def checkDbms(self):
if ((kb.dbms is not None and kb.dbms.lower() in SYBASE_ALIASES) \
if ((getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in SYBASE_ALIASES) \
or conf.dbms in SYBASE_ALIASES) and kb.dbmsVersion and \
kb.dbmsVersion[0].isdigit():
setDbms("%s %s" % (DBMS.SYBASE, kb.dbmsVersion[0]))

View File

@@ -17,6 +17,7 @@ from lib.core.common import getRange
from lib.core.common import getCompiledRegex
from lib.core.common import getConsoleWidth
from lib.core.common import getFileItems
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getUnicode
from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable
@@ -74,19 +75,19 @@ class Enumeration:
kb.data.cachedColumns = {}
kb.data.dumpedTable = {}
kb.data.processChar = None
kb.misc.testedDbms = dbms
def getBanner(self):
if not conf.getBanner:
return
if kb.data.banner is None:
# TODO: is this assignement an ugly hack?
kb.dbmsDetected = True
infoMsg = "fetching banner"
logger.info(infoMsg)
query = queries[kb.dbms].banner.query
query = queries[getIdentifiedDBMS()].banner.query
kb.data.banner = inject.getValue(query)
bannerParser(kb.data.banner)
@@ -108,7 +109,7 @@ class Enumeration:
infoMsg = "fetching current user"
logger.info(infoMsg)
query = queries[kb.dbms].current_user.query
query = queries[getIdentifiedDBMS()].current_user.query
if not kb.data.currentUser:
kb.data.currentUser = inject.getValue(query)
@@ -119,7 +120,7 @@ class Enumeration:
infoMsg = "fetching current database"
logger.info(infoMsg)
query = queries[kb.dbms].current_db.query
query = queries[getIdentifiedDBMS()].current_db.query
if not kb.data.currentDb:
kb.data.currentDb = inject.getValue(query)
@@ -130,11 +131,11 @@ class Enumeration:
infoMsg = "testing if current user is DBA"
logger.info(infoMsg)
if kb.dbms == DBMS.MYSQL:
if getIdentifiedDBMS() == DBMS.MYSQL:
self.getCurrentUser()
query = queries[kb.dbms].is_dba.query % kb.data.currentUser.split("@")[0]
query = queries[getIdentifiedDBMS()].is_dba.query % kb.data.currentUser.split("@")[0]
else:
query = queries[kb.dbms].is_dba.query
query = queries[getIdentifiedDBMS()].is_dba.query
query = agent.forgeCaseStatement(query)
@@ -146,10 +147,10 @@ class Enumeration:
infoMsg = "fetching database users"
logger.info(infoMsg)
rootQuery = queries[kb.dbms].users
rootQuery = queries[getIdentifiedDBMS()].users
condition = ( kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ) )
condition |= ( kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema )
condition = ( getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ) )
condition |= ( getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema )
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
if condition:
@@ -175,14 +176,14 @@ class Enumeration:
errMsg = "unable to retrieve the number of database users"
raise sqlmapNoneDataException, errMsg
if kb.dbms == DBMS.ORACLE:
if getIdentifiedDBMS() == DBMS.ORACLE:
plusOne = True
else:
plusOne = False
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
if kb.dbms in (DBMS.SYBASE, DBMS.MAXDB):
if getIdentifiedDBMS() in (DBMS.SYBASE, DBMS.MAXDB):
query = rootQuery.blind.query % (kb.data.cachedUsers[-1] if kb.data.cachedUsers else " ")
elif condition:
query = rootQuery.blind.query2 % index
@@ -202,7 +203,7 @@ class Enumeration:
def getPasswordHashes(self):
infoMsg = "fetching database users password hashes"
rootQuery = queries[kb.dbms].passwords
rootQuery = queries[getIdentifiedDBMS()].passwords
if conf.user == "CU":
infoMsg += " for current user"
@@ -211,7 +212,7 @@ class Enumeration:
logger.info(infoMsg)
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
if kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
if getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
query = rootQuery.inband.query2
else:
query = rootQuery.inband.query
@@ -224,7 +225,7 @@ class Enumeration:
query += " WHERE "
query += " OR ".join("%s = '%s'" % (condition, user) for user in users)
else:
if kb.dbms == DBMS.MYSQL:
if getIdentifiedDBMS() == DBMS.MYSQL:
parsedUser = re.search("[\047]*(.*?)[\047]*\@", conf.user)
if parsedUser:
@@ -261,7 +262,7 @@ class Enumeration:
retrievedUsers = set()
for user in users:
if kb.dbms == DBMS.MYSQL:
if getIdentifiedDBMS() == DBMS.MYSQL:
parsedUser = re.search("[\047]*(.*?)[\047]*\@", user)
if parsedUser:
@@ -274,7 +275,7 @@ class Enumeration:
infoMsg += "for user '%s'" % user
logger.info(infoMsg)
if kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
if getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
query = rootQuery.blind.count2 % user
else:
query = rootQuery.blind.count % user
@@ -291,14 +292,14 @@ class Enumeration:
passwords = []
if kb.dbms == DBMS.ORACLE:
if getIdentifiedDBMS() == DBMS.ORACLE:
plusOne = True
else:
plusOne = False
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
if kb.dbms == DBMS.SYBASE:
if getIdentifiedDBMS() == DBMS.SYBASE:
if index > 0:
warnMsg = "unable to retrieve other password "
warnMsg += "hashes for user '%s'" % user
@@ -307,7 +308,7 @@ class Enumeration:
else:
query = rootQuery.blind.query % user
getCurrentThreadData().disableStdOut = True
elif kb.dbms == DBMS.MSSQL:
elif getIdentifiedDBMS() == DBMS.MSSQL:
if kb.dbmsVersion[0] in ( "2005", "2008" ):
query = rootQuery.blind.query2 % (user, index, user)
else:
@@ -315,7 +316,7 @@ class Enumeration:
else:
query = rootQuery.blind.query % (user, index)
password = inject.getValue(query, inband=False)
if kb.dbms == DBMS.SYBASE:
if getIdentifiedDBMS() == DBMS.SYBASE:
getCurrentThreadData().disableStdOut = False
password = "0x%s" % strToHex(password)
infoMsg = "retrieved: %s" % password
@@ -352,31 +353,31 @@ class Enumeration:
def __isAdminFromPrivileges(self, privileges):
# In PostgreSQL the usesuper privilege means that the
# user is DBA
dbaCondition = ( kb.dbms == DBMS.PGSQL and "super" in privileges )
dbaCondition = ( getIdentifiedDBMS() == DBMS.PGSQL and "super" in privileges )
# In Oracle the DBA privilege means that the
# user is DBA
dbaCondition |= ( kb.dbms == DBMS.ORACLE and "DBA" in privileges )
dbaCondition |= ( getIdentifiedDBMS() == DBMS.ORACLE and "DBA" in privileges )
# In MySQL >= 5.0 the SUPER privilege means
# that the user is DBA
dbaCondition |= ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema and "SUPER" in privileges )
dbaCondition |= ( getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema and "SUPER" in privileges )
# In MySQL < 5.0 the super_priv privilege means
# that the user is DBA
dbaCondition |= ( kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema and "super_priv" in privileges )
dbaCondition |= ( getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema and "super_priv" in privileges )
# In Firebird there is no specific privilege that means
# that the user is DBA
# TODO: confirm
dbaCondition |= ( kb.dbms == DBMS.FIREBIRD and "SELECT" in privileges and "INSERT" in privileges and "UPDATE" in privileges and "DELETE" in privileges and "REFERENCES" in privileges and "EXECUTE" in privileges )
dbaCondition |= ( getIdentifiedDBMS() == DBMS.FIREBIRD and "SELECT" in privileges and "INSERT" in privileges and "UPDATE" in privileges and "DELETE" in privileges and "REFERENCES" in privileges and "EXECUTE" in privileges )
return dbaCondition
def getPrivileges(self, query2=False):
infoMsg = "fetching database users privileges"
rootQuery = queries[kb.dbms].privileges
rootQuery = queries[getIdentifiedDBMS()].privileges
if conf.user == "CU":
infoMsg += " for current user"
@@ -432,10 +433,10 @@ class Enumeration:
}
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.inband.query2
condition = rootQuery.inband.condition2
elif kb.dbms == DBMS.ORACLE and query2:
elif getIdentifiedDBMS() == DBMS.ORACLE and query2:
query = rootQuery.inband.query2
condition = rootQuery.inband.condition2
else:
@@ -447,7 +448,7 @@ class Enumeration:
query += " WHERE "
# NOTE: I assume that the user provided is not in
# MySQL >= 5.0 syntax 'user'@'host'
if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
queryUser = "%" + conf.user + "%"
query += " OR ".join("%s LIKE '%s'" % (condition, "%" + user + "%") for user in users)
else:
@@ -455,7 +456,7 @@ class Enumeration:
values = inject.getValue(query, blind=False, error=False)
if not values and kb.dbms == DBMS.ORACLE and not query2:
if not values and getIdentifiedDBMS() == DBMS.ORACLE and not query2:
infoMsg = "trying with table USER_SYS_PRIVS"
logger.info(infoMsg)
@@ -477,19 +478,19 @@ class Enumeration:
# In PostgreSQL we get 1 if the privilege is
# True, 0 otherwise
if kb.dbms == DBMS.PGSQL and getUnicode(privilege).isdigit():
if getIdentifiedDBMS() == DBMS.PGSQL and getUnicode(privilege).isdigit():
for position, pgsqlPriv in pgsqlPrivs:
if count == position and int(privilege) == 1:
privileges.add(pgsqlPriv)
# In MySQL >= 5.0 and Oracle we get the list
# of privileges as string
elif kb.dbms == DBMS.ORACLE or ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema ):
elif getIdentifiedDBMS() == DBMS.ORACLE or ( getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema ):
privileges.add(privilege)
# In MySQL < 5.0 we get Y if the privilege is
# True, N otherwise
elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
elif getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
for position, mysqlPriv in mysqlPrivs:
if count == position and privilege.upper() == "Y":
privileges.add(mysqlPriv)
@@ -506,7 +507,7 @@ class Enumeration:
conditionChar = "="
if conf.user:
if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
conditionChar = " LIKE "
if "," in conf.user:
@@ -533,7 +534,7 @@ class Enumeration:
for user in users:
unescapedUser = None
if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
unescapedUser = unescaper.unescape(user, quote=False)
if user in retrievedUsers:
@@ -548,18 +549,18 @@ class Enumeration:
else:
queryUser = user
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.blind.count2 % queryUser
elif kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
elif getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
query = rootQuery.blind.count % (conditionChar, queryUser)
elif kb.dbms == DBMS.ORACLE and query2:
elif getIdentifiedDBMS() == DBMS.ORACLE and query2:
query = rootQuery.blind.count2 % queryUser
else:
query = rootQuery.blind.count % queryUser
count = inject.getValue(query, inband=False, expected=EXPECTED.INT, charsetType=2)
if not isNumPosStrValue(count):
if not (isinstance(count, basestring) and count.isdigit()) and kb.dbms == DBMS.ORACLE and not query2:
if not (isinstance(count, basestring) and count.isdigit()) and getIdentifiedDBMS() == DBMS.ORACLE and not query2:
infoMsg = "trying with table USER_SYS_PRIVS"
logger.info(infoMsg)
@@ -575,20 +576,20 @@ class Enumeration:
privileges = set()
if kb.dbms == DBMS.ORACLE:
if getIdentifiedDBMS() == DBMS.ORACLE:
plusOne = True
else:
plusOne = False
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.blind.query2 % (queryUser, index)
elif kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
elif getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
query = rootQuery.blind.query % (conditionChar, queryUser, index)
elif kb.dbms == DBMS.ORACLE and query2:
elif getIdentifiedDBMS() == DBMS.ORACLE and query2:
query = rootQuery.blind.query2 % (queryUser, index)
elif kb.dbms == DBMS.FIREBIRD:
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
query = rootQuery.blind.query % (index, queryUser)
else:
query = rootQuery.blind.query % (queryUser, index)
@@ -596,7 +597,7 @@ class Enumeration:
# In PostgreSQL we get 1 if the privilege is True,
# 0 otherwise
if kb.dbms == DBMS.PGSQL and ", " in privilege:
if getIdentifiedDBMS() == DBMS.PGSQL and ", " in privilege:
privilege = privilege.replace(", ", ",")
privs = privilege.split(",")
i = 1
@@ -611,12 +612,12 @@ class Enumeration:
# In MySQL >= 5.0 and Oracle we get the list
# of privileges as string
elif kb.dbms == DBMS.ORACLE or ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema ):
elif getIdentifiedDBMS() == DBMS.ORACLE or ( getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema ):
privileges.add(privilege)
# In MySQL < 5.0 we get Y if the privilege is
# True, N otherwise
elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
elif getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
privilege = privilege.replace(", ", ",")
privs = privilege.split(",")
i = 1
@@ -630,7 +631,7 @@ class Enumeration:
i += 1
# In Firebird we get one letter for each privilege
elif kb.dbms == DBMS.FIREBIRD:
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
privileges.add(firebirdPrivs[privilege.strip()])
if self.__isAdminFromPrivileges(privileges):
@@ -639,7 +640,7 @@ class Enumeration:
# In MySQL < 5.0 we break the cycle after the first
# time we get the user's privileges otherwise we
# duplicate the same query
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
break
if privileges:
@@ -659,14 +660,14 @@ class Enumeration:
return ( kb.data.cachedUsersPrivileges, areAdmins )
def getRoles(self, query2=False):
warnMsg = "on %s the concept of roles does not " % kb.dbms
warnMsg = "on %s the concept of roles does not " % getIdentifiedDBMS()
warnMsg += "exist. sqlmap will enumerate privileges instead"
logger.warn(warnMsg)
return self.getPrivileges(query2)
def getDbs(self):
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
warnMsg = "information_schema not available, "
warnMsg += "back-end DBMS is MySQL < 5. database "
warnMsg += "names will be fetched from 'mysql' database"
@@ -675,10 +676,10 @@ class Enumeration:
infoMsg = "fetching database names"
logger.info(infoMsg)
rootQuery = queries[kb.dbms].dbs
rootQuery = queries[getIdentifiedDBMS()].dbs
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.inband.query2
else:
query = rootQuery.inband.query
@@ -691,7 +692,7 @@ class Enumeration:
infoMsg = "fetching number of databases"
logger.info(infoMsg)
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.blind.count2
else:
query = rootQuery.blind.count
@@ -704,9 +705,9 @@ class Enumeration:
indexRange = getRange(count)
for index in indexRange:
if kb.dbms == DBMS.SYBASE:
if getIdentifiedDBMS() == DBMS.SYBASE:
query = rootQuery.blind.query % (kb.data.cachedDbs[-1] if kb.data.cachedDbs else " ")
elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
elif getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.blind.query2 % index
else:
query = rootQuery.blind.query % index
@@ -726,13 +727,13 @@ class Enumeration:
self.forceDbmsEnum()
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
errMsg = "information_schema not available, "
errMsg += "back-end DBMS is MySQL < 5.0"
logger.error(errMsg)
bruteForce = True
elif kb.dbms == DBMS.ACCESS:
elif getIdentifiedDBMS() == DBMS.ACCESS:
errMsg = "cannot retrieve table names, "
errMsg += "back-end DBMS is Access"
logger.error(errMsg)
@@ -771,7 +772,7 @@ class Enumeration:
infoMsg += " for database '%s'" % conf.db
logger.info(infoMsg)
rootQuery = queries[kb.dbms].tables
rootQuery = queries[getIdentifiedDBMS()].tables
if conf.db:
if "," in conf.db:
@@ -789,7 +790,7 @@ class Enumeration:
condition = rootQuery.inband.condition if 'condition' in rootQuery.inband else None
if condition:
if conf.db and kb.dbms != DBMS.SQLITE:
if conf.db and getIdentifiedDBMS() != DBMS.SQLITE:
if "," in conf.db:
dbs = conf.db.split(",")
query += " WHERE "
@@ -802,12 +803,12 @@ class Enumeration:
infoMsg = "skipping system databases '%s'" % ", ".join(db for db in self.excludeDbsList)
logger.info(infoMsg)
if kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
if getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
query = safeStringFormat(query, conf.db)
value = inject.getValue(query, blind=False, error=False)
if value:
if kb.dbms == DBMS.SQLITE:
if getIdentifiedDBMS() == DBMS.SQLITE:
if isinstance(value, basestring):
value = [[ DBMS.SQLITE, value ]]
elif isinstance(value, (list, tuple, set)):
@@ -836,7 +837,7 @@ class Enumeration:
infoMsg += "database '%s'" % db
logger.info(infoMsg)
if kb.dbms in (DBMS.SQLITE, DBMS.FIREBIRD, DBMS.MAXDB):
if getIdentifiedDBMS() in (DBMS.SQLITE, DBMS.FIREBIRD, DBMS.MAXDB):
query = rootQuery.blind.count
else:
query = rootQuery.blind.count % db
@@ -850,18 +851,18 @@ class Enumeration:
tables = []
if kb.dbms in ( DBMS.MSSQL, DBMS.ORACLE ):
if getIdentifiedDBMS() in ( DBMS.MSSQL, DBMS.ORACLE ):
plusOne = True
else:
plusOne = False
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
if kb.dbms == DBMS.SYBASE:
if getIdentifiedDBMS() == DBMS.SYBASE:
query = rootQuery.blind.query % (db, (kb.data.cachedTables[-1] if kb.data.cachedTables else " "))
elif kb.dbms == DBMS.MAXDB:
elif getIdentifiedDBMS() == DBMS.MAXDB:
query = rootQuery.blind.query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")
elif kb.dbms in (DBMS.SQLITE, DBMS.FIREBIRD):
elif getIdentifiedDBMS() in (DBMS.SQLITE, DBMS.FIREBIRD):
query = rootQuery.blind.query % index
else:
query = rootQuery.blind.query % (db, index)
@@ -902,13 +903,13 @@ class Enumeration:
conf.db = self.getCurrentDb()
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
errMsg = "information_schema not available, "
errMsg += "back-end DBMS is MySQL < 5.0"
logger.error(errMsg)
bruteForce = True
elif kb.dbms == DBMS.ACCESS:
elif getIdentifiedDBMS() == DBMS.ACCESS:
errMsg = "cannot retrieve column names, "
errMsg += "back-end DBMS is Access"
logger.error(errMsg)
@@ -959,13 +960,13 @@ class Enumeration:
"37":"VARCHAR"
}
rootQuery = queries[kb.dbms].columns
rootQuery = queries[getIdentifiedDBMS()].columns
condition = rootQuery.blind.condition if 'condition' in rootQuery.blind else None
infoMsg = "fetching columns "
if conf.col:
if kb.dbms == DBMS.ORACLE:
if getIdentifiedDBMS() == DBMS.ORACLE:
conf.col = conf.col.upper()
colList = conf.col.split(",")
condQuery = " AND (" + " OR ".join("%s LIKE '%s'" % (condition, "%" + col + "%") for col in colList) + ")"
@@ -978,24 +979,24 @@ class Enumeration:
logger.info(infoMsg)
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
query = rootQuery.inband.query % (conf.tbl, conf.db)
query += condQuery
elif kb.dbms == DBMS.ORACLE:
elif getIdentifiedDBMS() == DBMS.ORACLE:
query = rootQuery.inband.query % conf.tbl.upper()
query += condQuery
elif kb.dbms == DBMS.MSSQL:
elif getIdentifiedDBMS() == DBMS.MSSQL:
query = rootQuery.inband.query % (conf.db, conf.db,
conf.db, conf.db,
conf.db, conf.db,
conf.db, conf.tbl)
query += condQuery.replace("[DB]", conf.db)
elif kb.dbms == DBMS.SQLITE:
elif getIdentifiedDBMS() == DBMS.SQLITE:
query = rootQuery.inband.query % conf.tbl
value = inject.getValue(query, blind=False, error=False)
if kb.dbms == DBMS.SQLITE:
if getIdentifiedDBMS() == DBMS.SQLITE:
parseSqliteTableSchema(value)
elif value:
table = {}
@@ -1013,19 +1014,19 @@ class Enumeration:
infoMsg += " on database '%s'" % conf.db
logger.info(infoMsg)
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
query = rootQuery.blind.count % (conf.tbl, conf.db)
query += condQuery
elif kb.dbms == DBMS.ORACLE:
elif getIdentifiedDBMS() == DBMS.ORACLE:
query = rootQuery.blind.count % conf.tbl.upper()
query += condQuery
elif kb.dbms == DBMS.MSSQL:
elif getIdentifiedDBMS() == DBMS.MSSQL:
query = rootQuery.blind.count % (conf.db, conf.db, conf.tbl)
query += condQuery.replace("[DB]", conf.db)
elif kb.dbms == DBMS.FIREBIRD:
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
query = rootQuery.blind.count % (conf.tbl)
query += condQuery
elif kb.dbms == DBMS.SQLITE:
elif getIdentifiedDBMS() == DBMS.SQLITE:
query = rootQuery.blind.query % conf.tbl
value = inject.getValue(query, inband=False)
@@ -1047,22 +1048,22 @@ class Enumeration:
indexRange = getRange(count)
for index in indexRange:
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
query = rootQuery.blind.query % (conf.tbl, conf.db)
query += condQuery
field = None
elif kb.dbms == DBMS.ORACLE:
elif getIdentifiedDBMS() == DBMS.ORACLE:
query = rootQuery.blind.query % (conf.tbl.upper())
query += condQuery
field = None
elif kb.dbms == DBMS.MSSQL:
elif getIdentifiedDBMS() == DBMS.MSSQL:
query = rootQuery.blind.query % (conf.db, conf.db,
conf.db, conf.db,
conf.db, conf.db,
conf.tbl)
query += condQuery.replace("[DB]", conf.db)
field = condition.replace("[DB]", conf.db)
elif kb.dbms == DBMS.FIREBIRD:
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
query = rootQuery.blind.query % (conf.tbl)
query += condQuery
field = None
@@ -1071,20 +1072,20 @@ class Enumeration:
column = inject.getValue(query, inband=False)
if not onlyColNames:
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
query = rootQuery.blind.query2 % (conf.tbl, column, conf.db)
elif kb.dbms == DBMS.ORACLE:
elif getIdentifiedDBMS() == DBMS.ORACLE:
query = rootQuery.blind.query2 % (conf.tbl.upper(), column)
elif kb.dbms == DBMS.MSSQL:
elif getIdentifiedDBMS() == DBMS.MSSQL:
query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db,
conf.db, column, conf.db,
conf.db, conf.db, conf.tbl)
elif kb.dbms == DBMS.FIREBIRD:
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
query = rootQuery.blind.query2 % (conf.tbl, column)
colType = inject.getValue(query, inband=False)
if kb.dbms == DBMS.FIREBIRD:
if getIdentifiedDBMS() == DBMS.FIREBIRD:
colType = firebirdTypes[colType] if colType in firebirdTypes else colType
columns[column] = colType
@@ -1130,9 +1131,9 @@ class Enumeration:
conf.db = self.getCurrentDb()
rootQuery = queries[kb.dbms].dump_table
rootQuery = queries[getIdentifiedDBMS()].dump_table
if kb.dbms == DBMS.MYSQL:
if getIdentifiedDBMS() == DBMS.MYSQL:
if '-' in conf.tbl:
conf.tbl = "`%s`" % conf.tbl
if '-' in conf.db:
@@ -1175,9 +1176,9 @@ class Enumeration:
entriesCount = 0
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
if kb.dbms == DBMS.ORACLE:
if getIdentifiedDBMS() == DBMS.ORACLE:
query = rootQuery.inband.query % (colString, conf.tbl.upper())
elif kb.dbms == DBMS.SQLITE:
elif getIdentifiedDBMS() == DBMS.SQLITE:
query = rootQuery.inband.query % (colString, conf.tbl)
else:
query = rootQuery.inband.query % (colString, conf.db, conf.tbl)
@@ -1223,9 +1224,9 @@ class Enumeration:
infoMsg += "on database '%s'" % conf.db
logger.info(infoMsg)
if kb.dbms == DBMS.ORACLE:
if getIdentifiedDBMS() == DBMS.ORACLE:
query = rootQuery.blind.count % conf.tbl.upper()
elif kb.dbms in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
elif getIdentifiedDBMS() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
query = rootQuery.blind.count % conf.tbl
else:
query = rootQuery.blind.count % (conf.db, conf.tbl)
@@ -1245,14 +1246,14 @@ class Enumeration:
lengths = {}
entries = {}
if kb.dbms in (DBMS.ORACLE, DBMS.MSSQL, DBMS.SYBASE):
if getIdentifiedDBMS() in (DBMS.ORACLE, DBMS.MSSQL, DBMS.SYBASE):
plusOne = True
else:
plusOne = False
indexRange = getRange(count, dump=True, plusOne=plusOne)
try:
if kb.dbms == DBMS.ACCESS:
if getIdentifiedDBMS() == DBMS.ACCESS:
validColumnList = False
validPivotValue = False
@@ -1329,22 +1330,22 @@ class Enumeration:
if column not in entries:
entries[column] = []
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
query = rootQuery.blind.query % (column, conf.db,
conf.tbl, index)
elif kb.dbms == DBMS.ORACLE:
elif getIdentifiedDBMS() == DBMS.ORACLE:
query = rootQuery.blind.query % (column, column,
conf.tbl.upper(),
index)
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
query = rootQuery.blind.query % (column, index, conf.db,
conf.tbl, colList[0],
colList[0], colList[0])
elif kb.dbms == DBMS.SQLITE:
elif getIdentifiedDBMS() == DBMS.SQLITE:
query = rootQuery.blind.query % (column, conf.tbl, index)
elif kb.dbms == DBMS.FIREBIRD:
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
query = rootQuery.blind.query % (index, column, conf.tbl)
value = inject.getValue(query, inband=False)
@@ -1388,7 +1389,7 @@ class Enumeration:
return kb.data.dumpedTable
def dumpAll(self):
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
errMsg = "information_schema not available, "
errMsg += "back-end DBMS is MySQL < 5.0"
raise sqlmapUnsupportedFeatureException, errMsg
@@ -1489,10 +1490,10 @@ class Enumeration:
def searchDb(self):
foundDbs = []
rootQuery = queries[kb.dbms].search_db
rootQuery = queries[getIdentifiedDBMS()].search_db
dbList = conf.db.split(",")
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
dbCond = rootQuery.inband.condition2
else:
dbCond = rootQuery.inband.condition
@@ -1517,7 +1518,7 @@ class Enumeration:
dbQuery = dbQuery % db
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.inband.query2
else:
query = rootQuery.inband.query
@@ -1538,7 +1539,7 @@ class Enumeration:
infoMsg += " '%s'" % db
logger.info(infoMsg)
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.blind.count2
else:
query = rootQuery.blind.count
@@ -1558,7 +1559,7 @@ class Enumeration:
indexRange = getRange(count)
for index in indexRange:
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
query = rootQuery.blind.query2
else:
query = rootQuery.blind.query
@@ -1573,12 +1574,12 @@ class Enumeration:
def searchTable(self):
bruteForce = False
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
errMsg = "information_schema not available, "
errMsg += "back-end DBMS is MySQL < 5.0"
bruteForce = True
elif kb.dbms == DBMS.ACCESS:
elif getIdentifiedDBMS() == DBMS.ACCESS:
errMsg = "cannot retrieve table names, "
errMsg += "back-end DBMS is Access"
logger.error(errMsg)
@@ -1596,7 +1597,7 @@ class Enumeration:
regex = "|".join(conf.tbl.split(","))
return tableExists(paths.COMMON_TABLES, regex)
rootQuery = queries[kb.dbms].search_table
rootQuery = queries[getIdentifiedDBMS()].search_table
foundTbls = {}
tblList = conf.tbl.split(",")
tblCond = rootQuery.inband.condition
@@ -1605,7 +1606,7 @@ class Enumeration:
tblConsider, tblCondParam = self.likeOrExact("table")
for tbl in tblList:
if kb.dbms == DBMS.ORACLE:
if getIdentifiedDBMS() == DBMS.ORACLE:
tbl = tbl.upper()
infoMsg = "searching table"
@@ -1715,12 +1716,12 @@ class Enumeration:
def searchColumn(self):
bruteForce = False
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
errMsg = "information_schema not available, "
errMsg += "back-end DBMS is MySQL < 5.0"
bruteForce = True
elif kb.dbms == DBMS.ACCESS:
elif getIdentifiedDBMS() == DBMS.ACCESS:
errMsg = "cannot retrieve column names, "
errMsg += "back-end DBMS is Access"
logger.error(errMsg)
@@ -1746,7 +1747,7 @@ class Enumeration:
return
rootQuery = queries[kb.dbms].search_column
rootQuery = queries[getIdentifiedDBMS()].search_column
foundCols = {}
dbs = {}
colList = conf.col.split(",")
@@ -1958,7 +1959,7 @@ class Enumeration:
return output
def sqlShell(self):
infoMsg = "calling %s shell. To quit type " % kb.dbms
infoMsg = "calling %s shell. To quit type " % getIdentifiedDBMS()
infoMsg += "'x' or 'q' and press ENTER"
logger.info(infoMsg)

View File

@@ -13,6 +13,7 @@ import os
from lib.core.agent import agent
from lib.core.common import dataToOutFile
from lib.core.common import getIdentifiedDBMS
from lib.core.common import isTechniqueAvailable
from lib.core.common import randomStr
from lib.core.common import readInput
@@ -86,13 +87,13 @@ class Filesystem:
return fileLines
def __checkWrittenFile(self, wFile, dFile, fileType):
if kb.dbms == DBMS.MYSQL:
if getIdentifiedDBMS() == DBMS.MYSQL:
lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % dFile
elif kb.dbms == DBMS.PGSQL:
elif getIdentifiedDBMS() == DBMS.PGSQL:
lengthQuery = "SELECT LENGTH(data) FROM pg_largeobject WHERE loid=%d" % self.oid
elif kb.dbms == DBMS.MSSQL:
elif getIdentifiedDBMS() == DBMS.MSSQL:
self.createSupportTbl(self.fileTblName, self.tblField, "text")
# Reference: http://msdn.microsoft.com/en-us/library/ms188365.aspx
@@ -270,7 +271,7 @@ class Filesystem:
fileContent = self.unionReadFile(rFile)
if fileContent in ( None, "" ) and kb.dbms != "PostgreSQL":
if fileContent in ( None, "" ) and getIdentifiedDBMS() != DBMS.PGSQL:
self.cleanup(onlyFileTbl=True)
return
@@ -288,7 +289,7 @@ class Filesystem:
fileContent = self.__unhexString(fileContent)
rFilePath = dataToOutFile(fileContent)
if kb.dbms != "PostgreSQL":
if getIdentifiedDBMS() != DBMS.PGSQL:
self.cleanup(onlyFileTbl=True)
return rFilePath

View File

@@ -10,6 +10,7 @@ See the file 'doc/COPYING' for copying permission
import re
from lib.core.common import getCompiledRegex
from lib.core.common import getIdentifiedDBMS
from lib.core.common import isTechniqueAvailable
from lib.core.common import normalizePath
from lib.core.common import ntToPosixSlashes
@@ -56,19 +57,19 @@ class Miscellaneous:
infoMsg = "detecting back-end DBMS version from its banner"
logger.info(infoMsg)
if kb.dbms == DBMS.MYSQL:
if getIdentifiedDBMS() == DBMS.MYSQL:
first, last = 1, 6
elif kb.dbms == DBMS.PGSQL:
elif getIdentifiedDBMS() == DBMS.PGSQL:
first, last = 12, 6
elif kb.dbms == DBMS.MSSQL:
elif getIdentifiedDBMS() == DBMS.MSSQL:
first, last = 29, 9
else:
raise sqlmapUnsupportedFeatureException, "unsupported DBMS"
query = queries[kb.dbms].substring.query % (queries[kb.dbms].banner.query, first, last)
query = queries[getIdentifiedDBMS()].substring.query % (queries[getIdentifiedDBMS()].banner.query, first, last)
if conf.direct:
query = "SELECT %s" % query
@@ -119,7 +120,7 @@ class Miscellaneous:
if not onlyFileTbl:
inject.goStacked("DROP TABLE %s" % self.cmdTblName, silent=True)
if kb.dbms == DBMS.MSSQL:
if getIdentifiedDBMS() == DBMS.MSSQL:
return
if udfDict is None:
@@ -132,7 +133,7 @@ class Miscellaneous:
if not output or output in ("y", "Y"):
dropStr = "DROP FUNCTION %s" % udf
if kb.dbms == DBMS.PGSQL:
if getIdentifiedDBMS() == DBMS.PGSQL:
inp = ", ".join(i for i in inpRet["input"])
dropStr += "(%s)" % inp

View File

@@ -9,6 +9,7 @@ See the file 'doc/COPYING' for copying permission
import os
from lib.core.common import getIdentifiedDBMS
from lib.core.common import isTechniqueAvailable
from lib.core.common import readInput
from lib.core.common import runningAsAdmin
@@ -44,7 +45,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
def osCmd(self):
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
web = False
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and kb.dbms == DBMS.MYSQL:
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and getIdentifiedDBMS() == DBMS.MYSQL:
infoMsg = "going to use a web backdoor for command execution"
logger.info(infoMsg)
@@ -65,7 +66,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
def osShell(self):
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
web = False
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and kb.dbms == DBMS.MYSQL:
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and getIdentifiedDBMS() == DBMS.MYSQL:
infoMsg = "going to use a web backdoor for command prompt"
logger.info(infoMsg)
@@ -148,7 +149,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
errMsg += "is unlikely to receive commands send from you"
logger.error(errMsg)
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
self.sysUdfs.pop("sys_bineval")
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
@@ -158,7 +159,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
self.initEnv(web=web)
if tunnel == 1:
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
msg = "how do you want to execute the Metasploit shellcode "
msg += "on the back-end database underlying operating system?"
msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
@@ -188,7 +189,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
self.uploadMsfPayloadStager()
if kb.os == "Windows" and conf.privEsc:
if kb.dbms == DBMS.MYSQL:
if getIdentifiedDBMS() == DBMS.MYSQL:
debugMsg = "by default MySQL on Windows runs as SYSTEM "
debugMsg += "user, no need to privilege escalate"
logger.debug(debugMsg)
@@ -206,7 +207,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
self.uploadIcmpshSlave(web=web)
self.icmpPwn()
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and kb.dbms == DBMS.MYSQL:
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and getIdentifiedDBMS() == DBMS.MYSQL:
web = True
infoMsg = "going to use a web backdoor to establish the tunnel"
@@ -255,13 +256,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
raise sqlmapUnsupportedDBMSException(errMsg)
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
if kb.dbms in ( DBMS.PGSQL, DBMS.MSSQL ):
if getIdentifiedDBMS() in ( DBMS.PGSQL, DBMS.MSSQL ):
errMsg = "on this back-end DBMS it is only possible to "
errMsg += "perform the SMB relay attack if stacked "
errMsg += "queries are supported"
raise sqlmapUnsupportedDBMSException(errMsg)
elif kb.dbms == DBMS.MYSQL:
elif getIdentifiedDBMS() == DBMS.MYSQL:
debugMsg = "since stacked queries are not supported, "
debugMsg += "sqlmap is going to perform the SMB relay "
debugMsg += "attack via inference blind SQL injection"
@@ -270,18 +271,18 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
printWarn = True
warnMsg = "it is unlikely that this attack will be successful "
if kb.dbms == DBMS.MYSQL:
if getIdentifiedDBMS() == DBMS.MYSQL:
warnMsg += "because by default MySQL on Windows runs as "
warnMsg += "Local System which is not a real user, it does "
warnMsg += "not send the NTLM session hash when connecting to "
warnMsg += "a SMB service"
elif kb.dbms == DBMS.PGSQL:
elif getIdentifiedDBMS() == DBMS.PGSQL:
warnMsg += "because by default PostgreSQL on Windows runs "
warnMsg += "as postgres user which is a real user of the "
warnMsg += "system, but not within the Administrators group"
elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
elif getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
warnMsg += "because often Microsoft SQL Server %s " % kb.dbmsVersion[0]
warnMsg += "runs as Network Service which is not a real user, "
warnMsg += "it does not send the NTLM session hash when "
@@ -299,7 +300,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
return
if not kb.dbms == DBMS.MSSQL or kb.dbmsVersion[0] not in ( "2000", "2005" ):
if not getIdentifiedDBMS() == DBMS.MSSQL or kb.dbmsVersion[0] not in ( "2000", "2005" ):
errMsg = "the back-end DBMS must be Microsoft SQL Server "
errMsg += "2000 or 2005 to be able to exploit the heap-based "
errMsg += "buffer overflow in the 'sp_replwritetovarbin' "