mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-02-03 05:04:11 +03:00
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:
parent
a1d1f69c3f
commit
2ac8debea0
|
@ -12,6 +12,7 @@ import socket
|
|||
import time
|
||||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import aliasToDbmsEnum
|
||||
from lib.core.common import beep
|
||||
from lib.core.common import extractRegexResult
|
||||
from lib.core.common import findDynamicContent
|
||||
|
@ -430,7 +431,7 @@ def checkSqlInjection(place, parameter, value):
|
|||
for detailKey, detailValue in test.details.items():
|
||||
if detailKey == "dbms" and injection.dbms is None:
|
||||
injection.dbms = detailValue
|
||||
kb.dbms = detailValue
|
||||
kb.dbms = aliasToDbmsEnum(detailValue)
|
||||
elif detailKey == "dbms_version" and injection.dbms_version is None:
|
||||
injection.dbms_version = detailValue
|
||||
kb.dbmsVersion = [ detailValue ]
|
||||
|
|
|
@ -7,7 +7,7 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
|||
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 pushValue
|
||||
from lib.core.data import conf
|
||||
|
@ -63,18 +63,11 @@ def setHandler():
|
|||
( SYBASE_ALIASES, SybaseMap, SybaseConn ),
|
||||
]
|
||||
|
||||
inferencedDbms = (getErrorParsedDBMSes()[0] if getErrorParsedDBMSes() else '') or kb.dbms
|
||||
|
||||
for injection in kb.injections:
|
||||
if hasattr(injection, "dbms") and injection.dbms:
|
||||
inferencedDbms = injection.dbms
|
||||
break
|
||||
|
||||
if inferencedDbms is not None:
|
||||
if getIdentifiedDBMS() is not None:
|
||||
for i in xrange(len(dbmsObj)):
|
||||
dbmsAliases, _, _ = dbmsObj[i]
|
||||
|
||||
if inferencedDbms.lower() in dbmsAliases:
|
||||
if getIdentifiedDBMS().lower() in dbmsAliases:
|
||||
if i > 0:
|
||||
pushValue(dbmsObj[i])
|
||||
dbmsObj.remove(dbmsObj[i])
|
||||
|
|
|
@ -13,6 +13,7 @@ from xml.etree import ElementTree as ET
|
|||
|
||||
from lib.core.common import getCompiledRegex
|
||||
from lib.core.common import getErrorParsedDBMSes
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import isDBMSVersionAtLeast
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
from lib.core.common import randomInt
|
||||
|
@ -33,13 +34,6 @@ class Agent:
|
|||
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):
|
||||
if query.startswith("AND "):
|
||||
query = query.replace("AND ", "SELECT ", 1)
|
||||
|
@ -211,8 +205,8 @@ class Agent:
|
|||
payload = payload.replace("[ORIGVALUE]", origvalue)
|
||||
|
||||
if "[INFERENCE]" in payload:
|
||||
if kb.dbms is not None:
|
||||
inference = queries[kb.dbms].inference
|
||||
if getIdentifiedDBMS() is not None:
|
||||
inference = queries[getIdentifiedDBMS()].inference
|
||||
|
||||
if "dbms_version" in inference:
|
||||
if isDBMSVersionAtLeast(inference.dbms_version):
|
||||
|
@ -223,11 +217,6 @@ class Agent:
|
|||
inferenceQuery = inference.query
|
||||
|
||||
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:
|
||||
errMsg = "invalid usage of inference payload without "
|
||||
errMsg += "knowledge of underlying DBMS"
|
||||
|
@ -275,17 +264,17 @@ class Agent:
|
|||
|
||||
# SQLite version 2 does not support neither CAST() nor IFNULL(),
|
||||
# introduced only in SQLite version 3
|
||||
if kb.dbms == DBMS.SQLITE:
|
||||
if getIdentifiedDBMS() == DBMS.SQLITE:
|
||||
return field
|
||||
|
||||
if field.startswith("(CASE"):
|
||||
nulledCastedField = field
|
||||
else:
|
||||
nulledCastedField = queries[kb.dbms].cast.query % field
|
||||
if kb.dbms == DBMS.ACCESS:
|
||||
nulledCastedField = queries[kb.dbms].isnull.query % (nulledCastedField, nulledCastedField)
|
||||
nulledCastedField = queries[getIdentifiedDBMS()].cast.query % field
|
||||
if getIdentifiedDBMS() == DBMS.ACCESS:
|
||||
nulledCastedField = queries[getIdentifiedDBMS()].isnull.query % (nulledCastedField, nulledCastedField)
|
||||
else:
|
||||
nulledCastedField = queries[kb.dbms].isnull.query % nulledCastedField
|
||||
nulledCastedField = queries[getIdentifiedDBMS()].isnull.query % nulledCastedField
|
||||
|
||||
return nulledCastedField
|
||||
|
||||
|
@ -324,7 +313,7 @@ class Agent:
|
|||
|
||||
fields = fields.replace(", ", ",")
|
||||
fieldsSplitted = fields.split(",")
|
||||
dbmsDelimiter = queries[kb.dbms].delimiter.query
|
||||
dbmsDelimiter = queries[getIdentifiedDBMS()].delimiter.query
|
||||
nulledCastedFields = []
|
||||
|
||||
for field in fieldsSplitted:
|
||||
|
@ -383,13 +372,13 @@ class Agent:
|
|||
def simpleConcatQuery(self, query1, query2):
|
||||
concatenatedQuery = ""
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
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)
|
||||
|
||||
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
concatenatedQuery = "%s+%s" % (query1, query2)
|
||||
|
||||
return concatenatedQuery
|
||||
|
@ -431,7 +420,7 @@ class Agent:
|
|||
concatenatedQuery = query
|
||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
if fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
||||
concatenatedQuery += ",'%s')" % kb.misc.stop
|
||||
|
@ -444,7 +433,7 @@ class Agent:
|
|||
elif fieldsNoSelect:
|
||||
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:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.misc.stop
|
||||
|
@ -457,10 +446,10 @@ class Agent:
|
|||
elif fieldsNoSelect:
|
||||
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"
|
||||
|
||||
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
if fieldsSelectTop:
|
||||
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)
|
||||
|
@ -511,13 +500,13 @@ class Agent:
|
|||
"""
|
||||
|
||||
if query.startswith("SELECT "):
|
||||
query = query[len("SELECT "):]
|
||||
query = query[len("SELECT "):]
|
||||
|
||||
inbandQuery = self.prefixQuery("UNION ALL SELECT ", prefix=prefix)
|
||||
|
||||
if query.startswith("TOP"):
|
||||
topNum = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1)
|
||||
query = query[len("TOP %s " % topNum):]
|
||||
topNum = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1)
|
||||
query = query[len("TOP %s " % topNum):]
|
||||
inbandQuery += "TOP %s " % topNum
|
||||
|
||||
intoRegExp = re.search("(\s+INTO (DUMP|OUT)FILE\s+\'(.+?)\')", query, re.I)
|
||||
|
@ -526,7 +515,7 @@ class Agent:
|
|||
intoRegExp = intoRegExp.group(1)
|
||||
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")]
|
||||
|
||||
for element in range(count):
|
||||
|
@ -546,7 +535,7 @@ class Agent:
|
|||
conditionIndex = query.index(" FROM ")
|
||||
inbandQuery += query[conditionIndex:]
|
||||
|
||||
if kb.dbms == DBMS.ORACLE or DBMS.ORACLE in getErrorParsedDBMSes():
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
if " FROM " not in inbandQuery:
|
||||
inbandQuery += " FROM DUAL"
|
||||
|
||||
|
@ -565,7 +554,7 @@ class Agent:
|
|||
else:
|
||||
inbandQuery += char
|
||||
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
inbandQuery += " FROM DUAL"
|
||||
|
||||
inbandQuery = self.suffixQuery(inbandQuery, comment, suffix)
|
||||
|
@ -595,21 +584,21 @@ class Agent:
|
|||
"""
|
||||
|
||||
limitedQuery = query
|
||||
limitStr = queries[kb.dbms].limit.query
|
||||
limitStr = queries[getIdentifiedDBMS()].limit.query
|
||||
fromIndex = limitedQuery.index(" FROM ")
|
||||
untilFrom = limitedQuery[:fromIndex]
|
||||
fromFrom = limitedQuery[fromIndex+1:]
|
||||
orderBy = False
|
||||
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE ):
|
||||
limitStr = queries[kb.dbms].limit.query % (num, 1)
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE ):
|
||||
limitStr = queries[getIdentifiedDBMS()].limit.query % (num, 1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
limitStr = queries[kb.dbms].limit.query % (num+1, num+1)
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
limitStr = queries[getIdentifiedDBMS()].limit.query % (num+1, num+1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery:
|
||||
orderBy = limitedQuery[limitedQuery.index(" ORDER BY "):]
|
||||
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
||||
|
@ -621,7 +610,7 @@ class Agent:
|
|||
limitedQuery = limitedQuery % fromFrom
|
||||
limitedQuery += "=%d" % (num + 1)
|
||||
|
||||
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
forgeNotIn = True
|
||||
|
||||
if " ORDER BY " in limitedQuery:
|
||||
|
@ -635,7 +624,7 @@ class Agent:
|
|||
limitedQuery = limitedQuery.replace("DISTINCT %s" % notDistinct, notDistinct)
|
||||
|
||||
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:
|
||||
topNums = topNums.groups()
|
||||
|
@ -681,7 +670,7 @@ class Agent:
|
|||
@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):
|
||||
"""
|
||||
|
|
|
@ -218,15 +218,15 @@ def formatDBMSfp(versions=None):
|
|||
versions = kb.dbmsVersion
|
||||
|
||||
if isinstance(versions, basestring):
|
||||
return "%s %s" % (kb.dbms, versions)
|
||||
return "%s %s" % (getIdentifiedDBMS(), versions)
|
||||
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:
|
||||
warnMsg = "unable to extensively fingerprint the back-end "
|
||||
warnMsg += "DBMS version"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return kb.dbms
|
||||
return getIdentifiedDBMS()
|
||||
|
||||
def formatFingerprintString(values, chain=" or "):
|
||||
strJoin = "|".join([v for v in values])
|
||||
|
@ -627,7 +627,7 @@ def parsePasswordHash(password):
|
|||
if not password or password == " ":
|
||||
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
|
||||
password = "%s\n" % hexPassword
|
||||
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):
|
||||
query = None
|
||||
|
||||
if kb.dbms in (DBMS.MYSQL, DBMS.PGSQL):
|
||||
if getIdentifiedDBMS() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||
if not kb.data.banner:
|
||||
conf.dbmsHandler.getVersionFromBanner()
|
||||
|
||||
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"):
|
||||
query = queries[kb.dbms].timedelay.query % conf.timeSec
|
||||
if banVer is None or (getIdentifiedDBMS() == DBMS.MYSQL and banVer >= "5.0.12") or (getIdentifiedDBMS() == DBMS.PGSQL and banVer >= "8.2"):
|
||||
query = queries[getIdentifiedDBMS()].timedelay.query % conf.timeSec
|
||||
else:
|
||||
query = queries[kb.dbms].timedelay.query2 % conf.timeSec
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
query = queries[kb.dbms].timedelay.query
|
||||
query = queries[getIdentifiedDBMS()].timedelay.query2 % conf.timeSec
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
query = queries[getIdentifiedDBMS()].timedelay.query
|
||||
else:
|
||||
query = queries[kb.dbms].timedelay.query % conf.timeSec
|
||||
query = queries[getIdentifiedDBMS()].timedelay.query % conf.timeSec
|
||||
|
||||
if andCond:
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.SQLITE ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.SQLITE ):
|
||||
query = query.replace("SELECT ", "")
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
query = "(%s)>0" % query
|
||||
|
||||
return query
|
||||
|
@ -1763,7 +1763,7 @@ def aliasToDbmsEnum(value):
|
|||
retVal = None
|
||||
|
||||
for key, item in dbmsDict.items():
|
||||
if value in item[0]:
|
||||
if value.lower() in item[0]:
|
||||
retVal = key
|
||||
break
|
||||
|
||||
|
@ -2040,6 +2040,18 @@ def getErrorParsedDBMSes():
|
|||
|
||||
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():
|
||||
"""
|
||||
Shows all HTTP error codes raised till now
|
||||
|
|
|
@ -31,7 +31,7 @@ class DBMS:
|
|||
MSSQL = "Microsoft SQL Server"
|
||||
MYSQL = "MySQL"
|
||||
ORACLE = "Oracle"
|
||||
PGSQL = "PostgreSQL"
|
||||
PGSQL = "PostgreSQL"
|
||||
SQLITE = "SQLite"
|
||||
SYBASE = "Sybase"
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ from lib.core.common import parseTargetDirect
|
|||
from lib.core.common import parseTargetUrl
|
||||
from lib.core.common import paths
|
||||
from lib.core.common import randomRange
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import readCachedFileContent
|
||||
from lib.core.common import readInput
|
||||
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.datatype import advancedDict
|
||||
from lib.core.datatype import injectionDict
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import HTTPMETHOD
|
||||
from lib.core.enums import PAYLOAD
|
||||
from lib.core.enums import PRIORITY
|
||||
|
@ -1165,6 +1167,12 @@ def __setKnowledgeBaseAttributes(flushAll=True):
|
|||
kb.threadException = False
|
||||
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:
|
||||
kb.keywords = set(getFileItems(paths.SQL_KEYWORDS))
|
||||
kb.tamperFunctions = []
|
||||
|
|
|
@ -13,6 +13,7 @@ from lib.core.common import aliasToDbmsEnum
|
|||
from lib.core.common import dataToSessionFile
|
||||
from lib.core.common import formatFingerprintString
|
||||
from lib.core.common import getFilteredPageContent
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import readInput
|
||||
from lib.core.convert import base64pickle
|
||||
from lib.core.convert import base64unpickle
|
||||
|
@ -140,7 +141,7 @@ def setDbms(dbms):
|
|||
if dbmsRegExp:
|
||||
dbms = dbmsRegExp.group(1)
|
||||
|
||||
kb.dbms = dbms
|
||||
kb.dbms = aliasToDbmsEnum(dbms)
|
||||
|
||||
logger.info("the back-end DBMS is %s" % kb.dbms)
|
||||
|
||||
|
@ -340,7 +341,7 @@ def resumeConfKb(expression, url, value):
|
|||
if '.' in table:
|
||||
db, table = table.split('.')
|
||||
else:
|
||||
db = "%s%s" % (kb.dbms, METADB_SUFFIX)
|
||||
db = "%s%s" % (getIdentifiedDBMS(), METADB_SUFFIX)
|
||||
|
||||
logMsg = "resuming brute forced table name "
|
||||
logMsg += "'%s' from session file" % table
|
||||
|
@ -355,7 +356,7 @@ def resumeConfKb(expression, url, value):
|
|||
if '.' in table:
|
||||
db, table = table.split('.')
|
||||
else:
|
||||
db = "%s%s" % (kb.dbms, METADB_SUFFIX)
|
||||
db = "%s%s" % (getIdentifiedDBMS(), METADB_SUFFIX)
|
||||
|
||||
logMsg = "resuming brute forced column name "
|
||||
logMsg += "'%s' for table '%s' from session file" % (colName, table)
|
||||
|
|
|
@ -12,6 +12,7 @@ import os
|
|||
import rlcompleter
|
||||
|
||||
from lib.core import readlineng as readline
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import paths
|
||||
from lib.core.data import queries
|
||||
|
@ -29,7 +30,7 @@ def loadHistory():
|
|||
def queriesForAutoCompletion():
|
||||
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':
|
||||
autoComplQueries[item.query] = None
|
||||
|
||||
|
|
|
@ -7,18 +7,15 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
|||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.common import getErrorParsedDBMSes
|
||||
from lib.core.data import kb
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.datatype import advancedDict
|
||||
|
||||
class Unescaper(advancedDict):
|
||||
def unescape(self, expression, quote=True, dbms=None):
|
||||
if hasattr(kb, "dbms") and kb.dbms is not None:
|
||||
return self[kb.dbms](expression, quote=quote)
|
||||
elif hasattr(kb.misc, "testedDbms") and kb.misc.testedDbms is not None:
|
||||
return self[kb.misc.testedDbms](expression, quote=quote)
|
||||
elif getErrorParsedDBMSes():
|
||||
return self[getErrorParsedDBMSes()[0]](expression, quote=quote)
|
||||
identifiedDbms = getIdentifiedDBMS()
|
||||
|
||||
if identifiedDbms is not None:
|
||||
return self[identifiedDbms](expression, quote=quote)
|
||||
elif dbms is not None:
|
||||
return self[dbms](expression, quote=quote)
|
||||
else:
|
||||
|
|
|
@ -13,6 +13,7 @@ from xml.sax.handler import ContentHandler
|
|||
|
||||
from lib.core.common import checkFile
|
||||
from lib.core.common import getCompiledRegex
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import parseXmlFile
|
||||
from lib.core.common import sanitizeStr
|
||||
from lib.core.data import kb
|
||||
|
@ -94,13 +95,13 @@ def bannerParser(banner):
|
|||
|
||||
xmlfile = None
|
||||
|
||||
if kb.dbms == DBMS.MSSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
xmlfile = paths.MSSQL_XML
|
||||
elif kb.dbms == DBMS.MYSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
xmlfile = paths.MYSQL_XML
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
xmlfile = paths.ORACLE_XML
|
||||
elif kb.dbms == DBMS.PGSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
xmlfile = paths.PGSQL_XML
|
||||
|
||||
if not xmlfile:
|
||||
|
@ -108,7 +109,7 @@ def bannerParser(banner):
|
|||
|
||||
checkFile(xmlfile)
|
||||
|
||||
if kb.dbms == DBMS.MSSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
handler = MSSQLBannerHandler(banner, kb.bannerFp)
|
||||
parseXmlFile(xmlfile, handler)
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ See the file 'doc/COPYING' for copying permission
|
|||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import dataToSessionFile
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.convert import base64pickle
|
||||
from lib.core.convert import base64unpickle
|
||||
|
@ -25,7 +26,7 @@ def direct(query, content=True):
|
|||
select = False
|
||||
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
|
||||
|
||||
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
|
||||
|
|
|
@ -15,6 +15,7 @@ from lib.core.common import calculateDeltaSeconds
|
|||
from lib.core.common import cleanQuery
|
||||
from lib.core.common import dataToSessionFile
|
||||
from lib.core.common import expandAsteriskForColumns
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getPublicTypeMembers
|
||||
from lib.core.common import initTechnique
|
||||
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):
|
||||
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)
|
||||
else:
|
||||
length = None
|
||||
|
@ -160,7 +161,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
|||
_, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression)
|
||||
|
||||
rdbRegExp = re.search("RDB\$GET_CONTEXT\([^)]+\)", expression, re.I)
|
||||
if rdbRegExp and kb.dbms == DBMS.FIREBIRD:
|
||||
if rdbRegExp and getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
expressionFieldsList = [expressionFields]
|
||||
|
||||
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
|
||||
# can return multiple entries
|
||||
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)
|
||||
|
||||
if limitRegExp or ( kb.dbms in (DBMS.MSSQL, DBMS.SYBASE) and topLimit ):
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
limitGroupStart = queries[kb.dbms].limitgroupstart.query
|
||||
limitGroupStop = queries[kb.dbms].limitgroupstop.query
|
||||
if limitRegExp or ( getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
limitGroupStart = queries[getIdentifiedDBMS()].limitgroupstart.query
|
||||
limitGroupStop = queries[getIdentifiedDBMS()].limitgroupstop.query
|
||||
|
||||
if limitGroupStart.isdigit():
|
||||
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))
|
||||
limitCond = int(stopLimit) > 1
|
||||
|
||||
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
if limitRegExp:
|
||||
limitGroupStart = queries[kb.dbms].limitgroupstart.query
|
||||
limitGroupStop = queries[kb.dbms].limitgroupstop.query
|
||||
limitGroupStart = queries[getIdentifiedDBMS()].limitgroupstart.query
|
||||
limitGroupStop = queries[getIdentifiedDBMS()].limitgroupstop.query
|
||||
|
||||
if limitGroupStart.isdigit():
|
||||
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))
|
||||
limitCond = int(stopLimit) > 1
|
||||
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
limitCond = False
|
||||
else:
|
||||
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 "
|
||||
# (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
|
||||
untilLimitChar = expression.index(queries[kb.dbms].limitstring.query)
|
||||
untilLimitChar = expression.index(queries[getIdentifiedDBMS()].limitstring.query)
|
||||
expression = expression[:untilLimitChar]
|
||||
|
||||
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
stopLimit += startLimit
|
||||
|
||||
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"
|
||||
elif batch:
|
||||
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"):
|
||||
# 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)
|
||||
|
||||
if re.search(" ORDER BY ", expression, re.I):
|
||||
|
@ -327,7 +328,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
|||
|
||||
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
|
||||
|
||||
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:
|
||||
return direct(expression), None
|
||||
|
||||
comment = queries[kb.dbms].comment.query
|
||||
comment = queries[getIdentifiedDBMS()].comment.query
|
||||
query = agent.prefixQuery("; %s" % expression)
|
||||
query = agent.suffixQuery("%s;%s" % (query, comment))
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ See the file 'doc/COPYING' for copying permission
|
|||
"""
|
||||
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
from lib.core.common import readInput
|
||||
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):
|
||||
self.webBackdoorRunCmd(cmd)
|
||||
|
||||
elif kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
elif getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
self.udfExecCmd(cmd, silent=silent)
|
||||
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
self.xpCmdshellExecCmd(cmd, silent=silent)
|
||||
|
||||
else:
|
||||
|
@ -54,10 +55,10 @@ class Abstraction(Web, UDF, xp_cmdshell):
|
|||
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||
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)
|
||||
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
return self.xpCmdshellEvalCmd(cmd, first, last)
|
||||
|
||||
else:
|
||||
|
@ -92,13 +93,13 @@ class Abstraction(Web, UDF, xp_cmdshell):
|
|||
logger.info(infoMsg)
|
||||
|
||||
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 += "user-defined functions for operating system "
|
||||
infoMsg += "command execution"
|
||||
logger.info(infoMsg)
|
||||
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
infoMsg = "going to use xp_cmdshell extended procedure for "
|
||||
infoMsg += "operating system command execution"
|
||||
logger.info(infoMsg)
|
||||
|
@ -150,9 +151,9 @@ class Abstraction(Web, UDF, xp_cmdshell):
|
|||
warnMsg += "the session user is not a database administrator"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
self.udfInjectSys()
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
if mandatory:
|
||||
self.xpCmdshellInit()
|
||||
else:
|
||||
|
|
|
@ -19,6 +19,7 @@ from subprocess import PIPE
|
|||
from subprocess import Popen as execute
|
||||
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getLocalIP
|
||||
from lib.core.common import getRemoteIP
|
||||
from lib.core.common import getUnicode
|
||||
|
@ -186,13 +187,13 @@ class Metasploit:
|
|||
if __payloadStr == "windows/vncinject":
|
||||
choose = False
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
debugMsg = "by default MySQL on Windows runs as SYSTEM "
|
||||
debugMsg += "user, it is likely that the the VNC "
|
||||
debugMsg += "injection will be successful"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
elif kb.dbms == DBMS.PGSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
choose = True
|
||||
|
||||
warnMsg = "by default PostgreSQL on Windows runs as "
|
||||
|
@ -200,7 +201,7 @@ class Metasploit:
|
|||
warnMsg += "injection will be successful"
|
||||
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
|
||||
|
||||
warnMsg = "it is unlikely that the VNC injection will be "
|
||||
|
@ -229,12 +230,12 @@ class Metasploit:
|
|||
break
|
||||
|
||||
elif choice == "1":
|
||||
if kb.dbms == DBMS.PGSQL:
|
||||
if getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
logger.warn("beware that the VNC injection might not work")
|
||||
|
||||
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
|
||||
|
||||
elif not choice.isdigit():
|
||||
|
@ -554,7 +555,7 @@ class Metasploit:
|
|||
# This is useful for sqlmap because on PostgreSQL it is not
|
||||
# possible to write files bigger than 8192 bytes abusing the
|
||||
# lo_export() feature implemented in sqlmap.
|
||||
if kb.dbms == DBMS.PGSQL:
|
||||
if getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
self.__fileFormat = "exe-small"
|
||||
else:
|
||||
self.__fileFormat = "exe"
|
||||
|
@ -656,7 +657,7 @@ class Metasploit:
|
|||
self.__forgeMsfConsoleResource()
|
||||
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)
|
||||
else:
|
||||
self.uncPath = "\\\\%s\\%s" % (self.lhostStr, self.__randFile)
|
||||
|
|
|
@ -11,6 +11,7 @@ import os
|
|||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
from lib.core.common import readInput
|
||||
from lib.core.data import conf
|
||||
|
@ -50,7 +51,7 @@ class UDF:
|
|||
def __checkExistUdf(self, 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)
|
||||
|
||||
if exists == "1":
|
||||
|
@ -103,7 +104,7 @@ class UDF:
|
|||
return output
|
||||
|
||||
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")
|
||||
|
||||
if not conf.osPwn:
|
||||
|
@ -142,9 +143,9 @@ class UDF:
|
|||
if udf in self.udfToCreate and udf not in self.createdUdf:
|
||||
self.udfCreateFromSharedLib(udf, inpRet)
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
supportTblType = "longtext"
|
||||
elif kb.dbms == DBMS.PGSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
supportTblType = "text"
|
||||
|
||||
self.udfCreateSupportTbl(supportTblType)
|
||||
|
@ -155,8 +156,8 @@ class UDF:
|
|||
self.udfInjectCore(self.sysUdfs)
|
||||
|
||||
def udfInjectCustom(self):
|
||||
if kb.dbms not in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
errMsg = "UDF injection feature is not yet implemented on %s" % kb.dbms
|
||||
if getIdentifiedDBMS() not in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
errMsg = "UDF injection feature is not yet implemented on %s" % getIdentifiedDBMS()
|
||||
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||
|
||||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
||||
|
@ -235,9 +236,9 @@ class UDF:
|
|||
else:
|
||||
logger.warn("you need to specify the name of the UDF")
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
defaultType = "string"
|
||||
elif kb.dbms == DBMS.PGSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
defaultType = "text"
|
||||
|
||||
self.udfs[udfName]["input"] = []
|
||||
|
|
|
@ -16,6 +16,7 @@ from lib.core.common import dataToSessionFile
|
|||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import filterControlChars
|
||||
from lib.core.common import getCharset
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import goGoodSamaritan
|
||||
from lib.core.common import getPartRun
|
||||
from lib.core.common import popValue
|
||||
|
@ -49,7 +50,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
|||
finalValue = ""
|
||||
asciiTbl = getCharset(charsetType)
|
||||
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
|
||||
# samaritan") is used
|
||||
|
@ -121,7 +121,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
|||
hintlock.release()
|
||||
|
||||
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]
|
||||
else:
|
||||
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
|
||||
if commonPattern is not None:
|
||||
# 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)
|
||||
query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (subquery, testValue)))
|
||||
query = agent.suffixQuery(query)
|
||||
|
|
|
@ -15,6 +15,7 @@ from lib.core.common import dataToSessionFile
|
|||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import filterListValue
|
||||
from lib.core.common import getFileItems
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getPageTextWordsSet
|
||||
from lib.core.common import popValue
|
||||
from lib.core.common import pushValue
|
||||
|
@ -31,7 +32,7 @@ from lib.core.session import safeFormatString
|
|||
from lib.request import inject
|
||||
|
||||
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 = []
|
||||
|
||||
infoMsg = "checking table existence using items from '%s'" % tableFile
|
||||
|
|
|
@ -13,6 +13,7 @@ import time
|
|||
from lib.core.agent import agent
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import extractRegexResult
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import initTechnique
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.common import replaceNewlineTabs
|
||||
|
@ -44,7 +45,7 @@ def errorUse(expression):
|
|||
_, _, _, _, _, _, fieldToCastStr = agent.getFields(expression)
|
||||
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'
|
||||
|
||||
expression = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
||||
|
|
|
@ -12,6 +12,7 @@ import time
|
|||
from lib.core.agent import agent
|
||||
from lib.core.common import clearConsoleLine
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import parseUnionPage
|
||||
from lib.core.common import randomStr
|
||||
|
@ -62,7 +63,7 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, coun
|
|||
# Perform the request
|
||||
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)
|
||||
|
||||
break
|
||||
|
@ -96,13 +97,13 @@ def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix
|
|||
query = agent.prefixQuery("UNION ALL SELECT %s" % conf.uChar)
|
||||
|
||||
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")]
|
||||
|
||||
if count:
|
||||
query += ", %s" % conf.uChar
|
||||
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
query += " FROM DUAL"
|
||||
|
||||
status = '%d/%d (%d%s)' % (count, conf.uColsStop, round(100.0*count/conf.uColsStop), '%')
|
||||
|
|
|
@ -14,6 +14,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import calculateDeltaSeconds
|
||||
from lib.core.common import clearConsoleLine
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import initTechnique
|
||||
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
|
||||
# return multiple entries
|
||||
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 kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
limitGroupStart = queries[kb.dbms].limitgroupstart.query
|
||||
limitGroupStop = queries[kb.dbms].limitgroupstop.query
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
limitGroupStart = queries[getIdentifiedDBMS()].limitgroupstart.query
|
||||
limitGroupStop = queries[getIdentifiedDBMS()].limitgroupstop.query
|
||||
|
||||
if limitGroupStart.isdigit():
|
||||
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))
|
||||
limitCond = int(stopLimit) > 1
|
||||
|
||||
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
limitGroupStart = queries[kb.dbms].limitgroupstart.query
|
||||
limitGroupStop = queries[kb.dbms].limitgroupstop.query
|
||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
limitGroupStart = queries[getIdentifiedDBMS()].limitgroupstart.query
|
||||
limitGroupStop = queries[getIdentifiedDBMS()].limitgroupstop.query
|
||||
|
||||
if limitGroupStart.isdigit():
|
||||
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))
|
||||
limitCond = int(stopLimit) > 1
|
||||
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
limitCond = False
|
||||
else:
|
||||
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 "
|
||||
# (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
|
||||
untilLimitChar = expression.index(queries[kb.dbms].limitstring.query)
|
||||
untilLimitChar = expression.index(queries[getIdentifiedDBMS()].limitstring.query)
|
||||
expression = expression[:untilLimitChar]
|
||||
|
||||
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
stopLimit += startLimit
|
||||
elif dump:
|
||||
if conf.limitStart:
|
||||
|
@ -116,14 +117,14 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
|
|||
stopLimit = conf.limitStop
|
||||
|
||||
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
|
||||
else:
|
||||
test = True
|
||||
|
||||
if test:
|
||||
# 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)
|
||||
|
||||
if re.search(" ORDER BY ", expression, re.I):
|
||||
|
@ -171,9 +172,9 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
|
|||
|
||||
try:
|
||||
for num in xrange(startLimit, stopLimit):
|
||||
if kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
if getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
field = expressionFieldsList[0]
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
field = expressionFieldsList
|
||||
else:
|
||||
field = None
|
||||
|
|
|
@ -22,6 +22,7 @@ from lib.core.common import clearConsoleLine
|
|||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getCompiledRegex
|
||||
from lib.core.common import getFileItems
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getPublicTypeMembers
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import paths
|
||||
|
@ -267,10 +268,10 @@ def hashRecognition(value):
|
|||
|
||||
if value:
|
||||
for name, regex in getPublicTypeMembers(HASH):
|
||||
#hashes for Oracle and old MySQL look the same hence these checks
|
||||
if kb.dbms == DBMS.ORACLE and regex == HASH.MYSQL_OLD:
|
||||
# Hashes for Oracle and old MySQL look the same hence these checks
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE and regex == HASH.MYSQL_OLD:
|
||||
continue
|
||||
elif kb.dbms == DBMS.MYSQL and regex == HASH.ORACLE_OLD:
|
||||
elif getIdentifiedDBMS() == DBMS.MYSQL and regex == HASH.ORACLE_OLD:
|
||||
continue
|
||||
elif getCompiledRegex(regex).match(value):
|
||||
retVal = regex
|
||||
|
|
|
@ -13,6 +13,7 @@ import time
|
|||
from lib.core.common import calculateDeltaSeconds
|
||||
from lib.core.common import dataToSessionFile
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import safeStringFormat
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import replaceNewlineTabs
|
||||
|
@ -33,8 +34,7 @@ def queryOutputLength(expression, payload):
|
|||
Returns the query output length.
|
||||
"""
|
||||
|
||||
lengthQuery = queries[kb.dbms].length.query
|
||||
|
||||
lengthQuery = queries[getIdentifiedDBMS()].length.query
|
||||
select = re.search("\ASELECT\s+", 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)
|
||||
|
@ -60,7 +60,7 @@ def queryOutputLength(expression, payload):
|
|||
if selectDistinctExpr:
|
||||
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)
|
||||
elif select:
|
||||
lengthExpr = expression.replace(regExpr, lengthQuery % regExpr, 1)
|
||||
|
@ -142,10 +142,10 @@ def resume(expression, payload):
|
|||
if not payload:
|
||||
return None
|
||||
|
||||
if not kb.dbms:
|
||||
if not getIdentifiedDBMS():
|
||||
return None
|
||||
|
||||
substringQuery = queries[kb.dbms].substring.query
|
||||
substringQuery = queries[getIdentifiedDBMS()].substring.query
|
||||
select = re.search("\ASELECT ", expression, re.I)
|
||||
|
||||
_, length, regExpr = queryOutputLength(expression, payload)
|
||||
|
|
|
@ -14,6 +14,7 @@ from lib.core.common import formatDBMSfp
|
|||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getCurrentThreadData
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import wasLastRequestDBMSError
|
||||
|
@ -148,7 +149,7 @@ class Fingerprint(GenericFingerprint):
|
|||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if (kb.dbms is not None and kb.dbms.lower() in ACCESS_ALIASES) or conf.dbms in ACCESS_ALIASES:
|
||||
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in ACCESS_ALIASES) or conf.dbms in ACCESS_ALIASES:
|
||||
setDbms(DBMS.ACCESS)
|
||||
|
||||
if not conf.extensiveFp:
|
||||
|
|
|
@ -13,6 +13,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.common import randomRange
|
||||
|
@ -97,13 +98,13 @@ class Fingerprint(GenericFingerprint):
|
|||
|
||||
def __dialectCheck(self):
|
||||
retVal = None
|
||||
if kb.dbms:
|
||||
if getIdentifiedDBMS():
|
||||
result = inject.checkBooleanExpression("EXISTS(SELECT CURRENT_DATE FROM RDB$DATABASE)")
|
||||
retVal = "dialect 3" if result else "dialect 1"
|
||||
return retVal
|
||||
|
||||
def checkDbms(self):
|
||||
if (kb.dbms is not None and kb.dbms.lower() in FIREBIRD_ALIASES) or conf.dbms in FIREBIRD_ALIASES:
|
||||
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in FIREBIRD_ALIASES) or conf.dbms in FIREBIRD_ALIASES:
|
||||
setDbms(DBMS.FIREBIRD)
|
||||
|
||||
self.getBanner()
|
||||
|
|
|
@ -13,6 +13,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.common import randomRange
|
||||
from lib.core.data import conf
|
||||
|
@ -100,7 +101,7 @@ class Fingerprint(GenericFingerprint):
|
|||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if (kb.dbms is not None and kb.dbms.lower() in MAXDB_ALIASES) or conf.dbms in MAXDB_ALIASES:
|
||||
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in MAXDB_ALIASES) or conf.dbms in MAXDB_ALIASES:
|
||||
setDbms(DBMS.MAXDB)
|
||||
|
||||
self.getBanner()
|
||||
|
|
|
@ -9,6 +9,7 @@ See the file 'doc/COPYING' for copying permission
|
|||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import arrayizeValue
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getRange
|
||||
from lib.core.common import isNumPosStrValue
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
|
@ -40,7 +41,7 @@ class Enumeration(GenericEnumeration):
|
|||
infoMsg += " for database '%s'" % conf.db
|
||||
logger.info(infoMsg)
|
||||
|
||||
rootQuery = queries[kb.dbms].tables
|
||||
rootQuery = queries[getIdentifiedDBMS()].tables
|
||||
|
||||
if not conf.db:
|
||||
if not len(kb.data.cachedDbs):
|
||||
|
@ -110,7 +111,7 @@ class Enumeration(GenericEnumeration):
|
|||
return kb.data.cachedTables
|
||||
|
||||
def searchTable(self):
|
||||
rootQuery = queries[kb.dbms].search_table
|
||||
rootQuery = queries[getIdentifiedDBMS()].search_table
|
||||
foundTbls = {}
|
||||
tblList = conf.tbl.split(",")
|
||||
tblCond = rootQuery.inband.condition
|
||||
|
@ -194,7 +195,7 @@ class Enumeration(GenericEnumeration):
|
|||
return foundTbls
|
||||
|
||||
def searchColumn(self):
|
||||
rootQuery = queries[kb.dbms].search_column
|
||||
rootQuery = queries[getIdentifiedDBMS()].search_column
|
||||
foundCols = {}
|
||||
dbs = {}
|
||||
colList = conf.col.split(",")
|
||||
|
|
|
@ -11,6 +11,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.data import conf
|
||||
|
@ -72,7 +73,7 @@ class Fingerprint(GenericFingerprint):
|
|||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if ((kb.dbms is not None and kb.dbms.lower() in MSSQL_ALIASES) \
|
||||
if ((getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in MSSQL_ALIASES) \
|
||||
or conf.dbms in MSSQL_ALIASES) and kb.dbmsVersion and \
|
||||
kb.dbmsVersion[0].isdigit():
|
||||
setDbms("%s %s" % (DBMS.MSSQL, kb.dbmsVersion[0]))
|
||||
|
|
|
@ -13,6 +13,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.data import conf
|
||||
|
@ -151,7 +152,7 @@ class Fingerprint(GenericFingerprint):
|
|||
* http://dev.mysql.com/doc/refman/6.0/en/news-6-0-x.html (manual has been withdrawn)
|
||||
"""
|
||||
|
||||
if ((kb.dbms is not None and kb.dbms.lower() in MYSQL_ALIASES) \
|
||||
if ((getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in MYSQL_ALIASES) \
|
||||
or conf.dbms in MYSQL_ALIASES) and kb.dbmsVersion and \
|
||||
kb.dbmsVersion[0] != UNKNOWN_DBMS_VERSION:
|
||||
kb.dbmsVersion[0] = kb.dbmsVersion[0].replace(">", "")
|
||||
|
|
|
@ -8,6 +8,7 @@ See the file 'doc/COPYING' for copying permission
|
|||
"""
|
||||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getRange
|
||||
from lib.core.common import isNumPosStrValue
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
|
@ -29,7 +30,7 @@ class Enumeration(GenericEnumeration):
|
|||
def getRoles(self, query2=False):
|
||||
infoMsg = "fetching database users roles"
|
||||
|
||||
rootQuery = queries[kb.dbms].roles
|
||||
rootQuery = queries[getIdentifiedDBMS()].roles
|
||||
|
||||
if conf.user == "CU":
|
||||
infoMsg += " for current user"
|
||||
|
@ -178,7 +179,7 @@ class Enumeration(GenericEnumeration):
|
|||
return []
|
||||
|
||||
def searchColumn(self):
|
||||
rootQuery = queries[kb.dbms].search_column
|
||||
rootQuery = queries[getIdentifiedDBMS()].search_column
|
||||
foundCols = {}
|
||||
dbs = { "USERS": {} }
|
||||
colList = conf.col.split(",")
|
||||
|
|
|
@ -13,6 +13,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
|
@ -64,7 +65,7 @@ class Fingerprint(GenericFingerprint):
|
|||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if (kb.dbms is not None and kb.dbms.lower() in ORACLE_ALIASES) or conf.dbms in ORACLE_ALIASES:
|
||||
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in ORACLE_ALIASES) or conf.dbms in ORACLE_ALIASES:
|
||||
setDbms(DBMS.ORACLE)
|
||||
|
||||
self.getBanner()
|
||||
|
|
|
@ -13,6 +13,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.data import conf
|
||||
|
@ -73,7 +74,7 @@ class Fingerprint(GenericFingerprint):
|
|||
* http://www.postgresql.org/docs/8.4/interactive/release.html (up to 8.4.2)
|
||||
"""
|
||||
|
||||
if (kb.dbms is not None and kb.dbms.lower() in PGSQL_ALIASES) or conf.dbms in PGSQL_ALIASES:
|
||||
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in PGSQL_ALIASES) or conf.dbms in PGSQL_ALIASES:
|
||||
setDbms(DBMS.PGSQL)
|
||||
|
||||
self.getBanner()
|
||||
|
|
|
@ -11,6 +11,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
|
@ -70,7 +71,7 @@ class Fingerprint(GenericFingerprint):
|
|||
* http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions
|
||||
"""
|
||||
|
||||
if (kb.dbms is not None and kb.dbms.lower() in SQLITE_ALIASES) or conf.dbms in SQLITE_ALIASES:
|
||||
if (getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in SQLITE_ALIASES) or conf.dbms in SQLITE_ALIASES:
|
||||
setDbms(DBMS.SQLITE)
|
||||
|
||||
self.getBanner()
|
||||
|
|
|
@ -11,6 +11,7 @@ from lib.core.agent import agent
|
|||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getErrorParsedDBMSesFormatted
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
|
@ -63,7 +64,7 @@ class Fingerprint(GenericFingerprint):
|
|||
return value
|
||||
|
||||
def checkDbms(self):
|
||||
if ((kb.dbms is not None and kb.dbms.lower() in SYBASE_ALIASES) \
|
||||
if ((getIdentifiedDBMS() is not None and getIdentifiedDBMS().lower() in SYBASE_ALIASES) \
|
||||
or conf.dbms in SYBASE_ALIASES) and kb.dbmsVersion and \
|
||||
kb.dbmsVersion[0].isdigit():
|
||||
setDbms("%s %s" % (DBMS.SYBASE, kb.dbmsVersion[0]))
|
||||
|
|
|
@ -17,6 +17,7 @@ from lib.core.common import getRange
|
|||
from lib.core.common import getCompiledRegex
|
||||
from lib.core.common import getConsoleWidth
|
||||
from lib.core.common import getFileItems
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import isNumPosStrValue
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
|
@ -74,19 +75,19 @@ class Enumeration:
|
|||
kb.data.cachedColumns = {}
|
||||
kb.data.dumpedTable = {}
|
||||
kb.data.processChar = None
|
||||
kb.misc.testedDbms = dbms
|
||||
|
||||
def getBanner(self):
|
||||
if not conf.getBanner:
|
||||
return
|
||||
|
||||
if kb.data.banner is None:
|
||||
# TODO: is this assignement an ugly hack?
|
||||
kb.dbmsDetected = True
|
||||
|
||||
infoMsg = "fetching banner"
|
||||
logger.info(infoMsg)
|
||||
|
||||
query = queries[kb.dbms].banner.query
|
||||
query = queries[getIdentifiedDBMS()].banner.query
|
||||
kb.data.banner = inject.getValue(query)
|
||||
bannerParser(kb.data.banner)
|
||||
|
||||
|
@ -108,7 +109,7 @@ class Enumeration:
|
|||
infoMsg = "fetching current user"
|
||||
logger.info(infoMsg)
|
||||
|
||||
query = queries[kb.dbms].current_user.query
|
||||
query = queries[getIdentifiedDBMS()].current_user.query
|
||||
|
||||
if not kb.data.currentUser:
|
||||
kb.data.currentUser = inject.getValue(query)
|
||||
|
@ -119,7 +120,7 @@ class Enumeration:
|
|||
infoMsg = "fetching current database"
|
||||
logger.info(infoMsg)
|
||||
|
||||
query = queries[kb.dbms].current_db.query
|
||||
query = queries[getIdentifiedDBMS()].current_db.query
|
||||
|
||||
if not kb.data.currentDb:
|
||||
kb.data.currentDb = inject.getValue(query)
|
||||
|
@ -130,11 +131,11 @@ class Enumeration:
|
|||
infoMsg = "testing if current user is DBA"
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
self.getCurrentUser()
|
||||
query = queries[kb.dbms].is_dba.query % kb.data.currentUser.split("@")[0]
|
||||
query = queries[getIdentifiedDBMS()].is_dba.query % kb.data.currentUser.split("@")[0]
|
||||
else:
|
||||
query = queries[kb.dbms].is_dba.query
|
||||
query = queries[getIdentifiedDBMS()].is_dba.query
|
||||
|
||||
query = agent.forgeCaseStatement(query)
|
||||
|
||||
|
@ -146,10 +147,10 @@ class Enumeration:
|
|||
infoMsg = "fetching database users"
|
||||
logger.info(infoMsg)
|
||||
|
||||
rootQuery = queries[kb.dbms].users
|
||||
rootQuery = queries[getIdentifiedDBMS()].users
|
||||
|
||||
condition = ( kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ) )
|
||||
condition |= ( kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema )
|
||||
condition = ( getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ) )
|
||||
condition |= ( getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema )
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
|
||||
if condition:
|
||||
|
@ -175,14 +176,14 @@ class Enumeration:
|
|||
errMsg = "unable to retrieve the number of database users"
|
||||
raise sqlmapNoneDataException, errMsg
|
||||
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
plusOne = True
|
||||
else:
|
||||
plusOne = False
|
||||
indexRange = getRange(count, plusOne=plusOne)
|
||||
|
||||
for index in indexRange:
|
||||
if kb.dbms in (DBMS.SYBASE, DBMS.MAXDB):
|
||||
if getIdentifiedDBMS() in (DBMS.SYBASE, DBMS.MAXDB):
|
||||
query = rootQuery.blind.query % (kb.data.cachedUsers[-1] if kb.data.cachedUsers else " ")
|
||||
elif condition:
|
||||
query = rootQuery.blind.query2 % index
|
||||
|
@ -202,7 +203,7 @@ class Enumeration:
|
|||
def getPasswordHashes(self):
|
||||
infoMsg = "fetching database users password hashes"
|
||||
|
||||
rootQuery = queries[kb.dbms].passwords
|
||||
rootQuery = queries[getIdentifiedDBMS()].passwords
|
||||
|
||||
if conf.user == "CU":
|
||||
infoMsg += " for current user"
|
||||
|
@ -211,7 +212,7 @@ class Enumeration:
|
|||
logger.info(infoMsg)
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
|
||||
if kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||
if getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||
query = rootQuery.inband.query2
|
||||
else:
|
||||
query = rootQuery.inband.query
|
||||
|
@ -224,7 +225,7 @@ class Enumeration:
|
|||
query += " WHERE "
|
||||
query += " OR ".join("%s = '%s'" % (condition, user) for user in users)
|
||||
else:
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
parsedUser = re.search("[\047]*(.*?)[\047]*\@", conf.user)
|
||||
|
||||
if parsedUser:
|
||||
|
@ -261,7 +262,7 @@ class Enumeration:
|
|||
retrievedUsers = set()
|
||||
|
||||
for user in users:
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
parsedUser = re.search("[\047]*(.*?)[\047]*\@", user)
|
||||
|
||||
if parsedUser:
|
||||
|
@ -274,7 +275,7 @@ class Enumeration:
|
|||
infoMsg += "for user '%s'" % user
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||
if getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||
query = rootQuery.blind.count2 % user
|
||||
else:
|
||||
query = rootQuery.blind.count % user
|
||||
|
@ -291,14 +292,14 @@ class Enumeration:
|
|||
|
||||
passwords = []
|
||||
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
plusOne = True
|
||||
else:
|
||||
plusOne = False
|
||||
indexRange = getRange(count, plusOne=plusOne)
|
||||
|
||||
for index in indexRange:
|
||||
if kb.dbms == DBMS.SYBASE:
|
||||
if getIdentifiedDBMS() == DBMS.SYBASE:
|
||||
if index > 0:
|
||||
warnMsg = "unable to retrieve other password "
|
||||
warnMsg += "hashes for user '%s'" % user
|
||||
|
@ -307,7 +308,7 @@ class Enumeration:
|
|||
else:
|
||||
query = rootQuery.blind.query % user
|
||||
getCurrentThreadData().disableStdOut = True
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
if kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||
query = rootQuery.blind.query2 % (user, index, user)
|
||||
else:
|
||||
|
@ -315,7 +316,7 @@ class Enumeration:
|
|||
else:
|
||||
query = rootQuery.blind.query % (user, index)
|
||||
password = inject.getValue(query, inband=False)
|
||||
if kb.dbms == DBMS.SYBASE:
|
||||
if getIdentifiedDBMS() == DBMS.SYBASE:
|
||||
getCurrentThreadData().disableStdOut = False
|
||||
password = "0x%s" % strToHex(password)
|
||||
infoMsg = "retrieved: %s" % password
|
||||
|
@ -352,31 +353,31 @@ class Enumeration:
|
|||
def __isAdminFromPrivileges(self, privileges):
|
||||
# In PostgreSQL the usesuper privilege means that the
|
||||
# user is DBA
|
||||
dbaCondition = ( kb.dbms == DBMS.PGSQL and "super" in privileges )
|
||||
dbaCondition = ( getIdentifiedDBMS() == DBMS.PGSQL and "super" in privileges )
|
||||
|
||||
# In Oracle the DBA privilege means that the
|
||||
# user is DBA
|
||||
dbaCondition |= ( kb.dbms == DBMS.ORACLE and "DBA" in privileges )
|
||||
dbaCondition |= ( getIdentifiedDBMS() == DBMS.ORACLE and "DBA" in privileges )
|
||||
|
||||
# In MySQL >= 5.0 the SUPER privilege means
|
||||
# that the user is DBA
|
||||
dbaCondition |= ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema and "SUPER" in privileges )
|
||||
dbaCondition |= ( getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema and "SUPER" in privileges )
|
||||
|
||||
# In MySQL < 5.0 the super_priv privilege means
|
||||
# that the user is DBA
|
||||
dbaCondition |= ( kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema and "super_priv" in privileges )
|
||||
dbaCondition |= ( getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema and "super_priv" in privileges )
|
||||
|
||||
# In Firebird there is no specific privilege that means
|
||||
# that the user is DBA
|
||||
# TODO: confirm
|
||||
dbaCondition |= ( kb.dbms == DBMS.FIREBIRD and "SELECT" in privileges and "INSERT" in privileges and "UPDATE" in privileges and "DELETE" in privileges and "REFERENCES" in privileges and "EXECUTE" in privileges )
|
||||
dbaCondition |= ( getIdentifiedDBMS() == DBMS.FIREBIRD and "SELECT" in privileges and "INSERT" in privileges and "UPDATE" in privileges and "DELETE" in privileges and "REFERENCES" in privileges and "EXECUTE" in privileges )
|
||||
|
||||
return dbaCondition
|
||||
|
||||
def getPrivileges(self, query2=False):
|
||||
infoMsg = "fetching database users privileges"
|
||||
|
||||
rootQuery = queries[kb.dbms].privileges
|
||||
rootQuery = queries[getIdentifiedDBMS()].privileges
|
||||
|
||||
if conf.user == "CU":
|
||||
infoMsg += " for current user"
|
||||
|
@ -432,10 +433,10 @@ class Enumeration:
|
|||
}
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.inband.query2
|
||||
condition = rootQuery.inband.condition2
|
||||
elif kb.dbms == DBMS.ORACLE and query2:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE and query2:
|
||||
query = rootQuery.inband.query2
|
||||
condition = rootQuery.inband.condition2
|
||||
else:
|
||||
|
@ -447,7 +448,7 @@ class Enumeration:
|
|||
query += " WHERE "
|
||||
# NOTE: I assume that the user provided is not in
|
||||
# MySQL >= 5.0 syntax 'user'@'host'
|
||||
if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
queryUser = "%" + conf.user + "%"
|
||||
query += " OR ".join("%s LIKE '%s'" % (condition, "%" + user + "%") for user in users)
|
||||
else:
|
||||
|
@ -455,7 +456,7 @@ class Enumeration:
|
|||
|
||||
values = inject.getValue(query, blind=False, error=False)
|
||||
|
||||
if not values and kb.dbms == DBMS.ORACLE and not query2:
|
||||
if not values and getIdentifiedDBMS() == DBMS.ORACLE and not query2:
|
||||
infoMsg = "trying with table USER_SYS_PRIVS"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
@ -477,19 +478,19 @@ class Enumeration:
|
|||
|
||||
# In PostgreSQL we get 1 if the privilege is
|
||||
# True, 0 otherwise
|
||||
if kb.dbms == DBMS.PGSQL and getUnicode(privilege).isdigit():
|
||||
if getIdentifiedDBMS() == DBMS.PGSQL and getUnicode(privilege).isdigit():
|
||||
for position, pgsqlPriv in pgsqlPrivs:
|
||||
if count == position and int(privilege) == 1:
|
||||
privileges.add(pgsqlPriv)
|
||||
|
||||
# In MySQL >= 5.0 and Oracle we get the list
|
||||
# of privileges as string
|
||||
elif kb.dbms == DBMS.ORACLE or ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema ):
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE or ( getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema ):
|
||||
privileges.add(privilege)
|
||||
|
||||
# In MySQL < 5.0 we get Y if the privilege is
|
||||
# True, N otherwise
|
||||
elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
elif getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
for position, mysqlPriv in mysqlPrivs:
|
||||
if count == position and privilege.upper() == "Y":
|
||||
privileges.add(mysqlPriv)
|
||||
|
@ -506,7 +507,7 @@ class Enumeration:
|
|||
conditionChar = "="
|
||||
|
||||
if conf.user:
|
||||
if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
conditionChar = " LIKE "
|
||||
|
||||
if "," in conf.user:
|
||||
|
@ -533,7 +534,7 @@ class Enumeration:
|
|||
for user in users:
|
||||
unescapedUser = None
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
unescapedUser = unescaper.unescape(user, quote=False)
|
||||
|
||||
if user in retrievedUsers:
|
||||
|
@ -548,18 +549,18 @@ class Enumeration:
|
|||
else:
|
||||
queryUser = user
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.blind.count2 % queryUser
|
||||
elif kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
elif getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
query = rootQuery.blind.count % (conditionChar, queryUser)
|
||||
elif kb.dbms == DBMS.ORACLE and query2:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE and query2:
|
||||
query = rootQuery.blind.count2 % queryUser
|
||||
else:
|
||||
query = rootQuery.blind.count % queryUser
|
||||
count = inject.getValue(query, inband=False, expected=EXPECTED.INT, charsetType=2)
|
||||
|
||||
if not isNumPosStrValue(count):
|
||||
if not (isinstance(count, basestring) and count.isdigit()) and kb.dbms == DBMS.ORACLE and not query2:
|
||||
if not (isinstance(count, basestring) and count.isdigit()) and getIdentifiedDBMS() == DBMS.ORACLE and not query2:
|
||||
infoMsg = "trying with table USER_SYS_PRIVS"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
@ -575,20 +576,20 @@ class Enumeration:
|
|||
|
||||
privileges = set()
|
||||
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
plusOne = True
|
||||
else:
|
||||
plusOne = False
|
||||
indexRange = getRange(count, plusOne=plusOne)
|
||||
|
||||
for index in indexRange:
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.blind.query2 % (queryUser, index)
|
||||
elif kb.dbms == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
elif getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema:
|
||||
query = rootQuery.blind.query % (conditionChar, queryUser, index)
|
||||
elif kb.dbms == DBMS.ORACLE and query2:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE and query2:
|
||||
query = rootQuery.blind.query2 % (queryUser, index)
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
query = rootQuery.blind.query % (index, queryUser)
|
||||
else:
|
||||
query = rootQuery.blind.query % (queryUser, index)
|
||||
|
@ -596,7 +597,7 @@ class Enumeration:
|
|||
|
||||
# In PostgreSQL we get 1 if the privilege is True,
|
||||
# 0 otherwise
|
||||
if kb.dbms == DBMS.PGSQL and ", " in privilege:
|
||||
if getIdentifiedDBMS() == DBMS.PGSQL and ", " in privilege:
|
||||
privilege = privilege.replace(", ", ",")
|
||||
privs = privilege.split(",")
|
||||
i = 1
|
||||
|
@ -611,12 +612,12 @@ class Enumeration:
|
|||
|
||||
# In MySQL >= 5.0 and Oracle we get the list
|
||||
# of privileges as string
|
||||
elif kb.dbms == DBMS.ORACLE or ( kb.dbms == DBMS.MYSQL and kb.data.has_information_schema ):
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE or ( getIdentifiedDBMS() == DBMS.MYSQL and kb.data.has_information_schema ):
|
||||
privileges.add(privilege)
|
||||
|
||||
# In MySQL < 5.0 we get Y if the privilege is
|
||||
# True, N otherwise
|
||||
elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
elif getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
privilege = privilege.replace(", ", ",")
|
||||
privs = privilege.split(",")
|
||||
i = 1
|
||||
|
@ -630,7 +631,7 @@ class Enumeration:
|
|||
i += 1
|
||||
|
||||
# In Firebird we get one letter for each privilege
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
privileges.add(firebirdPrivs[privilege.strip()])
|
||||
|
||||
if self.__isAdminFromPrivileges(privileges):
|
||||
|
@ -639,7 +640,7 @@ class Enumeration:
|
|||
# In MySQL < 5.0 we break the cycle after the first
|
||||
# time we get the user's privileges otherwise we
|
||||
# duplicate the same query
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
break
|
||||
|
||||
if privileges:
|
||||
|
@ -659,14 +660,14 @@ class Enumeration:
|
|||
return ( kb.data.cachedUsersPrivileges, areAdmins )
|
||||
|
||||
def getRoles(self, query2=False):
|
||||
warnMsg = "on %s the concept of roles does not " % kb.dbms
|
||||
warnMsg = "on %s the concept of roles does not " % getIdentifiedDBMS()
|
||||
warnMsg += "exist. sqlmap will enumerate privileges instead"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
return self.getPrivileges(query2)
|
||||
|
||||
def getDbs(self):
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
warnMsg = "information_schema not available, "
|
||||
warnMsg += "back-end DBMS is MySQL < 5. database "
|
||||
warnMsg += "names will be fetched from 'mysql' database"
|
||||
|
@ -675,10 +676,10 @@ class Enumeration:
|
|||
infoMsg = "fetching database names"
|
||||
logger.info(infoMsg)
|
||||
|
||||
rootQuery = queries[kb.dbms].dbs
|
||||
rootQuery = queries[getIdentifiedDBMS()].dbs
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.inband.query2
|
||||
else:
|
||||
query = rootQuery.inband.query
|
||||
|
@ -691,7 +692,7 @@ class Enumeration:
|
|||
infoMsg = "fetching number of databases"
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.blind.count2
|
||||
else:
|
||||
query = rootQuery.blind.count
|
||||
|
@ -704,9 +705,9 @@ class Enumeration:
|
|||
indexRange = getRange(count)
|
||||
|
||||
for index in indexRange:
|
||||
if kb.dbms == DBMS.SYBASE:
|
||||
if getIdentifiedDBMS() == DBMS.SYBASE:
|
||||
query = rootQuery.blind.query % (kb.data.cachedDbs[-1] if kb.data.cachedDbs else " ")
|
||||
elif kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
elif getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.blind.query2 % index
|
||||
else:
|
||||
query = rootQuery.blind.query % index
|
||||
|
@ -726,13 +727,13 @@ class Enumeration:
|
|||
|
||||
self.forceDbmsEnum()
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
logger.error(errMsg)
|
||||
bruteForce = True
|
||||
|
||||
elif kb.dbms == DBMS.ACCESS:
|
||||
elif getIdentifiedDBMS() == DBMS.ACCESS:
|
||||
errMsg = "cannot retrieve table names, "
|
||||
errMsg += "back-end DBMS is Access"
|
||||
logger.error(errMsg)
|
||||
|
@ -771,7 +772,7 @@ class Enumeration:
|
|||
infoMsg += " for database '%s'" % conf.db
|
||||
logger.info(infoMsg)
|
||||
|
||||
rootQuery = queries[kb.dbms].tables
|
||||
rootQuery = queries[getIdentifiedDBMS()].tables
|
||||
|
||||
if conf.db:
|
||||
if "," in conf.db:
|
||||
|
@ -789,7 +790,7 @@ class Enumeration:
|
|||
condition = rootQuery.inband.condition if 'condition' in rootQuery.inband else None
|
||||
|
||||
if condition:
|
||||
if conf.db and kb.dbms != DBMS.SQLITE:
|
||||
if conf.db and getIdentifiedDBMS() != DBMS.SQLITE:
|
||||
if "," in conf.db:
|
||||
dbs = conf.db.split(",")
|
||||
query += " WHERE "
|
||||
|
@ -802,12 +803,12 @@ class Enumeration:
|
|||
infoMsg = "skipping system databases '%s'" % ", ".join(db for db in self.excludeDbsList)
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
if getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
query = safeStringFormat(query, conf.db)
|
||||
value = inject.getValue(query, blind=False, error=False)
|
||||
|
||||
if value:
|
||||
if kb.dbms == DBMS.SQLITE:
|
||||
if getIdentifiedDBMS() == DBMS.SQLITE:
|
||||
if isinstance(value, basestring):
|
||||
value = [[ DBMS.SQLITE, value ]]
|
||||
elif isinstance(value, (list, tuple, set)):
|
||||
|
@ -836,7 +837,7 @@ class Enumeration:
|
|||
infoMsg += "database '%s'" % db
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms in (DBMS.SQLITE, DBMS.FIREBIRD, DBMS.MAXDB):
|
||||
if getIdentifiedDBMS() in (DBMS.SQLITE, DBMS.FIREBIRD, DBMS.MAXDB):
|
||||
query = rootQuery.blind.count
|
||||
else:
|
||||
query = rootQuery.blind.count % db
|
||||
|
@ -850,18 +851,18 @@ class Enumeration:
|
|||
|
||||
tables = []
|
||||
|
||||
if kb.dbms in ( DBMS.MSSQL, DBMS.ORACLE ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MSSQL, DBMS.ORACLE ):
|
||||
plusOne = True
|
||||
else:
|
||||
plusOne = False
|
||||
indexRange = getRange(count, plusOne=plusOne)
|
||||
|
||||
for index in indexRange:
|
||||
if kb.dbms == DBMS.SYBASE:
|
||||
if getIdentifiedDBMS() == DBMS.SYBASE:
|
||||
query = rootQuery.blind.query % (db, (kb.data.cachedTables[-1] if kb.data.cachedTables else " "))
|
||||
elif kb.dbms == DBMS.MAXDB:
|
||||
elif getIdentifiedDBMS() == DBMS.MAXDB:
|
||||
query = rootQuery.blind.query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")
|
||||
elif kb.dbms in (DBMS.SQLITE, DBMS.FIREBIRD):
|
||||
elif getIdentifiedDBMS() in (DBMS.SQLITE, DBMS.FIREBIRD):
|
||||
query = rootQuery.blind.query % index
|
||||
else:
|
||||
query = rootQuery.blind.query % (db, index)
|
||||
|
@ -902,13 +903,13 @@ class Enumeration:
|
|||
|
||||
conf.db = self.getCurrentDb()
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
logger.error(errMsg)
|
||||
bruteForce = True
|
||||
|
||||
elif kb.dbms == DBMS.ACCESS:
|
||||
elif getIdentifiedDBMS() == DBMS.ACCESS:
|
||||
errMsg = "cannot retrieve column names, "
|
||||
errMsg += "back-end DBMS is Access"
|
||||
logger.error(errMsg)
|
||||
|
@ -959,13 +960,13 @@ class Enumeration:
|
|||
"37":"VARCHAR"
|
||||
}
|
||||
|
||||
rootQuery = queries[kb.dbms].columns
|
||||
rootQuery = queries[getIdentifiedDBMS()].columns
|
||||
condition = rootQuery.blind.condition if 'condition' in rootQuery.blind else None
|
||||
|
||||
infoMsg = "fetching columns "
|
||||
|
||||
if conf.col:
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
conf.col = conf.col.upper()
|
||||
colList = conf.col.split(",")
|
||||
condQuery = " AND (" + " OR ".join("%s LIKE '%s'" % (condition, "%" + col + "%") for col in colList) + ")"
|
||||
|
@ -978,24 +979,24 @@ class Enumeration:
|
|||
logger.info(infoMsg)
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
query = rootQuery.inband.query % (conf.tbl, conf.db)
|
||||
query += condQuery
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
query = rootQuery.inband.query % conf.tbl.upper()
|
||||
query += condQuery
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
query = rootQuery.inband.query % (conf.db, conf.db,
|
||||
conf.db, conf.db,
|
||||
conf.db, conf.db,
|
||||
conf.db, conf.tbl)
|
||||
query += condQuery.replace("[DB]", conf.db)
|
||||
elif kb.dbms == DBMS.SQLITE:
|
||||
elif getIdentifiedDBMS() == DBMS.SQLITE:
|
||||
query = rootQuery.inband.query % conf.tbl
|
||||
|
||||
value = inject.getValue(query, blind=False, error=False)
|
||||
|
||||
if kb.dbms == DBMS.SQLITE:
|
||||
if getIdentifiedDBMS() == DBMS.SQLITE:
|
||||
parseSqliteTableSchema(value)
|
||||
elif value:
|
||||
table = {}
|
||||
|
@ -1013,19 +1014,19 @@ class Enumeration:
|
|||
infoMsg += " on database '%s'" % conf.db
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
query = rootQuery.blind.count % (conf.tbl, conf.db)
|
||||
query += condQuery
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
query = rootQuery.blind.count % conf.tbl.upper()
|
||||
query += condQuery
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
query = rootQuery.blind.count % (conf.db, conf.db, conf.tbl)
|
||||
query += condQuery.replace("[DB]", conf.db)
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
query = rootQuery.blind.count % (conf.tbl)
|
||||
query += condQuery
|
||||
elif kb.dbms == DBMS.SQLITE:
|
||||
elif getIdentifiedDBMS() == DBMS.SQLITE:
|
||||
query = rootQuery.blind.query % conf.tbl
|
||||
value = inject.getValue(query, inband=False)
|
||||
|
||||
|
@ -1047,22 +1048,22 @@ class Enumeration:
|
|||
indexRange = getRange(count)
|
||||
|
||||
for index in indexRange:
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
query = rootQuery.blind.query % (conf.tbl, conf.db)
|
||||
query += condQuery
|
||||
field = None
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
query = rootQuery.blind.query % (conf.tbl.upper())
|
||||
query += condQuery
|
||||
field = None
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
query = rootQuery.blind.query % (conf.db, conf.db,
|
||||
conf.db, conf.db,
|
||||
conf.db, conf.db,
|
||||
conf.tbl)
|
||||
query += condQuery.replace("[DB]", conf.db)
|
||||
field = condition.replace("[DB]", conf.db)
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
query = rootQuery.blind.query % (conf.tbl)
|
||||
query += condQuery
|
||||
field = None
|
||||
|
@ -1071,20 +1072,20 @@ class Enumeration:
|
|||
column = inject.getValue(query, inband=False)
|
||||
|
||||
if not onlyColNames:
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
query = rootQuery.blind.query2 % (conf.tbl, column, conf.db)
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
query = rootQuery.blind.query2 % (conf.tbl.upper(), column)
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db,
|
||||
conf.db, column, conf.db,
|
||||
conf.db, conf.db, conf.tbl)
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
query = rootQuery.blind.query2 % (conf.tbl, column)
|
||||
|
||||
colType = inject.getValue(query, inband=False)
|
||||
|
||||
if kb.dbms == DBMS.FIREBIRD:
|
||||
if getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
colType = firebirdTypes[colType] if colType in firebirdTypes else colType
|
||||
|
||||
columns[column] = colType
|
||||
|
@ -1130,9 +1131,9 @@ class Enumeration:
|
|||
|
||||
conf.db = self.getCurrentDb()
|
||||
|
||||
rootQuery = queries[kb.dbms].dump_table
|
||||
rootQuery = queries[getIdentifiedDBMS()].dump_table
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
if '-' in conf.tbl:
|
||||
conf.tbl = "`%s`" % conf.tbl
|
||||
if '-' in conf.db:
|
||||
|
@ -1175,9 +1176,9 @@ class Enumeration:
|
|||
entriesCount = 0
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
query = rootQuery.inband.query % (colString, conf.tbl.upper())
|
||||
elif kb.dbms == DBMS.SQLITE:
|
||||
elif getIdentifiedDBMS() == DBMS.SQLITE:
|
||||
query = rootQuery.inband.query % (colString, conf.tbl)
|
||||
else:
|
||||
query = rootQuery.inband.query % (colString, conf.db, conf.tbl)
|
||||
|
@ -1223,9 +1224,9 @@ class Enumeration:
|
|||
infoMsg += "on database '%s'" % conf.db
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
query = rootQuery.blind.count % conf.tbl.upper()
|
||||
elif kb.dbms in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
|
||||
elif getIdentifiedDBMS() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
|
||||
query = rootQuery.blind.count % conf.tbl
|
||||
else:
|
||||
query = rootQuery.blind.count % (conf.db, conf.tbl)
|
||||
|
@ -1245,14 +1246,14 @@ class Enumeration:
|
|||
lengths = {}
|
||||
entries = {}
|
||||
|
||||
if kb.dbms in (DBMS.ORACLE, DBMS.MSSQL, DBMS.SYBASE):
|
||||
if getIdentifiedDBMS() in (DBMS.ORACLE, DBMS.MSSQL, DBMS.SYBASE):
|
||||
plusOne = True
|
||||
else:
|
||||
plusOne = False
|
||||
indexRange = getRange(count, dump=True, plusOne=plusOne)
|
||||
|
||||
try:
|
||||
if kb.dbms == DBMS.ACCESS:
|
||||
if getIdentifiedDBMS() == DBMS.ACCESS:
|
||||
validColumnList = False
|
||||
validPivotValue = False
|
||||
|
||||
|
@ -1329,22 +1330,22 @@ class Enumeration:
|
|||
if column not in entries:
|
||||
entries[column] = []
|
||||
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
query = rootQuery.blind.query % (column, conf.db,
|
||||
conf.tbl, index)
|
||||
elif kb.dbms == DBMS.ORACLE:
|
||||
elif getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
query = rootQuery.blind.query % (column, column,
|
||||
conf.tbl.upper(),
|
||||
index)
|
||||
elif kb.dbms in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
query = rootQuery.blind.query % (column, index, conf.db,
|
||||
conf.tbl, colList[0],
|
||||
colList[0], colList[0])
|
||||
|
||||
elif kb.dbms == DBMS.SQLITE:
|
||||
elif getIdentifiedDBMS() == DBMS.SQLITE:
|
||||
query = rootQuery.blind.query % (column, conf.tbl, index)
|
||||
|
||||
elif kb.dbms == DBMS.FIREBIRD:
|
||||
elif getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||
query = rootQuery.blind.query % (index, column, conf.tbl)
|
||||
|
||||
value = inject.getValue(query, inband=False)
|
||||
|
@ -1388,7 +1389,7 @@ class Enumeration:
|
|||
return kb.data.dumpedTable
|
||||
|
||||
def dumpAll(self):
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
raise sqlmapUnsupportedFeatureException, errMsg
|
||||
|
@ -1489,10 +1490,10 @@ class Enumeration:
|
|||
|
||||
def searchDb(self):
|
||||
foundDbs = []
|
||||
rootQuery = queries[kb.dbms].search_db
|
||||
rootQuery = queries[getIdentifiedDBMS()].search_db
|
||||
dbList = conf.db.split(",")
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
dbCond = rootQuery.inband.condition2
|
||||
else:
|
||||
dbCond = rootQuery.inband.condition
|
||||
|
@ -1517,7 +1518,7 @@ class Enumeration:
|
|||
dbQuery = dbQuery % db
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) or conf.direct:
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.inband.query2
|
||||
else:
|
||||
query = rootQuery.inband.query
|
||||
|
@ -1538,7 +1539,7 @@ class Enumeration:
|
|||
infoMsg += " '%s'" % db
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.blind.count2
|
||||
else:
|
||||
query = rootQuery.blind.count
|
||||
|
@ -1558,7 +1559,7 @@ class Enumeration:
|
|||
indexRange = getRange(count)
|
||||
|
||||
for index in indexRange:
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
query = rootQuery.blind.query2
|
||||
else:
|
||||
query = rootQuery.blind.query
|
||||
|
@ -1573,12 +1574,12 @@ class Enumeration:
|
|||
def searchTable(self):
|
||||
bruteForce = False
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
bruteForce = True
|
||||
|
||||
elif kb.dbms == DBMS.ACCESS:
|
||||
elif getIdentifiedDBMS() == DBMS.ACCESS:
|
||||
errMsg = "cannot retrieve table names, "
|
||||
errMsg += "back-end DBMS is Access"
|
||||
logger.error(errMsg)
|
||||
|
@ -1596,7 +1597,7 @@ class Enumeration:
|
|||
regex = "|".join(conf.tbl.split(","))
|
||||
return tableExists(paths.COMMON_TABLES, regex)
|
||||
|
||||
rootQuery = queries[kb.dbms].search_table
|
||||
rootQuery = queries[getIdentifiedDBMS()].search_table
|
||||
foundTbls = {}
|
||||
tblList = conf.tbl.split(",")
|
||||
tblCond = rootQuery.inband.condition
|
||||
|
@ -1605,7 +1606,7 @@ class Enumeration:
|
|||
tblConsider, tblCondParam = self.likeOrExact("table")
|
||||
|
||||
for tbl in tblList:
|
||||
if kb.dbms == DBMS.ORACLE:
|
||||
if getIdentifiedDBMS() == DBMS.ORACLE:
|
||||
tbl = tbl.upper()
|
||||
|
||||
infoMsg = "searching table"
|
||||
|
@ -1715,12 +1716,12 @@ class Enumeration:
|
|||
def searchColumn(self):
|
||||
bruteForce = False
|
||||
|
||||
if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL and not kb.data.has_information_schema:
|
||||
errMsg = "information_schema not available, "
|
||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||
bruteForce = True
|
||||
|
||||
elif kb.dbms == DBMS.ACCESS:
|
||||
elif getIdentifiedDBMS() == DBMS.ACCESS:
|
||||
errMsg = "cannot retrieve column names, "
|
||||
errMsg += "back-end DBMS is Access"
|
||||
logger.error(errMsg)
|
||||
|
@ -1746,7 +1747,7 @@ class Enumeration:
|
|||
|
||||
return
|
||||
|
||||
rootQuery = queries[kb.dbms].search_column
|
||||
rootQuery = queries[getIdentifiedDBMS()].search_column
|
||||
foundCols = {}
|
||||
dbs = {}
|
||||
colList = conf.col.split(",")
|
||||
|
@ -1958,7 +1959,7 @@ class Enumeration:
|
|||
return output
|
||||
|
||||
def sqlShell(self):
|
||||
infoMsg = "calling %s shell. To quit type " % kb.dbms
|
||||
infoMsg = "calling %s shell. To quit type " % getIdentifiedDBMS()
|
||||
infoMsg += "'x' or 'q' and press ENTER"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import os
|
|||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import dataToOutFile
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import readInput
|
||||
|
@ -86,13 +87,13 @@ class Filesystem:
|
|||
return fileLines
|
||||
|
||||
def __checkWrittenFile(self, wFile, dFile, fileType):
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % dFile
|
||||
|
||||
elif kb.dbms == DBMS.PGSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
lengthQuery = "SELECT LENGTH(data) FROM pg_largeobject WHERE loid=%d" % self.oid
|
||||
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
||||
|
||||
# Reference: http://msdn.microsoft.com/en-us/library/ms188365.aspx
|
||||
|
@ -270,7 +271,7 @@ class Filesystem:
|
|||
|
||||
fileContent = self.unionReadFile(rFile)
|
||||
|
||||
if fileContent in ( None, "" ) and kb.dbms != "PostgreSQL":
|
||||
if fileContent in ( None, "" ) and getIdentifiedDBMS() != DBMS.PGSQL:
|
||||
self.cleanup(onlyFileTbl=True)
|
||||
|
||||
return
|
||||
|
@ -288,7 +289,7 @@ class Filesystem:
|
|||
fileContent = self.__unhexString(fileContent)
|
||||
rFilePath = dataToOutFile(fileContent)
|
||||
|
||||
if kb.dbms != "PostgreSQL":
|
||||
if getIdentifiedDBMS() != DBMS.PGSQL:
|
||||
self.cleanup(onlyFileTbl=True)
|
||||
|
||||
return rFilePath
|
||||
|
|
|
@ -10,6 +10,7 @@ See the file 'doc/COPYING' for copying permission
|
|||
import re
|
||||
|
||||
from lib.core.common import getCompiledRegex
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
from lib.core.common import normalizePath
|
||||
from lib.core.common import ntToPosixSlashes
|
||||
|
@ -56,19 +57,19 @@ class Miscellaneous:
|
|||
infoMsg = "detecting back-end DBMS version from its banner"
|
||||
logger.info(infoMsg)
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
first, last = 1, 6
|
||||
|
||||
elif kb.dbms == DBMS.PGSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
first, last = 12, 6
|
||||
|
||||
elif kb.dbms == DBMS.MSSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
first, last = 29, 9
|
||||
|
||||
else:
|
||||
raise sqlmapUnsupportedFeatureException, "unsupported DBMS"
|
||||
|
||||
query = queries[kb.dbms].substring.query % (queries[kb.dbms].banner.query, first, last)
|
||||
query = queries[getIdentifiedDBMS()].substring.query % (queries[getIdentifiedDBMS()].banner.query, first, last)
|
||||
|
||||
if conf.direct:
|
||||
query = "SELECT %s" % query
|
||||
|
@ -119,7 +120,7 @@ class Miscellaneous:
|
|||
if not onlyFileTbl:
|
||||
inject.goStacked("DROP TABLE %s" % self.cmdTblName, silent=True)
|
||||
|
||||
if kb.dbms == DBMS.MSSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MSSQL:
|
||||
return
|
||||
|
||||
if udfDict is None:
|
||||
|
@ -132,7 +133,7 @@ class Miscellaneous:
|
|||
if not output or output in ("y", "Y"):
|
||||
dropStr = "DROP FUNCTION %s" % udf
|
||||
|
||||
if kb.dbms == DBMS.PGSQL:
|
||||
if getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
inp = ", ".join(i for i in inpRet["input"])
|
||||
dropStr += "(%s)" % inp
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ See the file 'doc/COPYING' for copying permission
|
|||
|
||||
import os
|
||||
|
||||
from lib.core.common import getIdentifiedDBMS
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
from lib.core.common import readInput
|
||||
from lib.core.common import runningAsAdmin
|
||||
|
@ -44,7 +45,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
def osCmd(self):
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
|
||||
web = False
|
||||
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and kb.dbms == DBMS.MYSQL:
|
||||
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
infoMsg = "going to use a web backdoor for command execution"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
@ -65,7 +66,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
def osShell(self):
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
|
||||
web = False
|
||||
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and kb.dbms == DBMS.MYSQL:
|
||||
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
infoMsg = "going to use a web backdoor for command prompt"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
@ -148,7 +149,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
errMsg += "is unlikely to receive commands send from you"
|
||||
logger.error(errMsg)
|
||||
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
self.sysUdfs.pop("sys_bineval")
|
||||
|
||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
|
||||
|
@ -158,7 +159,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
self.initEnv(web=web)
|
||||
|
||||
if tunnel == 1:
|
||||
if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
||||
msg = "how do you want to execute the Metasploit shellcode "
|
||||
msg += "on the back-end database underlying operating system?"
|
||||
msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
|
||||
|
@ -188,7 +189,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
self.uploadMsfPayloadStager()
|
||||
|
||||
if kb.os == "Windows" and conf.privEsc:
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
debugMsg = "by default MySQL on Windows runs as SYSTEM "
|
||||
debugMsg += "user, no need to privilege escalate"
|
||||
logger.debug(debugMsg)
|
||||
|
@ -206,7 +207,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
self.uploadIcmpshSlave(web=web)
|
||||
self.icmpPwn()
|
||||
|
||||
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and kb.dbms == DBMS.MYSQL:
|
||||
elif not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
web = True
|
||||
|
||||
infoMsg = "going to use a web backdoor to establish the tunnel"
|
||||
|
@ -255,13 +256,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||
|
||||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
||||
if kb.dbms in ( DBMS.PGSQL, DBMS.MSSQL ):
|
||||
if getIdentifiedDBMS() in ( DBMS.PGSQL, DBMS.MSSQL ):
|
||||
errMsg = "on this back-end DBMS it is only possible to "
|
||||
errMsg += "perform the SMB relay attack if stacked "
|
||||
errMsg += "queries are supported"
|
||||
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||
|
||||
elif kb.dbms == DBMS.MYSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
debugMsg = "since stacked queries are not supported, "
|
||||
debugMsg += "sqlmap is going to perform the SMB relay "
|
||||
debugMsg += "attack via inference blind SQL injection"
|
||||
|
@ -270,18 +271,18 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
printWarn = True
|
||||
warnMsg = "it is unlikely that this attack will be successful "
|
||||
|
||||
if kb.dbms == DBMS.MYSQL:
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
warnMsg += "because by default MySQL on Windows runs as "
|
||||
warnMsg += "Local System which is not a real user, it does "
|
||||
warnMsg += "not send the NTLM session hash when connecting to "
|
||||
warnMsg += "a SMB service"
|
||||
|
||||
elif kb.dbms == DBMS.PGSQL:
|
||||
elif getIdentifiedDBMS() == DBMS.PGSQL:
|
||||
warnMsg += "because by default PostgreSQL on Windows runs "
|
||||
warnMsg += "as postgres user which is a real user of the "
|
||||
warnMsg += "system, but not within the Administrators group"
|
||||
|
||||
elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||
elif getIdentifiedDBMS() == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||
warnMsg += "because often Microsoft SQL Server %s " % kb.dbmsVersion[0]
|
||||
warnMsg += "runs as Network Service which is not a real user, "
|
||||
warnMsg += "it does not send the NTLM session hash when "
|
||||
|
@ -299,7 +300,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
|||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
||||
return
|
||||
|
||||
if not kb.dbms == DBMS.MSSQL or kb.dbmsVersion[0] not in ( "2000", "2005" ):
|
||||
if not getIdentifiedDBMS() == DBMS.MSSQL or kb.dbmsVersion[0] not in ( "2000", "2005" ):
|
||||
errMsg = "the back-end DBMS must be Microsoft SQL Server "
|
||||
errMsg += "2000 or 2005 to be able to exploit the heap-based "
|
||||
errMsg += "buffer overflow in the 'sp_replwritetovarbin' "
|
||||
|
|
Loading…
Reference in New Issue
Block a user