From 264a270985f9fe5c4797d0cc880997ce47b380e6 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Mon, 3 Feb 2020 01:58:12 +0100 Subject: [PATCH] Adding initial support for Cubrid --- data/xml/queries.xml | 67 +++++++++++++++++++++ lib/controller/handler.py | 4 ++ lib/core/agent.py | 6 +- lib/core/common.py | 4 +- lib/core/dicts.py | 3 + lib/core/enums.py | 2 + lib/core/settings.py | 8 ++- lib/utils/deps.py | 2 + plugins/dbms/cubrid/__init__.py | 30 ++++++++++ plugins/dbms/cubrid/connector.py | 59 +++++++++++++++++++ plugins/dbms/cubrid/enumeration.py | 32 ++++++++++ plugins/dbms/cubrid/filesystem.py | 11 ++++ plugins/dbms/cubrid/fingerprint.py | 94 ++++++++++++++++++++++++++++++ plugins/dbms/cubrid/syntax.py | 23 ++++++++ plugins/dbms/cubrid/takeover.py | 28 +++++++++ plugins/generic/databases.py | 4 +- 16 files changed, 367 insertions(+), 10 deletions(-) create mode 100644 plugins/dbms/cubrid/__init__.py create mode 100644 plugins/dbms/cubrid/connector.py create mode 100644 plugins/dbms/cubrid/enumeration.py create mode 100644 plugins/dbms/cubrid/filesystem.py create mode 100644 plugins/dbms/cubrid/fingerprint.py create mode 100644 plugins/dbms/cubrid/syntax.py create mode 100644 plugins/dbms/cubrid/takeover.py diff --git a/data/xml/queries.xml b/data/xml/queries.xml index 3677a5151..6bd4ec287 100644 --- a/data/xml/queries.xml +++ b/data/xml/queries.xml @@ -1381,4 +1381,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/controller/handler.py b/lib/controller/handler.py index 7c3ed9e2b..97f87c407 100644 --- a/lib/controller/handler.py +++ b/lib/controller/handler.py @@ -14,6 +14,7 @@ from lib.core.exception import SqlmapConnectionException from lib.core.settings import ACCESS_ALIASES from lib.core.settings import ALTIBASE_ALIASES from lib.core.settings import CRATEDB_ALIASES +from lib.core.settings import CUBRID_ALIASES from lib.core.settings import DB2_ALIASES from lib.core.settings import DERBY_ALIASES from lib.core.settings import FIREBIRD_ALIASES @@ -40,6 +41,8 @@ from plugins.dbms.altibase.connector import Connector as AltibaseConn from plugins.dbms.altibase import AltibaseMap from plugins.dbms.cratedb.connector import Connector as CrateDBConn from plugins.dbms.cratedb import CrateDBMap +from plugins.dbms.cubrid.connector import Connector as CubridConn +from plugins.dbms.cubrid import CubridMap from plugins.dbms.db2.connector import Connector as DB2Conn from plugins.dbms.db2 import DB2Map from plugins.dbms.derby.connector import Connector as DerbyConn @@ -105,6 +108,7 @@ def setHandler(): (DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn), (DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn), (DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, CrateDBConn), + (DBMS.CUBRID, CUBRID_ALIASES, CubridMap, CubridConn), ] _ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items) diff --git a/lib/core/agent.py b/lib/core/agent.py index 3e260637a..2d792e459 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -301,7 +301,7 @@ class Agent(object): comment = getTechniqueData().comment if comment is None else comment if any((comment or "").startswith(_) for _ in ("--", GENERIC_SQL_COMMENT_MARKER)): - if not GENERIC_SQL_COMMENT.startswith(queries[Backend.getIdentifiedDbms()].comment.query): + if Backend.getIdentifiedDbms() and not GENERIC_SQL_COMMENT.startswith(queries[Backend.getIdentifiedDbms()].comment.query): comment = queries[Backend.getIdentifiedDbms()].comment.query if comment is not None: @@ -660,7 +660,7 @@ class Agent(object): elif fieldsNoSelect: concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop) - elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB): + elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID): if fieldsExists: concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery += "||'%s'" % kb.chars.stop @@ -949,7 +949,7 @@ class Agent(object): fromFrom = limitedQuery[fromIndex + 1:] orderBy = None - if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL): + if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID): limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1) limitedQuery += " %s" % limitStr diff --git a/lib/core/common.py b/lib/core/common.py index 57b16ff48..e498e5d8a 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -4076,7 +4076,7 @@ def safeSQLIdentificatorNaming(name, isTable=False): if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal) retVal = unsafeSQLIdentificatorNaming(retVal) - if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users) + if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users) retVal = "`%s`" % retVal elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB): retVal = "\"%s\"" % retVal @@ -4114,7 +4114,7 @@ def unsafeSQLIdentificatorNaming(name): retVal = name if isinstance(name, six.string_types): - if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.SQLITE): + if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): retVal = name.replace("`", "") elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB): retVal = name.replace("\"", "") diff --git a/lib/core/dicts.py b/lib/core/dicts.py index 5c18d74d0..24e8c5790 100644 --- a/lib/core/dicts.py +++ b/lib/core/dicts.py @@ -13,6 +13,7 @@ from lib.core.settings import ACCESS_ALIASES from lib.core.settings import ALTIBASE_ALIASES from lib.core.settings import BLANK from lib.core.settings import CRATEDB_ALIASES +from lib.core.settings import CUBRID_ALIASES from lib.core.settings import DB2_ALIASES from lib.core.settings import DERBY_ALIASES from lib.core.settings import FIREBIRD_ALIASES @@ -214,6 +215,7 @@ DBMS_DICT = { DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None), DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None), DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"), + DBMS.CUBRID: (CUBRID_ALIASES, "CUBRID-Python", "https://github.com/CUBRID/cubrid-python", None), } # Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/ @@ -245,6 +247,7 @@ HEURISTIC_NULL_EVAL = { DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)", DBMS.MIMERSQL: "ASCII_CHAR(256)", DBMS.CRATEDB: "(NULL~NULL)", + DBMS.CUBRID: "(NULL SETEQ NULL)", } SQL_STATEMENTS = { diff --git a/lib/core/enums.py b/lib/core/enums.py index f8f8aa7f8..ffefec653 100644 --- a/lib/core/enums.py +++ b/lib/core/enums.py @@ -53,6 +53,7 @@ class DBMS(object): ALTIBASE = "Altibase" MIMERSQL = "MimerSQL" CRATEDB = "CrateDB" + CUBRID = "Cubrid" class DBMS_DIRECTORY_NAME(object): ACCESS = "access" @@ -76,6 +77,7 @@ class DBMS_DIRECTORY_NAME(object): ALTIBASE = "altibase" MIMERSQL = "mimersql" CRATEDB = "cratedb" + CUBRID = "cubrid" class FORK(object): MARIADB = "MariaDB" diff --git a/lib/core/settings.py b/lib/core/settings.py index c06875c3f..fbd8360a5 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -18,7 +18,7 @@ from lib.core.enums import OS from thirdparty.six import unichr as _unichr # sqlmap version (...) -VERSION = "1.4.2.6" +VERSION = "1.4.2.7" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) @@ -267,6 +267,7 @@ PRESTO_SYSTEM_DBS = ("information_schema",) ALTIBASE_SYSTEM_DBS = ("SYSTEM_",) MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",) CRATEDB_SYSTEM_DBS = ("information_schema", "pg_catalog", "sys") +CUBRID_SYSTEM_DBS = ("",) # Note: () + () MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") @@ -290,13 +291,14 @@ PRESTO_ALIASES = ("presto",) ALTIBASE_ALIASES = ("altibase",) MIMERSQL_ALIASES = ("mimersql", "mimer") CRATEDB_ALIASES = ("cratedb", "crate") +CUBRID_ALIASES = ("cubrid",) DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_")) -SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES +SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_ALIASES SUPPORTED_OS = ("linux", "windows") -DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES)) +DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES)) USER_AGENT_ALIASES = ("ua", "useragent", "user-agent") REFERER_ALIASES = ("ref", "referer", "referrer") diff --git a/lib/utils/deps.py b/lib/utils/deps.py index 3fbb822f8..1c330931d 100644 --- a/lib/utils/deps.py +++ b/lib/utils/deps.py @@ -56,6 +56,8 @@ def checkDependencies(): __import__("prestodb") elif dbmsName == DBMS.MIMERSQL: __import__("mimerpy") + elif dbmsName == DBMS.CUBRID: + __import__("CUBRIDdb") except: warnMsg = "sqlmap requires '%s' third-party library " % data[1] warnMsg += "in order to directly connect to the DBMS " diff --git a/plugins/dbms/cubrid/__init__.py b/plugins/dbms/cubrid/__init__.py new file mode 100644 index 000000000..73dacb32e --- /dev/null +++ b/plugins/dbms/cubrid/__init__.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +from lib.core.enums import DBMS +from lib.core.settings import CUBRID_SYSTEM_DBS +from lib.core.unescaper import unescaper + +from plugins.dbms.cubrid.enumeration import Enumeration +from plugins.dbms.cubrid.filesystem import Filesystem +from plugins.dbms.cubrid.fingerprint import Fingerprint +from plugins.dbms.cubrid.syntax import Syntax +from plugins.dbms.cubrid.takeover import Takeover +from plugins.generic.misc import Miscellaneous + +class CubridMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover): + """ + This class defines Cubrid methods + """ + + def __init__(self): + self.excludeDbsList = CUBRID_SYSTEM_DBS + + for cls in self.__class__.__bases__: + cls.__init__(self) + + unescaper[DBMS.CUBRID] = Syntax.escape diff --git a/plugins/dbms/cubrid/connector.py b/plugins/dbms/cubrid/connector.py new file mode 100644 index 000000000..6f0850464 --- /dev/null +++ b/plugins/dbms/cubrid/connector.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +try: + import CUBRIDdb +except: + pass + +import logging + +from lib.core.common import getSafeExString +from lib.core.data import conf +from lib.core.data import logger +from lib.core.exception import SqlmapConnectionException +from plugins.generic.connector import Connector as GenericConnector + +class Connector(GenericConnector): + """ + Homepage: https://github.com/CUBRID/cubrid-python + User guide: https://github.com/CUBRID/cubrid-python/blob/develop/README.md + API: https://www.python.org/dev/peps/pep-0249/ + License: BSD License + """ + + def connect(self): + self.initConnection() + + try: + self.connector = CUBRIDdb.connect(hostname=self.hostname, username=self.user, password=self.password, database=self.db, port=self.port, connect_timeout=conf.timeout) + except CUBRIDdb.DatabaseError as ex: + raise SqlmapConnectionException(getSafeExString(ex)) + + self.initCursor() + self.printConnected() + + def fetchall(self): + try: + return self.cursor.fetchall() + except CUBRIDdb.DatabaseError as ex: + logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex)) + return None + + def execute(self, query): + try: + self.cursor.execute(query) + except CUBRIDdb.DatabaseError as ex: + logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex)) + except CUBRIDdb.Error as ex: + raise SqlmapConnectionException(getSafeExString(ex)) + + self.connector.commit() + + def select(self, query): + self.execute(query) + return self.fetchall() diff --git a/plugins/dbms/cubrid/enumeration.py b/plugins/dbms/cubrid/enumeration.py new file mode 100644 index 000000000..c41565ac6 --- /dev/null +++ b/plugins/dbms/cubrid/enumeration.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +from lib.core.data import logger +from plugins.generic.enumeration import Enumeration as GenericEnumeration + +class Enumeration(GenericEnumeration): + def getPasswordHashes(self): + warnMsg = "on Cubrid it is not possible to enumerate password hashes" + logger.warn(warnMsg) + + return {} + + def getStatements(self): + warnMsg = "on Cubrid it is not possible to enumerate the SQL statements" + logger.warn(warnMsg) + + return [] + + def getRoles(self, *args, **kwargs): + warnMsg = "on Cubrid it is not possible to enumerate the user roles" + logger.warn(warnMsg) + + return {} + + def getHostname(self): + warnMsg = "on Cubrid it is not possible to enumerate the hostname" + logger.warn(warnMsg) diff --git a/plugins/dbms/cubrid/filesystem.py b/plugins/dbms/cubrid/filesystem.py new file mode 100644 index 000000000..e8c642492 --- /dev/null +++ b/plugins/dbms/cubrid/filesystem.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +from plugins.generic.filesystem import Filesystem as GenericFilesystem + +class Filesystem(GenericFilesystem): + pass diff --git a/plugins/dbms/cubrid/fingerprint.py b/plugins/dbms/cubrid/fingerprint.py new file mode 100644 index 000000000..8ee033e20 --- /dev/null +++ b/plugins/dbms/cubrid/fingerprint.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +from lib.core.common import Backend +from lib.core.common import Format +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.session import setDbms +from lib.core.settings import CUBRID_ALIASES +from lib.request import inject +from plugins.generic.fingerprint import Fingerprint as GenericFingerprint + +class Fingerprint(GenericFingerprint): + def __init__(self): + GenericFingerprint.__init__(self, DBMS.CUBRID) + + def getFingerprint(self): + value = "" + wsOsFp = Format.getOs("web server", kb.headersFp) + + if wsOsFp: + value += "%s\n" % wsOsFp + + if kb.data.banner: + dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp) + + if dbmsOsFp: + value += "%s\n" % dbmsOsFp + + value += "back-end DBMS: " + + if not conf.extensiveFp: + value += DBMS.CUBRID + return value + + actVer = Format.getDbms() + blank = " " * 15 + value += "active fingerprint: %s" % actVer + + if kb.bannerFp: + banVer = kb.bannerFp.get("dbmsVersion") + + if banVer: + banVer = Format.getDbms([banVer]) + value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer) + + htmlErrorFp = Format.getErrorParsedDBMSes() + + if htmlErrorFp: + value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp) + + return value + + def checkDbms(self): + if not conf.extensiveFp and Backend.isDbmsWithin(CUBRID_ALIASES): + setDbms(DBMS.CUBRID) + + self.getBanner() + + return True + + infoMsg = "testing %s" % DBMS.CUBRID + logger.info(infoMsg) + + result = inject.checkBooleanExpression("{} SUBSETEQ (CAST ({} AS SET))") + + if result: + infoMsg = "confirming %s" % DBMS.CUBRID + logger.info(infoMsg) + + result = inject.checkBooleanExpression("DRAND()<2") + + if not result: + warnMsg = "the back-end DBMS is not %s" % DBMS.CUBRID + logger.warn(warnMsg) + + return False + + setDbms(DBMS.CUBRID) + + self.getBanner() + + return True + else: + warnMsg = "the back-end DBMS is not %s" % DBMS.CUBRID + logger.warn(warnMsg) + + return False diff --git a/plugins/dbms/cubrid/syntax.py b/plugins/dbms/cubrid/syntax.py new file mode 100644 index 000000000..72211de38 --- /dev/null +++ b/plugins/dbms/cubrid/syntax.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +from lib.core.convert import getOrds +from plugins.generic.syntax import Syntax as GenericSyntax + +class Syntax(GenericSyntax): + @staticmethod + def escape(expression, quote=True): + """ + >>> from lib.core.common import Backend + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHR(97)||CHR(98)||CHR(99)||CHR(100)||CHR(101)||CHR(102)||CHR(103)||CHR(104) FROM foobar" + True + """ + + def escaper(value): + return "||".join("CHR(%d)" % _ for _ in getOrds(value)) + + return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/cubrid/takeover.py b/plugins/dbms/cubrid/takeover.py new file mode 100644 index 000000000..26b16de10 --- /dev/null +++ b/plugins/dbms/cubrid/takeover.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +from lib.core.exception import SqlmapUnsupportedFeatureException +from plugins.generic.takeover import Takeover as GenericTakeover + +class Takeover(GenericTakeover): + def osCmd(self): + errMsg = "on Cubrid it is not possible to execute commands" + raise SqlmapUnsupportedFeatureException(errMsg) + + def osShell(self): + errMsg = "on Cubrid it is not possible to execute commands" + raise SqlmapUnsupportedFeatureException(errMsg) + + def osPwn(self): + errMsg = "on Cubrid it is not possible to establish an " + errMsg += "out-of-band connection" + raise SqlmapUnsupportedFeatureException(errMsg) + + def osSmb(self): + errMsg = "on Cubrid it is not possible to establish an " + errMsg += "out-of-band connection" + raise SqlmapUnsupportedFeatureException(errMsg) diff --git a/plugins/generic/databases.py b/plugins/generic/databases.py index 6bf03dce6..fa8395a55 100644 --- a/plugins/generic/databases.py +++ b/plugins/generic/databases.py @@ -87,7 +87,7 @@ class Databases(object): warnMsg += "schema names for enumeration as the counterpart to database " warnMsg += "names on other DBMSes" singleTimeWarnMessage(warnMsg) - elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE,): + elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.CUBRID): warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms() warnMsg += "user names for enumeration as the counterpart to database " warnMsg += "names on other DBMSes" @@ -115,7 +115,7 @@ class Databases(object): infoMsg = "fetching database (schema) names" - elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE,): + elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.CUBRID): warnMsg = "user names are going to be used on %s " % Backend.getIdentifiedDbms() warnMsg += "for enumeration as the counterpart to database " warnMsg += "names on other DBMSes"