diff --git a/lib/core/common.py b/lib/core/common.py index 4a7b13267..7b282e207 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -42,7 +42,6 @@ from extra.cloak.cloak import decloak from extra.magic import magic from extra.odict.odict import OrderedDict from lib.core.data import conf -from lib.core.data import dbmsDict from lib.core.data import kb from lib.core.data import logger 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.enums import DBMS from lib.core.enums import HTTPHEADER +from lib.core.enums import OS from lib.core.enums import PLACE from lib.core.enums import PAYLOAD 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.settings import INFERENCE_UNKNOWN_CHAR 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 IS_WIN 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 DYNAMICITY_MARK_LENGTH 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 URI_INJECTION_MARK_CHAR from lib.core.settings import URI_QUESTION_MARKER @@ -305,7 +307,7 @@ class Backend: return None # 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 += "operating system %s. However now it has " % kb.os msg += "been fingerprinted to be %s. " % os @@ -318,14 +320,14 @@ class Backend: if inp == kb.os: break elif inp == os: - kb.os = inp + kb.os = inp.capitalize() break else: warnMsg = "invalid value" logger.warn(warnMsg) - elif kb.os is None: - kb.os = os + elif kb.os is None and isinstance(os, basestring): + kb.os = os.capitalize() return kb.os @@ -419,7 +421,7 @@ class Backend: @staticmethod 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): """ @@ -506,7 +508,7 @@ def getDocRoot(): docRoot = None pagePath = directoryPath(conf.path) - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): defaultDocRoot = ["C:/xampp/htdocs/", "C:/Inetpub/wwwroot/"] else: defaultDocRoot = ["/var/www/"] @@ -954,7 +956,7 @@ def parseTargetDirect(): errMsg += "or 'access://DATABASE_FILEPATH'" raise sqlmapSyntaxException, errMsg - for dbmsName, data in dbmsDict.items(): + for dbmsName, data in DBMS_DICT.items(): if conf.dbms in data[0]: try: if dbmsName in (DBMS.ACCESS, DBMS.SQLITE, DBMS.FIREBIRD): @@ -2064,7 +2066,7 @@ def aliasToDbmsEnum(dbms): if dbms is None: return None - for key, item in dbmsDict.items(): + for key, item in DBMS_DICT.items(): if dbms.lower() in item[0]: retVal = key break diff --git a/lib/core/data.py b/lib/core/data.py index d4aeef412..716948a23 100644 --- a/lib/core/data.py +++ b/lib/core/data.py @@ -38,14 +38,3 @@ queries = {} # 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/"] - } diff --git a/lib/core/enums.py b/lib/core/enums.py index 6562723e6..623f6c57e 100644 --- a/lib/core/enums.py +++ b/lib/core/enums.py @@ -35,6 +35,10 @@ class DBMS: SQLITE = "SQLite" SYBASE = "Sybase" +class OS: + LINUX = "Linux" + WINDOWS = "Windows" + class PLACE: GET = "GET" POST = "POST" diff --git a/lib/core/option.py b/lib/core/option.py index f559de269..883113877 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -75,6 +75,7 @@ from lib.core.settings import PLATFORM from lib.core.settings import PYVERSION from lib.core.settings import SITE 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_OS from lib.core.settings import VERSION_STRING @@ -601,20 +602,21 @@ def __setOS(): if not conf.os: return - debugMsg = "forcing back-end DBMS operating system to user defined value" - logger.debug(debugMsg) - - conf.os = conf.os.lower() - - if conf.os not in SUPPORTED_OS: - errMsg = "you provided an unsupported back-end DBMS operating " + if conf.os.lower() not in SUPPORTED_OS: + errMsg = "you provided an unsupported back-end DBMS operating " 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 += "do not provide it and sqlmap will fingerprint it for " errMsg += "you." 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(): validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1]) validLetters = map(lambda x: x[0][0].upper(), validTechniques) @@ -667,11 +669,10 @@ def __setDBMS(): Backend.setVersion(str(dbmsRegExp.group(2))) if conf.dbms not in SUPPORTED_DBMS: - errMsg = "you provided an unsupported back-end database management " - errMsg += "system. The supported DBMS are MySQL, PostgreSQL, " - errMsg += "Microsoft SQL Server and Oracle. If you do not know " - errMsg += "the back-end DBMS, do not provide it and sqlmap will " - errMsg += "fingerprint it for you." + errMsg = "you provided an unsupported back-end database management " + errMsg += "system. The supported DBMS are %s. " % ', '.join([d for d in DBMS_DICT]) + errMsg += "If you do not know the back-end DBMS, do not provide " + errMsg += "it and sqlmap will fingerprint it for you." raise sqlmapUnsupportedDBMSException, errMsg for aliases in (MSSQL_ALIASES, MYSQL_ALIASES, PGSQL_ALIASES, \ @@ -1203,6 +1204,12 @@ def __cleanupOptions(): if 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 if conf.timeSec is None: if conf.tor: diff --git a/lib/core/session.py b/lib/core/session.py index 9d8e231c0..96cf67444 100644 --- a/lib/core/session.py +++ b/lib/core/session.py @@ -22,6 +22,7 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.datatype import injectionDict from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.enums import PAYLOAD from lib.core.enums import PLACE from lib.core.settings import METADB_SUFFIX @@ -123,8 +124,8 @@ def setOs(): return if "type" in kb.bannerFp: - kb.os = Format.humanize(kb.bannerFp["type"]) - infoMsg = "the back-end DBMS operating system is %s" % kb.os + Backend.setOs(Format.humanize(kb.bannerFp["type"])) + infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs() if "distrib" in kb.bannerFp: kb.osVersion = Format.humanize(kb.bannerFp["distrib"]) @@ -133,17 +134,17 @@ def setOs(): if "sp" in kb.bannerFp: 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 - if kb.os and kb.osVersion and kb.osSP: + if Backend.getOs() and kb.osVersion and kb.osSP: infoMsg += " Service Pack %d" % kb.osSP if infoMsg: logger.info(infoMsg) 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(): condition = ( @@ -242,6 +243,8 @@ def resumeConfKb(expression, url, value): else: conf.os = os + Backend.setOs(conf.os) + elif expression == "Remote temp path" and url == conf.url and conf.tmpPath is None: conf.tmpPath = unSafeFormatString(value[:-1]) diff --git a/lib/core/settings.py b/lib/core/settings.py index e7c11224e..721de8619 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -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_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" ) USER_AGENT_ALIASES = ( "ua", "useragent", "user-agent" ) diff --git a/lib/core/shell.py b/lib/core/shell.py index 1d0f68d9b..111838989 100644 --- a/lib/core/shell.py +++ b/lib/core/shell.py @@ -17,6 +17,7 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.data import paths from lib.core.data import queries +from lib.core.enums import OS def saveHistory(): historyPath = os.path.expanduser(paths.SQLMAP_HISTORY) @@ -68,7 +69,7 @@ def autoCompletion(sqlShell=False, osShell=False): if sqlShell: completer = CompleterNG(queriesForAutoCompletion()) elif osShell: - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): # Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands completer = CompleterNG({ "copy": None, "del": None, "dir": None, diff --git a/lib/takeover/abstraction.py b/lib/takeover/abstraction.py index 789460ecc..321848c8b 100644 --- a/lib/takeover/abstraction.py +++ b/lib/takeover/abstraction.py @@ -15,6 +15,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapUnsupportedFeatureException 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" 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" logger.info(infoMsg) diff --git a/lib/takeover/metasploit.py b/lib/takeover/metasploit.py index e6dae7713..a8b3afe99 100644 --- a/lib/takeover/metasploit.py +++ b/lib/takeover/metasploit.py @@ -32,6 +32,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.exception import sqlmapDataException from lib.core.exception import sqlmapFilePathException from lib.core.settings import UNICODE_ENCODING @@ -118,7 +119,7 @@ class Metasploit: } def __skeletonSelection(self, msg, lst=None, maxValue=1, default=1): - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): opSys = "windows" else: opSys = "linux" @@ -169,11 +170,11 @@ class Metasploit: if isinstance(encode, basestring): return encode - elif kb.os == "Windows" and encode: + elif Backend.isOs(OS.WINDOWS) and encode: return self.__skeletonSelection("payload encoding", self.__msfEncodersList) 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 += "it is the only payload that can be used to " infoMsg += "escalate privileges, either via 'incognito' " @@ -358,7 +359,7 @@ class Metasploit: elif not self.connectionStr.startswith("bind"): 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) if extra is not None: @@ -395,7 +396,7 @@ class Metasploit: infoMsg += "remotely, please wait.." logger.info(infoMsg) - if kb.os != "Windows": + if not Backend.isOs(OS.WINDOWS): self.execCmd("chmod +x %s" % self.exeFilePathRemote, silent=True) cmd = "%s &" % self.exeFilePathRemote @@ -403,7 +404,7 @@ class Metasploit: self.execCmd(cmd, silent=True) def __loadMetExtensions(self, proc, metSess): - if kb.os != "Windows": + if not Backend.isOs(OS.WINDOWS): return if self.resourceFile is not None: @@ -479,7 +480,7 @@ class Metasploit: func() 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") else: proc.stdin.write("uname -a ; id\n") @@ -512,7 +513,7 @@ class Metasploit: pollProcess(process) 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) else: payloadSize = re.search("Length\:\s([\d]+)", payloadStderr, re.I) @@ -547,7 +548,7 @@ class Metasploit: 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) # Metasploit developers added support for the old exe format @@ -579,7 +580,7 @@ class Metasploit: pollProcess(process) payloadStderr = process.communicate()[1] - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): payloadSize = re.search("size\s([\d]+)", payloadStderr, re.I) else: payloadSize = re.search("Length\:\s([\d]+)", payloadStderr, re.I) diff --git a/lib/takeover/udf.py b/lib/takeover/udf.py index 37cff2215..97b02406e 100644 --- a/lib/takeover/udf.py +++ b/lib/takeover/udf.py @@ -19,6 +19,7 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapFilePathException from lib.core.exception import sqlmapMissingMandatoryOptionException @@ -191,12 +192,12 @@ class UDF: errMsg = "shared library file must end with '.dll' or '.so'" 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 += "the database underlying operating system is Windows" 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 += "but the database underlying operating system is Linux" raise sqlmapMissingMandatoryOptionException(errMsg) diff --git a/lib/takeover/web.py b/lib/takeover/web.py index db7649d8b..90cea6641 100644 --- a/lib/takeover/web.py +++ b/lib/takeover/web.py @@ -14,6 +14,7 @@ import re from extra.cloak.cloak import decloak from lib.core.agent import agent +from lib.core.common import Backend from lib.core.common import decloakToNamedTemporaryFile from lib.core.common import extractRegexResult 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 logger from lib.core.data import paths +from lib.core.enums import OS from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapUnsupportedDBMSException from lib.core.shell import autoCompletion @@ -103,7 +105,7 @@ class Web: def __webFileInject(self, fileContent, fileName, directory): 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 = "" if isTechniqueAvailable(kb.technique): @@ -144,12 +146,12 @@ class Web: break if not default: - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): default = "asp" else: default = "php" - message = "which web application language does the web server " + message = "which web application language does the web server " message += "support?\n" for count in xrange(len(choices)): @@ -284,7 +286,7 @@ class Web: continue 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 += "with file stager probably because of " warnMsg += "lack of write permission." diff --git a/plugins/dbms/mssqlserver/fingerprint.py b/plugins/dbms/mssqlserver/fingerprint.py index c8b0bee8f..cb5ec1231 100644 --- a/plugins/dbms/mssqlserver/fingerprint.py +++ b/plugins/dbms/mssqlserver/fingerprint.py @@ -16,6 +16,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.session import setDbms from lib.core.settings import MSSQL_ALIASES from lib.core.settings import UNKNOWN_DBMS_VERSION @@ -78,7 +79,7 @@ class Fingerprint(GenericFingerprint): self.getBanner() - kb.os = "Windows" + Backend.setOs(OS.WINDOWS) return True @@ -112,7 +113,7 @@ class Fingerprint(GenericFingerprint): self.getBanner() - kb.os = "Windows" + Backend.setOs(OS.WINDOWS) return True else: @@ -122,11 +123,11 @@ class Fingerprint(GenericFingerprint): return 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 - if not kb.os: - kb.os = "Windows" + if not Backend.getOs(): + Backend.setOs(OS.WINDOWS) if not detailed: return @@ -135,7 +136,7 @@ class Fingerprint(GenericFingerprint): infoMsg += "version and service pack" 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)") inject.goStacked("INSERT INTO %s(%s) VALUES (%s)" % (self.fileTblName, self.tblField, "@@VERSION")) diff --git a/plugins/dbms/mysql/fingerprint.py b/plugins/dbms/mysql/fingerprint.py index 08df082a2..af37cc85a 100644 --- a/plugins/dbms/mysql/fingerprint.py +++ b/plugins/dbms/mysql/fingerprint.py @@ -18,6 +18,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.enums import PLACE from lib.core.session import setDbms from lib.core.settings import MYSQL_ALIASES @@ -272,7 +273,7 @@ class Fingerprint(GenericFingerprint): return False def checkDbmsOs(self, detailed=False): - if kb.os: + if Backend.getOs(): return 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))") if result: - kb.os = "Windows" + Backend.setOs(OS.WINDOWS) elif not result: - kb.os = "Linux" + Backend.setOs(OS.LINUX) - if kb.os: - infoMsg = "the back-end DBMS operating system is %s" % kb.os + if Backend.getOs(): + infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs() logger.info(infoMsg) else: self.userChooseDbmsOs() diff --git a/plugins/dbms/mysql/takeover.py b/plugins/dbms/mysql/takeover.py index da505be9a..9e03ec5e7 100644 --- a/plugins/dbms/mysql/takeover.py +++ b/plugins/dbms/mysql/takeover.py @@ -10,6 +10,7 @@ See the file 'doc/COPYING' for copying permission import re from lib.core.agent import agent +from lib.core.common import Backend from lib.core.common import isTechniqueAvailable from lib.core.common import normalizePath 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 logger from lib.core.data import paths +from lib.core.enums import OS from lib.core.enums import PAYLOAD from lib.request import inject from lib.request.connect import Connect as Request @@ -45,12 +47,12 @@ class Takeover(GenericTakeover): self.__basedir = inject.getValue("SELECT @@basedir") if re.search("^[\w]\:[\/\\\\]+", self.__basedir, re.I): - kb.os = "Windows" + Backend.setOs(OS.WINDOWS) else: - kb.os = "Linux" + Backend.setOs(OS.LINUX) # 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" else: self.__basedir += "/lib/mysql/plugin" @@ -97,7 +99,7 @@ class Takeover(GenericTakeover): warnMsg = "invalid value, valid values are 1 and 2" logger.warn(warnMsg) - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): self.udfLocalFile += "/mysql/windows/%d/lib_mysqludf_sys.dll" % arch self.udfSharedLibExt = "dll" else: diff --git a/plugins/dbms/postgresql/fingerprint.py b/plugins/dbms/postgresql/fingerprint.py index af37320aa..172fded22 100644 --- a/plugins/dbms/postgresql/fingerprint.py +++ b/plugins/dbms/postgresql/fingerprint.py @@ -18,6 +18,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.session import setDbms from lib.core.settings import PGSQL_ALIASES from lib.core.settings import PGSQL_SYSTEM_DBS @@ -148,7 +149,7 @@ class Fingerprint(GenericFingerprint): return False def checkDbmsOs(self, detailed=False): - if kb.os: + if Backend.getOs(): return infoMsg = "fingerprinting the back-end DBMS operating system" @@ -166,14 +167,14 @@ class Fingerprint(GenericFingerprint): query += "LIKE '%" + osPattern + "%')>0" if inject.checkBooleanExpression(query): - kb.os = "Windows" + Backend.setOs(OS.WINDOWS) break - if kb.os is None: - kb.os = "Linux" + if Backend.getOs() is None: + 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) self.cleanup(onlyFileTbl=True) diff --git a/plugins/dbms/postgresql/takeover.py b/plugins/dbms/postgresql/takeover.py index a0a9d304f..f37162b62 100644 --- a/plugins/dbms/postgresql/takeover.py +++ b/plugins/dbms/postgresql/takeover.py @@ -7,11 +7,13 @@ Copyright (c) 2006-2011 sqlmap developers (http://sqlmap.sourceforge.net/) 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 readInput from lib.core.data import kb from lib.core.data import logger from lib.core.data import paths +from lib.core.enums import OS from lib.core.exception import sqlmapUnsupportedFeatureException from lib.request import inject @@ -23,7 +25,7 @@ class Takeover(GenericTakeover): def udfSetRemotePath(self): # On Windows - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): # The DLL can be in any folder where postgres user has # read/write/execute access is valid # 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" 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.udfSharedLibExt = "dll" else: diff --git a/plugins/dbms/sybase/fingerprint.py b/plugins/dbms/sybase/fingerprint.py index 191104db4..a3aa44179 100644 --- a/plugins/dbms/sybase/fingerprint.py +++ b/plugins/dbms/sybase/fingerprint.py @@ -15,6 +15,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.session import setDbms from lib.core.settings import SYBASE_ALIASES from lib.request import inject @@ -69,7 +70,7 @@ class Fingerprint(GenericFingerprint): self.getBanner() - kb.os = "Windows" + Backend.setOs(OS.WINDOWS) return True diff --git a/plugins/generic/fingerprint.py b/plugins/generic/fingerprint.py index 216efcca9..b8411a0fc 100644 --- a/plugins/generic/fingerprint.py +++ b/plugins/generic/fingerprint.py @@ -11,6 +11,7 @@ from lib.core.common import Backend from lib.core.common import readInput from lib.core.data import kb from lib.core.data import logger +from lib.core.enums import OS from lib.core.exception import sqlmapUndefinedMethod class Fingerprint: @@ -50,10 +51,10 @@ class Fingerprint: os = readInput(msg, default="W") if os[0].lower() == "w": - kb.os = "Windows" + Backend.setOs(OS.WINDOWS) break elif os[0].lower() == "l": - kb.os = "Linux" + Backend.setOs(OS.LINUX) break else: warnMsg = "invalid value" diff --git a/plugins/generic/misc.py b/plugins/generic/misc.py index 0afe6ee98..25a1da5b3 100644 --- a/plugins/generic/misc.py +++ b/plugins/generic/misc.py @@ -21,6 +21,7 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapNoneDataException from lib.core.exception import sqlmapUnsupportedFeatureException @@ -37,13 +38,13 @@ class Miscellaneous: def getRemoteTempPath(self): if not conf.tmpPath: - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): conf.tmpPath = "C:/WINDOWS/Temp" else: conf.tmpPath = "/tmp" if getCompiledRegex("(?i)\A[\w]:[\/\\\\]+").search(conf.tmpPath): - kb.os = "Windows" + Backend.setOs(OS.WINDOWS) conf.tmpPath = normalizePath(conf.tmpPath) conf.tmpPath = ntToPosixSlashes(conf.tmpPath) @@ -80,7 +81,7 @@ class Miscellaneous: def delRemoteFile(self, tempFile): self.checkDbmsOs() - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): tempFile = posixToNtSlashes(tempFile) cmd = "del /F /Q %s" % tempFile else: @@ -100,10 +101,10 @@ class Miscellaneous: if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct: return - if kb.os == "Windows": + if Backend.isOs(OS.WINDOWS): libtype = "dynamic-link library" - elif kb.os == "Linux": + elif Backend.isOs(OS.LINUX): libtype = "shared object" else: diff --git a/plugins/generic/takeover.py b/plugins/generic/takeover.py index c81424f3c..32e55b7bd 100644 --- a/plugins/generic/takeover.py +++ b/plugins/generic/takeover.py @@ -17,6 +17,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.enums import DBMS +from lib.core.enums import OS from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapMissingDependence 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" 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 += "the moment. The back-end database server is " errMsg += "not. sqlmap will fallback to TCP (Metasploit)" @@ -189,13 +190,13 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): self.createMsfPayloadStager() self.uploadMsfPayloadStager() - if kb.os == "Windows" and conf.privEsc: + if Backend.isOs(OS.WINDOWS) and conf.privEsc: if Backend.getIdentifiedDbms() == DBMS.MYSQL: debugMsg = "by default MySQL on Windows runs as SYSTEM " debugMsg += "user, no need to privilege escalate" 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 # system is not Windows conf.privEsc = False @@ -217,7 +218,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): self.initEnv(web=web) 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 # system is not Windows conf.privEsc = False @@ -250,7 +251,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): def osSmb(self): self.checkDbmsOs() - if kb.os != "Windows": + if not Backend.isOs(OS.WINDOWS): errMsg = "the back-end DBMS underlying operating system is " errMsg += "not Windows: it is not possible to perform the SMB " errMsg += "relay attack" @@ -329,7 +330,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous): self.checkDbmsOs() - if kb.os != "Windows": + if not Backend.isOs(OS.WINDOWS): errMsg = "the back-end DBMS underlying operating system is " errMsg += "not Windows" raise sqlmapUnsupportedDBMSException(errMsg)