Minor code refactoring relating set/get back-end DBMS operating system and minor bug fix to properly enforce OS value with --os switch

This commit is contained in:
Bernardo Damele 2011-04-23 16:25:09 +00:00
parent 75142b383d
commit d0dff82ce0
20 changed files with 125 additions and 92 deletions

View File

@ -42,7 +42,6 @@ from extra.cloak.cloak import decloak
from extra.magic import magic from extra.magic import magic
from extra.odict.odict import OrderedDict from extra.odict.odict import OrderedDict
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import dbmsDict
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import paths from lib.core.data import paths
@ -52,6 +51,7 @@ from lib.core.convert import urldecode
from lib.core.convert import urlencode from lib.core.convert import urlencode
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import HTTPHEADER from lib.core.enums import HTTPHEADER
from lib.core.enums import OS
from lib.core.enums import PLACE from lib.core.enums import PLACE
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.enums import SORTORDER from lib.core.enums import SORTORDER
@ -64,6 +64,7 @@ from lib.core.exception import sqlmapSyntaxException
from lib.core.optiondict import optDict from lib.core.optiondict import optDict
from lib.core.settings import INFERENCE_UNKNOWN_CHAR from lib.core.settings import INFERENCE_UNKNOWN_CHAR
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import DBMS_DICT
from lib.core.settings import DESCRIPTION from lib.core.settings import DESCRIPTION
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import PLATFORM from lib.core.settings import PLATFORM
@ -93,6 +94,7 @@ from lib.core.settings import TIME_DEFAULT_DELAY
from lib.core.settings import TIME_STDEV_COEFF from lib.core.settings import TIME_STDEV_COEFF
from lib.core.settings import DYNAMICITY_MARK_LENGTH from lib.core.settings import DYNAMICITY_MARK_LENGTH
from lib.core.settings import SENSITIVE_DATA_REGEX from lib.core.settings import SENSITIVE_DATA_REGEX
from lib.core.settings import SUPPORTED_OS
from lib.core.settings import UNKNOWN_DBMS_VERSION from lib.core.settings import UNKNOWN_DBMS_VERSION
from lib.core.settings import URI_INJECTION_MARK_CHAR from lib.core.settings import URI_INJECTION_MARK_CHAR
from lib.core.settings import URI_QUESTION_MARKER from lib.core.settings import URI_QUESTION_MARKER
@ -305,7 +307,7 @@ class Backend:
return None return None
# Little precaution, in theory this condition should always be false # Little precaution, in theory this condition should always be false
elif kb.os is not None and kb.os != os: elif kb.os is not None and isinstance(os, basestring) and kb.os.lower() != os.lower():
msg = "sqlmap previously fingerprinted back-end DBMS " msg = "sqlmap previously fingerprinted back-end DBMS "
msg += "operating system %s. However now it has " % kb.os msg += "operating system %s. However now it has " % kb.os
msg += "been fingerprinted to be %s. " % os msg += "been fingerprinted to be %s. " % os
@ -318,14 +320,14 @@ class Backend:
if inp == kb.os: if inp == kb.os:
break break
elif inp == os: elif inp == os:
kb.os = inp kb.os = inp.capitalize()
break break
else: else:
warnMsg = "invalid value" warnMsg = "invalid value"
logger.warn(warnMsg) logger.warn(warnMsg)
elif kb.os is None: elif kb.os is None and isinstance(os, basestring):
kb.os = os kb.os = os.capitalize()
return kb.os return kb.os
@ -419,7 +421,7 @@ class Backend:
@staticmethod @staticmethod
def isOs(os): def isOs(os):
return Backend.getOs() is not None and Backend.getOs().lower() == kb.os.lower() return Backend.getOs() is not None and Backend.getOs().lower() == os.lower()
def paramToDict(place, parameters=None): def paramToDict(place, parameters=None):
""" """
@ -506,7 +508,7 @@ def getDocRoot():
docRoot = None docRoot = None
pagePath = directoryPath(conf.path) pagePath = directoryPath(conf.path)
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
defaultDocRoot = ["C:/xampp/htdocs/", "C:/Inetpub/wwwroot/"] defaultDocRoot = ["C:/xampp/htdocs/", "C:/Inetpub/wwwroot/"]
else: else:
defaultDocRoot = ["/var/www/"] defaultDocRoot = ["/var/www/"]
@ -954,7 +956,7 @@ def parseTargetDirect():
errMsg += "or 'access://DATABASE_FILEPATH'" errMsg += "or 'access://DATABASE_FILEPATH'"
raise sqlmapSyntaxException, errMsg raise sqlmapSyntaxException, errMsg
for dbmsName, data in dbmsDict.items(): for dbmsName, data in DBMS_DICT.items():
if conf.dbms in data[0]: if conf.dbms in data[0]:
try: try:
if dbmsName in (DBMS.ACCESS, DBMS.SQLITE, DBMS.FIREBIRD): if dbmsName in (DBMS.ACCESS, DBMS.SQLITE, DBMS.FIREBIRD):
@ -2064,7 +2066,7 @@ def aliasToDbmsEnum(dbms):
if dbms is None: if dbms is None:
return None return None
for key, item in dbmsDict.items(): for key, item in DBMS_DICT.items():
if dbms.lower() in item[0]: if dbms.lower() in item[0]:
retVal = key retVal = key
break break

View File

@ -38,14 +38,3 @@ queries = {}
# logger # logger
logger = LOGGER logger = LOGGER
dbmsDict = { DBMS.MSSQL: [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"],
DBMS.MYSQL: [MYSQL_ALIASES, "python-mysqldb", "http://mysql-python.sourceforge.net/"],
DBMS.PGSQL: [PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/"],
DBMS.ORACLE: [ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/"],
DBMS.SQLITE: [SQLITE_ALIASES, "python-pysqlite2", "http://pysqlite.googlecode.com/"],
DBMS.ACCESS: [ACCESS_ALIASES, "python-pyodbc", "http://pyodbc.googlecode.com/"],
DBMS.FIREBIRD: [FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/"],
DBMS.MAXDB: [MAXDB_ALIASES, None, None],
DBMS.SYBASE: [SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"]
}

View File

@ -35,6 +35,10 @@ class DBMS:
SQLITE = "SQLite" SQLITE = "SQLite"
SYBASE = "Sybase" SYBASE = "Sybase"
class OS:
LINUX = "Linux"
WINDOWS = "Windows"
class PLACE: class PLACE:
GET = "GET" GET = "GET"
POST = "POST" POST = "POST"

View File

@ -75,6 +75,7 @@ from lib.core.settings import PLATFORM
from lib.core.settings import PYVERSION from lib.core.settings import PYVERSION
from lib.core.settings import SITE from lib.core.settings import SITE
from lib.core.settings import DEFAULT_TOR_PROXY from lib.core.settings import DEFAULT_TOR_PROXY
from lib.core.settings import DBMS_DICT
from lib.core.settings import SUPPORTED_DBMS from lib.core.settings import SUPPORTED_DBMS
from lib.core.settings import SUPPORTED_OS from lib.core.settings import SUPPORTED_OS
from lib.core.settings import VERSION_STRING from lib.core.settings import VERSION_STRING
@ -601,20 +602,21 @@ def __setOS():
if not conf.os: if not conf.os:
return return
debugMsg = "forcing back-end DBMS operating system to user defined value" if conf.os.lower() not in SUPPORTED_OS:
logger.debug(debugMsg)
conf.os = conf.os.lower()
if conf.os not in SUPPORTED_OS:
errMsg = "you provided an unsupported back-end DBMS operating " errMsg = "you provided an unsupported back-end DBMS operating "
errMsg += "system. The supported DBMS operating systems for OS " errMsg += "system. The supported DBMS operating systems for OS "
errMsg += "and file system access are Linux and Windows. " errMsg += "and file system access are %s. " % ', '.join([o.capitalize() for o in SUPPORTED_OS])
errMsg += "If you do not know the back-end DBMS underlying OS, " errMsg += "If you do not know the back-end DBMS underlying OS, "
errMsg += "do not provide it and sqlmap will fingerprint it for " errMsg += "do not provide it and sqlmap will fingerprint it for "
errMsg += "you." errMsg += "you."
raise sqlmapUnsupportedDBMSException, errMsg raise sqlmapUnsupportedDBMSException, errMsg
debugMsg = "forcing back-end DBMS operating system to user defined "
debugMsg += "value '%s'" % conf.os
logger.debug(debugMsg)
Backend.setOs(conf.os)
def __setTechnique(): def __setTechnique():
validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1]) validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1])
validLetters = map(lambda x: x[0][0].upper(), validTechniques) validLetters = map(lambda x: x[0][0].upper(), validTechniques)
@ -668,10 +670,9 @@ def __setDBMS():
if conf.dbms not in SUPPORTED_DBMS: if conf.dbms not in SUPPORTED_DBMS:
errMsg = "you provided an unsupported back-end database management " errMsg = "you provided an unsupported back-end database management "
errMsg += "system. The supported DBMS are MySQL, PostgreSQL, " errMsg += "system. The supported DBMS are %s. " % ', '.join([d for d in DBMS_DICT])
errMsg += "Microsoft SQL Server and Oracle. If you do not know " errMsg += "If you do not know the back-end DBMS, do not provide "
errMsg += "the back-end DBMS, do not provide it and sqlmap will " errMsg += "it and sqlmap will fingerprint it for you."
errMsg += "fingerprint it for you."
raise sqlmapUnsupportedDBMSException, errMsg raise sqlmapUnsupportedDBMSException, errMsg
for aliases in (MSSQL_ALIASES, MYSQL_ALIASES, PGSQL_ALIASES, \ for aliases in (MSSQL_ALIASES, MYSQL_ALIASES, PGSQL_ALIASES, \
@ -1203,6 +1204,12 @@ def __cleanupOptions():
if conf.data: if conf.data:
conf.data = urldecode(conf.data) conf.data = urldecode(conf.data)
if conf.os:
conf.os = conf.os.capitalize()
if conf.dbms:
conf.dbms = conf.dbms.capitalize()
# to distinguish explicit usage of --time-sec # to distinguish explicit usage of --time-sec
if conf.timeSec is None: if conf.timeSec is None:
if conf.tor: if conf.tor:

View File

@ -22,6 +22,7 @@ from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.datatype import injectionDict from lib.core.datatype import injectionDict
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE from lib.core.enums import PLACE
from lib.core.settings import METADB_SUFFIX from lib.core.settings import METADB_SUFFIX
@ -123,8 +124,8 @@ def setOs():
return return
if "type" in kb.bannerFp: if "type" in kb.bannerFp:
kb.os = Format.humanize(kb.bannerFp["type"]) Backend.setOs(Format.humanize(kb.bannerFp["type"]))
infoMsg = "the back-end DBMS operating system is %s" % kb.os infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
if "distrib" in kb.bannerFp: if "distrib" in kb.bannerFp:
kb.osVersion = Format.humanize(kb.bannerFp["distrib"]) kb.osVersion = Format.humanize(kb.bannerFp["distrib"])
@ -133,17 +134,17 @@ def setOs():
if "sp" in kb.bannerFp: if "sp" in kb.bannerFp:
kb.osSP = int(Format.humanize(kb.bannerFp["sp"]).replace("Service Pack ", "")) kb.osSP = int(Format.humanize(kb.bannerFp["sp"]).replace("Service Pack ", ""))
elif "sp" not in kb.bannerFp and kb.os == "Windows": elif "sp" not in kb.bannerFp and Backend.isOs(OS.WINDOWS):
kb.osSP = 0 kb.osSP = 0
if kb.os and kb.osVersion and kb.osSP: if Backend.getOs() and kb.osVersion and kb.osSP:
infoMsg += " Service Pack %d" % kb.osSP infoMsg += " Service Pack %d" % kb.osSP
if infoMsg: if infoMsg:
logger.info(infoMsg) logger.info(infoMsg)
if condition: if condition:
dataToSessionFile("[%s][%s][%s][OS][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), safeFormatString(kb.os))) dataToSessionFile("[%s][%s][%s][OS][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), Backend.getOs()))
def setRemoteTempPath(): def setRemoteTempPath():
condition = ( condition = (
@ -242,6 +243,8 @@ def resumeConfKb(expression, url, value):
else: else:
conf.os = os conf.os = os
Backend.setOs(conf.os)
elif expression == "Remote temp path" and url == conf.url and conf.tmpPath is None: elif expression == "Remote temp path" and url == conf.url and conf.tmpPath is None:
conf.tmpPath = unSafeFormatString(value[:-1]) conf.tmpPath = unSafeFormatString(value[:-1])

View File

@ -161,6 +161,17 @@ SYBASE_ALIASES = [ "sybase", "sybase sql server" ]
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES
SUPPORTED_OS = ( "linux", "windows" ) SUPPORTED_OS = ( "linux", "windows" )
DBMS_DICT = { DBMS.MSSQL: [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"],
DBMS.MYSQL: [MYSQL_ALIASES, "python-mysqldb", "http://mysql-python.sourceforge.net/"],
DBMS.PGSQL: [PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/"],
DBMS.ORACLE: [ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/"],
DBMS.SQLITE: [SQLITE_ALIASES, "python-pysqlite2", "http://pysqlite.googlecode.com/"],
DBMS.ACCESS: [ACCESS_ALIASES, "python-pyodbc", "http://pyodbc.googlecode.com/"],
DBMS.FIREBIRD: [FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/"],
DBMS.MAXDB: [MAXDB_ALIASES, None, None],
DBMS.SYBASE: [SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"]
}
REFERER_ALIASES = ( "ref", "referer", "referrer" ) REFERER_ALIASES = ( "ref", "referer", "referrer" )
USER_AGENT_ALIASES = ( "ua", "useragent", "user-agent" ) USER_AGENT_ALIASES = ( "ua", "useragent", "user-agent" )

View File

@ -17,6 +17,7 @@ from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import paths from lib.core.data import paths
from lib.core.data import queries from lib.core.data import queries
from lib.core.enums import OS
def saveHistory(): def saveHistory():
historyPath = os.path.expanduser(paths.SQLMAP_HISTORY) historyPath = os.path.expanduser(paths.SQLMAP_HISTORY)
@ -68,7 +69,7 @@ def autoCompletion(sqlShell=False, osShell=False):
if sqlShell: if sqlShell:
completer = CompleterNG(queriesForAutoCompletion()) completer = CompleterNG(queriesForAutoCompletion())
elif osShell: elif osShell:
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
# Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands # Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands
completer = CompleterNG({ completer = CompleterNG({
"copy": None, "del": None, "dir": None, "copy": None, "del": None, "dir": None,

View File

@ -15,6 +15,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapUnsupportedFeatureException from lib.core.exception import sqlmapUnsupportedFeatureException
from lib.core.shell import autoCompletion from lib.core.shell import autoCompletion
@ -108,7 +109,7 @@ class Abstraction(Web, UDF, xp_cmdshell):
errMsg = "feature not yet implemented for the back-end DBMS" errMsg = "feature not yet implemented for the back-end DBMS"
raise sqlmapUnsupportedFeatureException, errMsg raise sqlmapUnsupportedFeatureException, errMsg
infoMsg = "calling %s OS shell. To quit type " % (kb.os or "Windows") infoMsg = "calling %s OS shell. To quit type " % (Backend.getOs() or "Windows")
infoMsg += "'x' or 'q' and press ENTER" infoMsg += "'x' or 'q' and press ENTER"
logger.info(infoMsg) logger.info(infoMsg)

View File

@ -32,6 +32,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.exception import sqlmapDataException from lib.core.exception import sqlmapDataException
from lib.core.exception import sqlmapFilePathException from lib.core.exception import sqlmapFilePathException
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
@ -118,7 +119,7 @@ class Metasploit:
} }
def __skeletonSelection(self, msg, lst=None, maxValue=1, default=1): def __skeletonSelection(self, msg, lst=None, maxValue=1, default=1):
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
opSys = "windows" opSys = "windows"
else: else:
opSys = "linux" opSys = "linux"
@ -169,11 +170,11 @@ class Metasploit:
if isinstance(encode, basestring): if isinstance(encode, basestring):
return encode return encode
elif kb.os == "Windows" and encode: elif Backend.isOs(OS.WINDOWS) and encode:
return self.__skeletonSelection("payload encoding", self.__msfEncodersList) return self.__skeletonSelection("payload encoding", self.__msfEncodersList)
def __selectPayload(self): def __selectPayload(self):
if kb.os == "Windows" and conf.privEsc: if Backend.isOs(OS.WINDOWS) and conf.privEsc:
infoMsg = "forcing Metasploit payload to Meterpreter because " infoMsg = "forcing Metasploit payload to Meterpreter because "
infoMsg += "it is the only payload that can be used to " infoMsg += "it is the only payload that can be used to "
infoMsg += "escalate privileges, either via 'incognito' " infoMsg += "escalate privileges, either via 'incognito' "
@ -358,7 +359,7 @@ class Metasploit:
elif not self.connectionStr.startswith("bind"): elif not self.connectionStr.startswith("bind"):
raise sqlmapDataException, "unexpected connection type" raise sqlmapDataException, "unexpected connection type"
if kb.os == "Windows" or extra == "BufferRegister=EAX": if Backend.isOs(OS.WINDOWS) or extra == "BufferRegister=EAX":
self.__payloadCmd += " R | %s -a x86 -e %s -o %s -t %s" % (self.__msfEncode, self.encoderStr, outFile, format) self.__payloadCmd += " R | %s -a x86 -e %s -o %s -t %s" % (self.__msfEncode, self.encoderStr, outFile, format)
if extra is not None: if extra is not None:
@ -395,7 +396,7 @@ class Metasploit:
infoMsg += "remotely, please wait.." infoMsg += "remotely, please wait.."
logger.info(infoMsg) logger.info(infoMsg)
if kb.os != "Windows": if not Backend.isOs(OS.WINDOWS):
self.execCmd("chmod +x %s" % self.exeFilePathRemote, silent=True) self.execCmd("chmod +x %s" % self.exeFilePathRemote, silent=True)
cmd = "%s &" % self.exeFilePathRemote cmd = "%s &" % self.exeFilePathRemote
@ -403,7 +404,7 @@ class Metasploit:
self.execCmd(cmd, silent=True) self.execCmd(cmd, silent=True)
def __loadMetExtensions(self, proc, metSess): def __loadMetExtensions(self, proc, metSess):
if kb.os != "Windows": if not Backend.isOs(OS.WINDOWS):
return return
if self.resourceFile is not None: if self.resourceFile is not None:
@ -479,7 +480,7 @@ class Metasploit:
func() func()
if "Starting the payload handler" in out and "shell" in self.payloadStr: if "Starting the payload handler" in out and "shell" in self.payloadStr:
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
proc.stdin.write("whoami\n") proc.stdin.write("whoami\n")
else: else:
proc.stdin.write("uname -a ; id\n") proc.stdin.write("uname -a ; id\n")
@ -512,7 +513,7 @@ class Metasploit:
pollProcess(process) pollProcess(process)
payloadStderr = process.communicate()[1] payloadStderr = process.communicate()[1]
if kb.os == "Windows" or extra == "BufferRegister=EAX": if Backend.isOs(OS.WINDOWS) or extra == "BufferRegister=EAX":
payloadSize = re.search("size ([\d]+)", payloadStderr, re.I) payloadSize = re.search("size ([\d]+)", payloadStderr, re.I)
else: else:
payloadSize = re.search("Length\:\s([\d]+)", payloadStderr, re.I) payloadSize = re.search("Length\:\s([\d]+)", payloadStderr, re.I)
@ -547,7 +548,7 @@ class Metasploit:
self.__randStr = randomStr(lowercase=True) self.__randStr = randomStr(lowercase=True)
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
self.exeFilePathLocal = os.path.join(conf.outputPath, "tmpm%s.exe" % self.__randStr) self.exeFilePathLocal = os.path.join(conf.outputPath, "tmpm%s.exe" % self.__randStr)
# Metasploit developers added support for the old exe format # Metasploit developers added support for the old exe format
@ -579,7 +580,7 @@ class Metasploit:
pollProcess(process) pollProcess(process)
payloadStderr = process.communicate()[1] payloadStderr = process.communicate()[1]
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
payloadSize = re.search("size\s([\d]+)", payloadStderr, re.I) payloadSize = re.search("size\s([\d]+)", payloadStderr, re.I)
else: else:
payloadSize = re.search("Length\:\s([\d]+)", payloadStderr, re.I) payloadSize = re.search("Length\:\s([\d]+)", payloadStderr, re.I)

View File

@ -19,6 +19,7 @@ from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import queries from lib.core.data import queries
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapFilePathException from lib.core.exception import sqlmapFilePathException
from lib.core.exception import sqlmapMissingMandatoryOptionException from lib.core.exception import sqlmapMissingMandatoryOptionException
@ -191,12 +192,12 @@ class UDF:
errMsg = "shared library file must end with '.dll' or '.so'" errMsg = "shared library file must end with '.dll' or '.so'"
raise sqlmapMissingMandatoryOptionException(errMsg) raise sqlmapMissingMandatoryOptionException(errMsg)
elif self.udfLocalFile.endswith(".so") and kb.os == "Windows": elif self.udfLocalFile.endswith(".so") and Backend.isOs(OS.WINDOWS):
errMsg = "you provided a shared object as shared library, but " errMsg = "you provided a shared object as shared library, but "
errMsg += "the database underlying operating system is Windows" errMsg += "the database underlying operating system is Windows"
raise sqlmapMissingMandatoryOptionException(errMsg) raise sqlmapMissingMandatoryOptionException(errMsg)
elif self.udfLocalFile.endswith(".dll") and kb.os == "Linux": elif self.udfLocalFile.endswith(".dll") and Backend.isOs(OS.LINUX):
errMsg = "you provided a dynamic-link library as shared library, " errMsg = "you provided a dynamic-link library as shared library, "
errMsg += "but the database underlying operating system is Linux" errMsg += "but the database underlying operating system is Linux"
raise sqlmapMissingMandatoryOptionException(errMsg) raise sqlmapMissingMandatoryOptionException(errMsg)

View File

@ -14,6 +14,7 @@ import re
from extra.cloak.cloak import decloak from extra.cloak.cloak import decloak
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import Backend
from lib.core.common import decloakToNamedTemporaryFile from lib.core.common import decloakToNamedTemporaryFile
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import getDirs from lib.core.common import getDirs
@ -31,6 +32,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import paths from lib.core.data import paths
from lib.core.enums import OS
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapUnsupportedDBMSException from lib.core.exception import sqlmapUnsupportedDBMSException
from lib.core.shell import autoCompletion from lib.core.shell import autoCompletion
@ -103,7 +105,7 @@ class Web:
def __webFileInject(self, fileContent, fileName, directory): def __webFileInject(self, fileContent, fileName, directory):
outFile = posixpath.normpath("%s/%s" % (directory, fileName)) outFile = posixpath.normpath("%s/%s" % (directory, fileName))
uplQuery = fileContent.replace("WRITABLE_DIR", directory.replace('/', '\\\\') if kb.os == "Windows" else directory) uplQuery = fileContent.replace("WRITABLE_DIR", directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)
query = "" query = ""
if isTechniqueAvailable(kb.technique): if isTechniqueAvailable(kb.technique):
@ -144,7 +146,7 @@ class Web:
break break
if not default: if not default:
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
default = "asp" default = "asp"
else: else:
default = "php" default = "php"
@ -284,7 +286,7 @@ class Web:
continue continue
else: else:
if not self.__webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(localPath) if kb.os == "Windows" else localPath): if not self.__webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(localPath) if Backend.isOs(OS.WINDOWS) else localPath):
warnMsg = "backdoor has not been successfully uploaded " warnMsg = "backdoor has not been successfully uploaded "
warnMsg += "with file stager probably because of " warnMsg += "with file stager probably because of "
warnMsg += "lack of write permission." warnMsg += "lack of write permission."

View File

@ -16,6 +16,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.session import setDbms from lib.core.session import setDbms
from lib.core.settings import MSSQL_ALIASES from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import UNKNOWN_DBMS_VERSION from lib.core.settings import UNKNOWN_DBMS_VERSION
@ -78,7 +79,7 @@ class Fingerprint(GenericFingerprint):
self.getBanner() self.getBanner()
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
return True return True
@ -112,7 +113,7 @@ class Fingerprint(GenericFingerprint):
self.getBanner() self.getBanner()
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
return True return True
else: else:
@ -122,11 +123,11 @@ class Fingerprint(GenericFingerprint):
return False return False
def checkDbmsOs(self, detailed=False): def checkDbmsOs(self, detailed=False):
if kb.os and kb.osVersion and kb.osSP: if Backend.getOs() and kb.osVersion and kb.osSP:
return return
if not kb.os: if not Backend.getOs():
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
if not detailed: if not detailed:
return return
@ -135,7 +136,7 @@ class Fingerprint(GenericFingerprint):
infoMsg += "version and service pack" infoMsg += "version and service pack"
logger.info(infoMsg) logger.info(infoMsg)
infoMsg = "the back-end DBMS operating system is %s" % kb.os infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
self.createSupportTbl(self.fileTblName, self.tblField, "varchar(1000)") self.createSupportTbl(self.fileTblName, self.tblField, "varchar(1000)")
inject.goStacked("INSERT INTO %s(%s) VALUES (%s)" % (self.fileTblName, self.tblField, "@@VERSION")) inject.goStacked("INSERT INTO %s(%s) VALUES (%s)" % (self.fileTblName, self.tblField, "@@VERSION"))

View File

@ -18,6 +18,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import PLACE from lib.core.enums import PLACE
from lib.core.session import setDbms from lib.core.session import setDbms
from lib.core.settings import MYSQL_ALIASES from lib.core.settings import MYSQL_ALIASES
@ -272,7 +273,7 @@ class Fingerprint(GenericFingerprint):
return False return False
def checkDbmsOs(self, detailed=False): def checkDbmsOs(self, detailed=False):
if kb.os: if Backend.getOs():
return return
infoMsg = "fingerprinting the back-end DBMS operating system" infoMsg = "fingerprinting the back-end DBMS operating system"
@ -281,12 +282,12 @@ class Fingerprint(GenericFingerprint):
result = inject.checkBooleanExpression("'W'=UPPER(MID(@@version_compile_os,1,1))") result = inject.checkBooleanExpression("'W'=UPPER(MID(@@version_compile_os,1,1))")
if result: if result:
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
elif not result: elif not result:
kb.os = "Linux" Backend.setOs(OS.LINUX)
if kb.os: if Backend.getOs():
infoMsg = "the back-end DBMS operating system is %s" % kb.os infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
logger.info(infoMsg) logger.info(infoMsg)
else: else:
self.userChooseDbmsOs() self.userChooseDbmsOs()

View File

@ -10,6 +10,7 @@ See the file 'doc/COPYING' for copying permission
import re import re
from lib.core.agent import agent from lib.core.agent import agent
from lib.core.common import Backend
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
from lib.core.common import normalizePath from lib.core.common import normalizePath
from lib.core.common import ntToPosixSlashes from lib.core.common import ntToPosixSlashes
@ -18,6 +19,7 @@ from lib.core.common import readInput
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import paths from lib.core.data import paths
from lib.core.enums import OS
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.request import inject from lib.request import inject
from lib.request.connect import Connect as Request from lib.request.connect import Connect as Request
@ -45,12 +47,12 @@ class Takeover(GenericTakeover):
self.__basedir = inject.getValue("SELECT @@basedir") self.__basedir = inject.getValue("SELECT @@basedir")
if re.search("^[\w]\:[\/\\\\]+", self.__basedir, re.I): if re.search("^[\w]\:[\/\\\\]+", self.__basedir, re.I):
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
else: else:
kb.os = "Linux" Backend.setOs(OS.LINUX)
# The DLL must be in C:\Program Files\MySQL\MySQL Server 5.1\lib\plugin # The DLL must be in C:\Program Files\MySQL\MySQL Server 5.1\lib\plugin
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
self.__basedir += "/lib/plugin" self.__basedir += "/lib/plugin"
else: else:
self.__basedir += "/lib/mysql/plugin" self.__basedir += "/lib/mysql/plugin"
@ -97,7 +99,7 @@ class Takeover(GenericTakeover):
warnMsg = "invalid value, valid values are 1 and 2" warnMsg = "invalid value, valid values are 1 and 2"
logger.warn(warnMsg) logger.warn(warnMsg)
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
self.udfLocalFile += "/mysql/windows/%d/lib_mysqludf_sys.dll" % arch self.udfLocalFile += "/mysql/windows/%d/lib_mysqludf_sys.dll" % arch
self.udfSharedLibExt = "dll" self.udfSharedLibExt = "dll"
else: else:

View File

@ -18,6 +18,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.session import setDbms from lib.core.session import setDbms
from lib.core.settings import PGSQL_ALIASES from lib.core.settings import PGSQL_ALIASES
from lib.core.settings import PGSQL_SYSTEM_DBS from lib.core.settings import PGSQL_SYSTEM_DBS
@ -148,7 +149,7 @@ class Fingerprint(GenericFingerprint):
return False return False
def checkDbmsOs(self, detailed=False): def checkDbmsOs(self, detailed=False):
if kb.os: if Backend.getOs():
return return
infoMsg = "fingerprinting the back-end DBMS operating system" infoMsg = "fingerprinting the back-end DBMS operating system"
@ -166,14 +167,14 @@ class Fingerprint(GenericFingerprint):
query += "LIKE '%" + osPattern + "%')>0" query += "LIKE '%" + osPattern + "%')>0"
if inject.checkBooleanExpression(query): if inject.checkBooleanExpression(query):
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
break break
if kb.os is None: if Backend.getOs() is None:
kb.os = "Linux" Backend.setOs(OS.LINUX)
infoMsg = "the back-end DBMS operating system is %s" % kb.os infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
logger.info(infoMsg) logger.info(infoMsg)
self.cleanup(onlyFileTbl=True) self.cleanup(onlyFileTbl=True)

View File

@ -7,11 +7,13 @@ Copyright (c) 2006-2011 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission See the file 'doc/COPYING' for copying permission
""" """
from lib.core.common import Backend
from lib.core.common import randomStr from lib.core.common import randomStr
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import paths from lib.core.data import paths
from lib.core.enums import OS
from lib.core.exception import sqlmapUnsupportedFeatureException from lib.core.exception import sqlmapUnsupportedFeatureException
from lib.request import inject from lib.request import inject
@ -23,7 +25,7 @@ class Takeover(GenericTakeover):
def udfSetRemotePath(self): def udfSetRemotePath(self):
# On Windows # On Windows
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
# The DLL can be in any folder where postgres user has # The DLL can be in any folder where postgres user has
# read/write/execute access is valid # read/write/execute access is valid
# NOTE: by not specifing any path, it will save into the # NOTE: by not specifing any path, it will save into the
@ -75,7 +77,7 @@ class Takeover(GenericTakeover):
warnMsg = "invalid value, valid values are 1 and 2" warnMsg = "invalid value, valid values are 1 and 2"
logger.warn(warnMsg) logger.warn(warnMsg)
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
self.udfLocalFile += "/postgresql/windows/%d/%s/lib_postgresqludf_sys.dll" % (arch, majorVer) self.udfLocalFile += "/postgresql/windows/%d/%s/lib_postgresqludf_sys.dll" % (arch, majorVer)
self.udfSharedLibExt = "dll" self.udfSharedLibExt = "dll"
else: else:

View File

@ -15,6 +15,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.session import setDbms from lib.core.session import setDbms
from lib.core.settings import SYBASE_ALIASES from lib.core.settings import SYBASE_ALIASES
from lib.request import inject from lib.request import inject
@ -69,7 +70,7 @@ class Fingerprint(GenericFingerprint):
self.getBanner() self.getBanner()
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
return True return True

View File

@ -11,6 +11,7 @@ from lib.core.common import Backend
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import OS
from lib.core.exception import sqlmapUndefinedMethod from lib.core.exception import sqlmapUndefinedMethod
class Fingerprint: class Fingerprint:
@ -50,10 +51,10 @@ class Fingerprint:
os = readInput(msg, default="W") os = readInput(msg, default="W")
if os[0].lower() == "w": if os[0].lower() == "w":
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
break break
elif os[0].lower() == "l": elif os[0].lower() == "l":
kb.os = "Linux" Backend.setOs(OS.LINUX)
break break
else: else:
warnMsg = "invalid value" warnMsg = "invalid value"

View File

@ -21,6 +21,7 @@ from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import queries from lib.core.data import queries
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapNoneDataException from lib.core.exception import sqlmapNoneDataException
from lib.core.exception import sqlmapUnsupportedFeatureException from lib.core.exception import sqlmapUnsupportedFeatureException
@ -37,13 +38,13 @@ class Miscellaneous:
def getRemoteTempPath(self): def getRemoteTempPath(self):
if not conf.tmpPath: if not conf.tmpPath:
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
conf.tmpPath = "C:/WINDOWS/Temp" conf.tmpPath = "C:/WINDOWS/Temp"
else: else:
conf.tmpPath = "/tmp" conf.tmpPath = "/tmp"
if getCompiledRegex("(?i)\A[\w]:[\/\\\\]+").search(conf.tmpPath): if getCompiledRegex("(?i)\A[\w]:[\/\\\\]+").search(conf.tmpPath):
kb.os = "Windows" Backend.setOs(OS.WINDOWS)
conf.tmpPath = normalizePath(conf.tmpPath) conf.tmpPath = normalizePath(conf.tmpPath)
conf.tmpPath = ntToPosixSlashes(conf.tmpPath) conf.tmpPath = ntToPosixSlashes(conf.tmpPath)
@ -80,7 +81,7 @@ class Miscellaneous:
def delRemoteFile(self, tempFile): def delRemoteFile(self, tempFile):
self.checkDbmsOs() self.checkDbmsOs()
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
tempFile = posixToNtSlashes(tempFile) tempFile = posixToNtSlashes(tempFile)
cmd = "del /F /Q %s" % tempFile cmd = "del /F /Q %s" % tempFile
else: else:
@ -100,10 +101,10 @@ class Miscellaneous:
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct: if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
return return
if kb.os == "Windows": if Backend.isOs(OS.WINDOWS):
libtype = "dynamic-link library" libtype = "dynamic-link library"
elif kb.os == "Linux": elif Backend.isOs(OS.LINUX):
libtype = "shared object" libtype = "shared object"
else: else:

View File

@ -17,6 +17,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapMissingDependence from lib.core.exception import sqlmapMissingDependence
from lib.core.exception import sqlmapMissingMandatoryOptionException from lib.core.exception import sqlmapMissingMandatoryOptionException
@ -108,7 +109,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
warnMsg = "invalid value, valid values are 1 and 2" warnMsg = "invalid value, valid values are 1 and 2"
logger.warn(warnMsg) logger.warn(warnMsg)
if tunnel == 2 and kb.os != "Windows": if tunnel == 2 and Backend.isOs(OS.WINDOWS):
errMsg = "icmpsh slave is only supported on Windows at " errMsg = "icmpsh slave is only supported on Windows at "
errMsg += "the moment. The back-end database server is " errMsg += "the moment. The back-end database server is "
errMsg += "not. sqlmap will fallback to TCP (Metasploit)" errMsg += "not. sqlmap will fallback to TCP (Metasploit)"
@ -189,13 +190,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
self.createMsfPayloadStager() self.createMsfPayloadStager()
self.uploadMsfPayloadStager() self.uploadMsfPayloadStager()
if kb.os == "Windows" and conf.privEsc: if Backend.isOs(OS.WINDOWS) and conf.privEsc:
if Backend.getIdentifiedDbms() == DBMS.MYSQL: if Backend.getIdentifiedDbms() == DBMS.MYSQL:
debugMsg = "by default MySQL on Windows runs as SYSTEM " debugMsg = "by default MySQL on Windows runs as SYSTEM "
debugMsg += "user, no need to privilege escalate" debugMsg += "user, no need to privilege escalate"
logger.debug(debugMsg) logger.debug(debugMsg)
elif kb.os != "Windows" and conf.privEsc: elif not Backend.isOs(OS.WINDOWS) and conf.privEsc:
# Unset --priv-esc if the back-end DBMS underlying operating # Unset --priv-esc if the back-end DBMS underlying operating
# system is not Windows # system is not Windows
conf.privEsc = False conf.privEsc = False
@ -217,7 +218,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
self.initEnv(web=web) self.initEnv(web=web)
if self.webBackdoorUrl: if self.webBackdoorUrl:
if kb.os != "Windows" and conf.privEsc: if not Backend.isOs(OS.WINDOWS) and conf.privEsc:
# Unset --priv-esc if the back-end DBMS underlying operating # Unset --priv-esc if the back-end DBMS underlying operating
# system is not Windows # system is not Windows
conf.privEsc = False conf.privEsc = False
@ -250,7 +251,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
def osSmb(self): def osSmb(self):
self.checkDbmsOs() self.checkDbmsOs()
if kb.os != "Windows": if not Backend.isOs(OS.WINDOWS):
errMsg = "the back-end DBMS underlying operating system is " errMsg = "the back-end DBMS underlying operating system is "
errMsg += "not Windows: it is not possible to perform the SMB " errMsg += "not Windows: it is not possible to perform the SMB "
errMsg += "relay attack" errMsg += "relay attack"
@ -329,7 +330,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
self.checkDbmsOs() self.checkDbmsOs()
if kb.os != "Windows": if not Backend.isOs(OS.WINDOWS):
errMsg = "the back-end DBMS underlying operating system is " errMsg = "the back-end DBMS underlying operating system is "
errMsg += "not Windows" errMsg += "not Windows"
raise sqlmapUnsupportedDBMSException(errMsg) raise sqlmapUnsupportedDBMSException(errMsg)