Adding support for InterSystems Cache (and IRIS)

This commit is contained in:
Miroslav Stampar 2020-02-25 12:36:07 +01:00
parent 5c82f30fd8
commit 7ff77ef052
23 changed files with 459 additions and 36 deletions

View File

@ -1457,4 +1457,64 @@
<blind query="SELECT DISTINCT(owner_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" query2="SELECT DISTINCT(db_class.class_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" count2="SELECT COUNT(DISTINCT(db_class.class_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" condition="attr_name" condition2="owner_name" condition3="db_class.class_name"/> <blind query="SELECT DISTINCT(owner_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" query2="SELECT DISTINCT(db_class.class_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" count2="SELECT COUNT(DISTINCT(db_class.class_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" condition="attr_name" condition2="owner_name" condition3="db_class.class_name"/>
</search_column> </search_column>
</dbms> </dbms>
<dbms value="InterSystems Cache">
<cast query="CAST(%s AS NVARCHAR(4000))"/>
<length query="CHAR_LENGTH(%s)"/>
<isnull query="COALESCE(%s,' ')"/>
<delimiter query="||"/>
<limit query="SELECT TOP %d %s FROM (%s) WHERE %%VID>%d"/>
<limitregexp query="TOP\s+(\d+)\s+.+?\s+FROM\s+.+?\s+WHERE\s+.+%%VID>(\d+)"/>
<limitgroupstart query="2"/>
<limitgroupstop query="1"/>
<limitstring/>
<order query="ORDER BY %s ASC"/>
<count query="COUNT(%s)"/>
<comment query="--" query2=";"/>
<substring query="SUBSTR((%s),%d,%d)"/>
<concatenate query="%s||%s"/>
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
<banner query="$ZVERSION"/>
<current_user query="$USERNAME"/>
<current_db/>
<hostname/>
<table_comment/>
<column_comment/>
<is_dba query="$USERNAME='_SYSTEM'"/>
<check_udf/>
<users/>
<passwords/>
<privileges/>
<roles/>
<statements/>
<dbs>
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA" query2="SELECT db FROM mysql.db"/>
<blind query="SELECT TOP 1 schema_name FROM (SELECT TOP ALL schema_name FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY schema_name) WHERE %%VID=%d" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA"/>
</dbs>
<tables>
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES" condition="table_schema"/>
<blind query="SELECT TOP 1 table_name FROM (SELECT TOP ALL table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' ORDER BY table_name) WHERE %%VID=%d" count="SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'"/>
</tables>
<columns>
<inband query="SELECT column_name,data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
<blind query="SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s' ORDER BY column_name" query2="SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
</columns>
<dump_table>
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
<blind query="SELECT TOP 1 %s FROM (SELECT TOP ALL * FROM %s.%s ORDER BY %s) WHERE %%VID=%d" count="SELECT COUNT(*) FROM %s.%s"/>
</dump_table>
<search_db>
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" query2="SELECT db FROM mysql.db WHERE %s" condition="schema_name" condition2="db"/>
<blind query="SELECT DISTINCT(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" query2="SELECT DISTINCT(db) FROM mysql.db WHERE %s" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" count2="SELECT COUNT(DISTINCT(db)) FROM mysql.db WHERE %s" condition="schema_name" condition2="db"/>
</search_db>
<search_table>
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE %s" condition="table_name" condition2="table_schema"/>
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.TABLES WHERE %s" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.TABLES WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
</search_table>
<search_column>
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" condition="column_name" condition2="table_schema" condition3="table_name"/>
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
</search_column>
</dbms>
</root> </root>

View File

@ -13,6 +13,7 @@ from lib.core.enums import DBMS
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.settings import ACCESS_ALIASES from lib.core.settings import ACCESS_ALIASES
from lib.core.settings import ALTIBASE_ALIASES from lib.core.settings import ALTIBASE_ALIASES
from lib.core.settings import CACHE_ALIASES
from lib.core.settings import CRATEDB_ALIASES from lib.core.settings import CRATEDB_ALIASES
from lib.core.settings import CUBRID_ALIASES from lib.core.settings import CUBRID_ALIASES
from lib.core.settings import DB2_ALIASES from lib.core.settings import DB2_ALIASES
@ -39,6 +40,8 @@ from plugins.dbms.access.connector import Connector as AccessConn
from plugins.dbms.access import AccessMap from plugins.dbms.access import AccessMap
from plugins.dbms.altibase.connector import Connector as AltibaseConn from plugins.dbms.altibase.connector import Connector as AltibaseConn
from plugins.dbms.altibase import AltibaseMap from plugins.dbms.altibase import AltibaseMap
from plugins.dbms.cache.connector import Connector as CacheConn
from plugins.dbms.cache import CacheMap
from plugins.dbms.cratedb.connector import Connector as CrateDBConn from plugins.dbms.cratedb.connector import Connector as CrateDBConn
from plugins.dbms.cratedb import CrateDBMap from plugins.dbms.cratedb import CrateDBMap
from plugins.dbms.cubrid.connector import Connector as CubridConn from plugins.dbms.cubrid.connector import Connector as CubridConn
@ -109,6 +112,7 @@ def setHandler():
(DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn), (DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn),
(DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, CrateDBConn), (DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, CrateDBConn),
(DBMS.CUBRID, CUBRID_ALIASES, CubridMap, CubridConn), (DBMS.CUBRID, CUBRID_ALIASES, CubridMap, CubridConn),
(DBMS.CACHE, CACHE_ALIASES, CacheMap, CacheConn),
] ]
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items) _ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items)

View File

@ -660,7 +660,7 @@ class Agent(object):
elif fieldsNoSelect: elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop) 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, DBMS.CUBRID): 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, DBMS.CACHE):
if fieldsExists: if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop concatenatedQuery += "||'%s'" % kb.chars.stop
@ -1011,6 +1011,15 @@ class Agent(object):
if match: if match:
orderBy = " ORDER BY %s" % match.group(1) orderBy = " ORDER BY %s" % match.group(1)
elif Backend.isDbms(DBMS.CACHE):
match = re.search(r"ORDER BY ([^ ]+)\Z", limitedQuery)
if match:
limitedQuery = re.sub(r"\s*%s\s*" % re.escape(match.group(0)), " ", limitedQuery).strip()
orderBy = " %s" % match.group(0)
field = match.group(1)
limitedQuery = queries[Backend.getIdentifiedDbms()].limit.query % (1, field, limitedQuery, num)
elif Backend.isDbms(DBMS.FIREBIRD): elif Backend.isDbms(DBMS.FIREBIRD):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, num + 1) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, num + 1)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr

View File

@ -4091,7 +4091,7 @@ def safeSQLIdentificatorNaming(name, isTable=False):
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) 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 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): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE):
retVal = "\"%s\"" % retVal retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper() retVal = "\"%s\"" % retVal.upper()
@ -4129,7 +4129,7 @@ def unsafeSQLIdentificatorNaming(name):
if isinstance(name, six.string_types): if isinstance(name, six.string_types):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE):
retVal = name.replace("`", "") 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): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE):
retVal = name.replace("\"", "") retVal = name.replace("\"", "")
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = name.replace("\"", "").upper() retVal = name.replace("\"", "").upper()

View File

@ -12,6 +12,7 @@ from lib.core.enums import POST_HINT
from lib.core.settings import ACCESS_ALIASES from lib.core.settings import ACCESS_ALIASES
from lib.core.settings import ALTIBASE_ALIASES from lib.core.settings import ALTIBASE_ALIASES
from lib.core.settings import BLANK from lib.core.settings import BLANK
from lib.core.settings import CACHE_ALIASES
from lib.core.settings import CRATEDB_ALIASES from lib.core.settings import CRATEDB_ALIASES
from lib.core.settings import CUBRID_ALIASES from lib.core.settings import CUBRID_ALIASES
from lib.core.settings import DB2_ALIASES from lib.core.settings import DB2_ALIASES
@ -123,9 +124,7 @@ ALTIBASE_TYPES = {
-8: "NCHAR", -8: "NCHAR",
-9: "NVARCHAR", -9: "NVARCHAR",
2: "NUMERIC", 2: "NUMERIC",
2: "DECIMAL",
6: "FLOAT", 6: "FLOAT",
6: "NUMBER",
8: "DOUBLE", 8: "DOUBLE",
7: "REAL", 7: "REAL",
-5: "BIGINT", -5: "BIGINT",
@ -240,6 +239,7 @@ DBMS_DICT = {
DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None), DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None),
DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"), DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
DBMS.CUBRID: (CUBRID_ALIASES, "CUBRID-Python", "https://github.com/CUBRID/cubrid-python", None), DBMS.CUBRID: (CUBRID_ALIASES, "CUBRID-Python", "https://github.com/CUBRID/cubrid-python", None),
DBMS.CACHE: (CACHE_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
} }
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/ # Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
@ -273,6 +273,7 @@ HEURISTIC_NULL_EVAL = {
DBMS.MIMERSQL: "ASCII_CHAR(256)", DBMS.MIMERSQL: "ASCII_CHAR(256)",
DBMS.CRATEDB: "MD5(NULL~NULL)", # Note: NULL~NULL also being evaluated on H2 and Ignite DBMS.CRATEDB: "MD5(NULL~NULL)", # Note: NULL~NULL also being evaluated on H2 and Ignite
DBMS.CUBRID: "(NULL SETEQ NULL)", DBMS.CUBRID: "(NULL SETEQ NULL)",
DBMS.CACHE: "%SQLUPPER NULL",
} }
SQL_STATEMENTS = { SQL_STATEMENTS = {

View File

@ -164,7 +164,7 @@ class Dump(object):
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER) self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
def currentDb(self, data): def currentDb(self, data):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB): if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE):
self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB): elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB):
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)

View File

@ -54,6 +54,7 @@ class DBMS(object):
MIMERSQL = "MimerSQL" MIMERSQL = "MimerSQL"
CRATEDB = "CrateDB" CRATEDB = "CrateDB"
CUBRID = "Cubrid" CUBRID = "Cubrid"
CACHE = "InterSystems Cache"
class DBMS_DIRECTORY_NAME(object): class DBMS_DIRECTORY_NAME(object):
ACCESS = "access" ACCESS = "access"
@ -78,6 +79,7 @@ class DBMS_DIRECTORY_NAME(object):
MIMERSQL = "mimersql" MIMERSQL = "mimersql"
CRATEDB = "cratedb" CRATEDB = "cratedb"
CUBRID = "cubrid" CUBRID = "cubrid"
CACHE = "cache"
class FORK(object): class FORK(object):
MARIADB = "MariaDB" MARIADB = "MariaDB"
@ -91,6 +93,8 @@ class FORK(object):
IGNITE = "Apache Ignite" IGNITE = "Apache Ignite"
AURORA = "Aurora" AURORA = "Aurora"
ENTERPRISEDB = "EnterpriseDB" ENTERPRISEDB = "EnterpriseDB"
YELLOWBRICK = "Yellowbrick"
IRIS = "Iris"
class CUSTOM_LOGGING(object): class CUSTOM_LOGGING(object):
PAYLOAD = 9 PAYLOAD = 9

View File

@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.4.2.38" VERSION = "1.4.2.39"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} 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) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@ -268,11 +268,12 @@ ALTIBASE_SYSTEM_DBS = ("SYSTEM_",)
MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",) MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",)
CRATEDB_SYSTEM_DBS = ("information_schema", "pg_catalog", "sys") CRATEDB_SYSTEM_DBS = ("information_schema", "pg_catalog", "sys")
CUBRID_SYSTEM_DBS = ("DBA",) CUBRID_SYSTEM_DBS = ("DBA",)
CACHE_SYSTEM_DBS = ("%Dictionary", "INFORMATION_SCHEMA", "%SYS")
# Note: (<regular>) + (<forks>) # Note: (<regular>) + (<forks>)
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona") MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona")
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb") PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "redshift", "greenplum", "yellowbrick", "enterprisedb", "aurora")
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or") ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
SQLITE_ALIASES = ("sqlite", "sqlite3") SQLITE_ALIASES = ("sqlite", "sqlite3")
ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access") ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access")
@ -292,13 +293,14 @@ ALTIBASE_ALIASES = ("altibase",)
MIMERSQL_ALIASES = ("mimersql", "mimer") MIMERSQL_ALIASES = ("mimersql", "mimer")
CRATEDB_ALIASES = ("cratedb", "crate") CRATEDB_ALIASES = ("cratedb", "crate")
CUBRID_ALIASES = ("cubrid",) CUBRID_ALIASES = ("cubrid",)
CACHE_ALIASES = ("cachedb", "cache")
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_")) 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 + CUBRID_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 + CACHE_ALIASES
SUPPORTED_OS = ("linux", "windows") 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.CUBRID, CUBRID_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), (DBMS.CACHE, CACHE_ALIASES))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent") USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer") REFERER_ALIASES = ("ref", "referer", "referrer")
@ -311,6 +313,10 @@ UPPER_CASE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC" H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
VERTICA_DEFAULT_SCHEMA = "public" VERTICA_DEFAULT_SCHEMA = "public"
MCKOI_DEFAULT_SCHEMA = "APP" MCKOI_DEFAULT_SCHEMA = "APP"
CACHE_DEFAULT_SCHEMA = "SQLUser"
# DBMSes where OFFSET mechanism starts from 1
PLUS_ONE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE, DBMS.MSSQL, DBMS.CACHE))
# Names that can't be used to name files on Windows OS # Names that can't be used to name files on Windows OS
WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9") WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9")

View File

@ -343,7 +343,8 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
# e.g. %20%28%29 # e.g. %20%28%29
if percentDecode: if percentDecode:
if b"%" in page: if b"%" in page:
page = re.sub(b"%([0-9a-fA-F]{2})", lambda _: decodeHex(_.group(1)), page) page = re.sub(b"%([0-9a-f]{2})", lambda _: decodeHex(_.group(1)), page)
page = re.sub(b"%([0-9A-F]{2})", lambda _: decodeHex(_.group(1)), page) # Note: %DeepSee_SQL in CACHE
# e.g. &amp; # e.g. &amp;
page = re.sub(b"&([^;]+);", lambda _: six.int2byte(HTML_ENTITIES[getText(_.group(1))]) if HTML_ENTITIES.get(getText(_.group(1)), 256) < 256 else _.group(0), page) page = re.sub(b"&([^;]+);", lambda _: six.int2byte(HTML_ENTITIES[getText(_.group(1))]) if HTML_ENTITIES.get(getText(_.group(1)), 256) < 256 else _.group(0), page)

View File

@ -41,7 +41,7 @@ def checkDependencies():
__import__("kinterbasdb") __import__("kinterbasdb")
elif dbmsName == DBMS.DB2: elif dbmsName == DBMS.DB2:
__import__("ibm_db_dbi") __import__("ibm_db_dbi")
elif dbmsName == DBMS.HSQLDB: elif dbmsName in (DBMS.HSQLDB, DBMS.CACHE):
__import__("jaydebeapi") __import__("jaydebeapi")
__import__("jpype") __import__("jpype")
elif dbmsName == DBMS.INFORMIX: elif dbmsName == DBMS.INFORMIX:

30
plugins/dbms/cache/__init__.py vendored Normal file
View File

@ -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 CACHE_SYSTEM_DBS
from lib.core.unescaper import unescaper
from plugins.dbms.cache.enumeration import Enumeration
from plugins.dbms.cache.filesystem import Filesystem
from plugins.dbms.cache.fingerprint import Fingerprint
from plugins.dbms.cache.syntax import Syntax
from plugins.dbms.cache.takeover import Takeover
from plugins.generic.misc import Miscellaneous
class CacheMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
"""
This class defines Cache methods
"""
def __init__(self):
self.excludeDbsList = CACHE_SYSTEM_DBS
for cls in self.__class__.__bases__:
cls.__init__(self)
unescaper[DBMS.CACHE] = Syntax.escape

77
plugins/dbms/cache/connector.py vendored Normal file
View File

@ -0,0 +1,77 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
try:
import jaydebeapi
import jpype
except:
pass
import logging
from lib.core.common import checkFile
from lib.core.common import getSafeExString
from lib.core.common import readInput
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://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/
User guide: https://pypi.python.org/pypi/JayDeBeApi/#usage & http://jpype.sourceforge.net/doc/user-guide/userguide.html
API: -
Debian package: -
License: LGPL & Apache License 2.0
"""
def connect(self):
self.initConnection()
try:
msg = "please enter the location of 'cachejdbc.jar'? "
jar = readInput(msg)
checkFile(jar)
args = "-Djava.class.path=%s" % jar
jvm_path = jpype.getDefaultJVMPath()
jpype.startJVM(jvm_path, args)
except Exception as ex:
raise SqlmapConnectionException(getSafeExString(ex))
try:
driver = 'com.intersys.jdbc.CacheDriver'
connection_string = 'jdbc:Cache://%s:%d/%s' % (self.hostname, self.port, self.db)
self.connector = jaydebeapi.connect(driver, connection_string, str(self.user), str(self.password))
except Exception as ex:
raise SqlmapConnectionException(getSafeExString(ex))
self.initCursor()
self.printConnected()
def fetchall(self):
try:
return self.cursor.fetchall()
except Exception as ex:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) '%s'" % getSafeExString(ex))
return None
def execute(self, query):
retVal = False
try:
self.cursor.execute(query)
retVal = True
except Exception as ex:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) '%s'" % getSafeExString(ex))
self.connector.commit()
return retVal
def select(self, query):
self.execute(query)
return self.fetchall()

48
plugins/dbms/cache/enumeration.py vendored Normal file
View File

@ -0,0 +1,48 @@
#!/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 lib.core.settings import CACHE_DEFAULT_SCHEMA
from plugins.generic.enumeration import Enumeration as GenericEnumeration
class Enumeration(GenericEnumeration):
def getCurrentDb(self):
return CACHE_DEFAULT_SCHEMA
def getUsers(self):
warnMsg = "on Cache it is not possible to enumerate the users"
logger.warn(warnMsg)
return []
def getPasswordHashes(self):
warnMsg = "on Cache it is not possible to enumerate password hashes"
logger.warn(warnMsg)
return {}
def getPrivileges(self, *args, **kwargs):
warnMsg = "on Cache it is not possible to enumerate the user privileges"
logger.warn(warnMsg)
return {}
def getStatements(self):
warnMsg = "on Cache it is not possible to enumerate the SQL statements"
logger.warn(warnMsg)
return []
def getRoles(self, *args, **kwargs):
warnMsg = "on Cache it is not possible to enumerate the user roles"
logger.warn(warnMsg)
return {}
def getHostname(self):
warnMsg = "on Cache it is not possible to enumerate the hostname"
logger.warn(warnMsg)

11
plugins/dbms/cache/filesystem.py vendored Normal file
View File

@ -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

113
plugins/dbms/cache/fingerprint.py vendored Normal file
View File

@ -0,0 +1,113 @@
#!/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.common import hashDBRetrieve
from lib.core.common import hashDBWrite
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 FORK
from lib.core.enums import HASHDB_KEYS
from lib.core.session import setDbms
from lib.core.settings import CACHE_ALIASES
from lib.request import inject
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
class Fingerprint(GenericFingerprint):
def __init__(self):
GenericFingerprint.__init__(self, DBMS.CACHE)
def getFingerprint(self):
fork = hashDBRetrieve(HASHDB_KEYS.DBMS_FORK)
if fork is None:
if inject.checkBooleanExpression("$ZVERSION LIKE '%IRIS%'"):
fork = FORK.IRIS
else:
fork = ""
hashDBWrite(HASHDB_KEYS.DBMS_FORK, fork)
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.CACHE
if fork:
value += " (%s fork)" % fork
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)
if fork:
value += "\n%sfork fingerprint: %s" % (blank, fork)
return value
def checkDbms(self):
if not conf.extensiveFp and Backend.isDbmsWithin(CACHE_ALIASES):
setDbms(DBMS.CACHE)
self.getBanner()
return True
infoMsg = "testing %s" % DBMS.CACHE
logger.info(infoMsg)
result = inject.checkBooleanExpression("$LISTLENGTH(NULL) IS NULL")
if result:
infoMsg = "confirming %s" % DBMS.CACHE
logger.info(infoMsg)
result = inject.checkBooleanExpression("%EXTERNAL %INTERNAL NULL IS NULL")
if not result:
warnMsg = "the back-end DBMS is not %s" % DBMS.CACHE
logger.warn(warnMsg)
return False
setDbms(DBMS.CACHE)
self.getBanner()
return True
else:
warnMsg = "the back-end DBMS is not %s" % DBMS.CACHE
logger.warn(warnMsg)
return False

23
plugins/dbms/cache/syntax.py vendored Normal file
View File

@ -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 CHAR(97)||CHAR(98)||CHAR(99)||CHAR(100)||CHAR(101)||CHAR(102)||CHAR(103)||CHAR(104) FROM foobar"
True
"""
def escaper(value):
return "||".join("CHAR(%d)" % _ for _ in getOrds(value))
return Syntax._escape(expression, quote, escaper)

28
plugins/dbms/cache/takeover.py vendored Normal file
View File

@ -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 Cache it is not possible to execute commands"
raise SqlmapUnsupportedFeatureException(errMsg)
def osShell(self):
errMsg = "on Cache it is not possible to execute commands"
raise SqlmapUnsupportedFeatureException(errMsg)
def osPwn(self):
errMsg = "on Cache it is not possible to establish an "
errMsg += "out-of-band connection"
raise SqlmapUnsupportedFeatureException(errMsg)
def osSmb(self):
errMsg = "on Cache it is not possible to establish an "
errMsg += "out-of-band connection"
raise SqlmapUnsupportedFeatureException(errMsg)

View File

@ -71,6 +71,9 @@ class Fingerprint(GenericFingerprint):
if htmlErrorFp: if htmlErrorFp:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp) value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
if fork:
value += "\n%sfork fingerprint: %s" % (blank, fork)
return value return value
def checkDbms(self): def checkDbms(self):

View File

@ -33,7 +33,7 @@ class Connector(GenericConnector):
def connect(self): def connect(self):
self.initConnection() self.initConnection()
try: try:
msg = "what's the location of 'hsqldb.jar'? " msg = "please enter the location of 'hsqldb.jar'? "
jar = readInput(msg) jar = readInput(msg)
checkFile(jar) checkFile(jar)
args = "-Djava.class.path=%s" % jar args = "-Djava.class.path=%s" % jar

View File

@ -35,6 +35,8 @@ class Fingerprint(GenericFingerprint):
fork = FORK.REDSHIFT fork = FORK.REDSHIFT
elif inject.checkBooleanExpression("VERSION() LIKE '%Greenplum%'"): # Reference: http://www.sqldbpros.com/wordpress/wp-content/uploads/2014/08/what-version-of-greenplum.png elif inject.checkBooleanExpression("VERSION() LIKE '%Greenplum%'"): # Reference: http://www.sqldbpros.com/wordpress/wp-content/uploads/2014/08/what-version-of-greenplum.png
fork = FORK.GREENPLUM fork = FORK.GREENPLUM
elif inject.checkBooleanExpression("VERSION() LIKE '%Yellowbrick%'"): # Reference: https://www.yellowbrick.com/docs/3.3/ybd_sqlref/version.html
fork = FORK.YELLOWBRICK
elif inject.checkBooleanExpression("VERSION() LIKE '%EnterpriseDB%'"): # Reference: https://www.enterprisedb.com/edb-docs/d/edb-postgres-advanced-server/user-guides/user-guide/11/EDB_Postgres_Advanced_Server_Guide.1.087.html elif inject.checkBooleanExpression("VERSION() LIKE '%EnterpriseDB%'"): # Reference: https://www.enterprisedb.com/edb-docs/d/edb-postgres-advanced-server/user-guides/user-guide/11/EDB_Postgres_Advanced_Server_Guide.1.087.html
fork = FORK.ENTERPRISEDB fork = FORK.ENTERPRISEDB
elif inject.checkBooleanExpression("AURORA_VERSION() LIKE '%'"): # Reference: https://aws.amazon.com/premiumsupport/knowledge-center/aurora-version-number/ elif inject.checkBooleanExpression("AURORA_VERSION() LIKE '%'"): # Reference: https://aws.amazon.com/premiumsupport/knowledge-center/aurora-version-number/

View File

@ -49,6 +49,7 @@ from lib.core.exception import SqlmapMissingMandatoryOptionException
from lib.core.exception import SqlmapNoneDataException from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import CURRENT_DB from lib.core.settings import CURRENT_DB
from lib.core.settings import PLUS_ONE_DBMSES
from lib.core.settings import REFLECTED_VALUE_MARKER from lib.core.settings import REFLECTED_VALUE_MARKER
from lib.core.settings import UPPER_CASE_DBMSES from lib.core.settings import UPPER_CASE_DBMSES
from lib.core.settings import VERTICA_DEFAULT_SCHEMA from lib.core.settings import VERTICA_DEFAULT_SCHEMA
@ -84,13 +85,13 @@ class Databases(object):
if not kb.data.currentDb and Backend.isDbms(DBMS.VERTICA): if not kb.data.currentDb and Backend.isDbms(DBMS.VERTICA):
kb.data.currentDb = VERTICA_DEFAULT_SCHEMA kb.data.currentDb = VERTICA_DEFAULT_SCHEMA
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CRATEDB): if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CACHE):
warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms() warnMsg = "on '%s' you'll need to use " % Backend.getIdentifiedDbms()
warnMsg += "schema names for enumeration as the counterpart to database " warnMsg += "schema names for enumeration as the counterpart to database "
warnMsg += "names on other DBMSes" warnMsg += "names on other DBMSes"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.CUBRID): elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.CUBRID):
warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms() warnMsg = "on '%s' you'll need to use " % Backend.getIdentifiedDbms()
warnMsg += "user names for enumeration as the counterpart to database " warnMsg += "user names for enumeration as the counterpart to database "
warnMsg += "names on other DBMSes" warnMsg += "names on other DBMSes"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
@ -109,8 +110,8 @@ class Databases(object):
warnMsg += "names will be fetched from 'mysql' database" warnMsg += "names will be fetched from 'mysql' database"
logger.warn(warnMsg) logger.warn(warnMsg)
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CRATEDB): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CACHE):
warnMsg = "schema names are going to be used on %s " % Backend.getIdentifiedDbms() warnMsg = "schema names are going to be used on '%s' " % Backend.getIdentifiedDbms()
warnMsg += "for enumeration as the counterpart to database " warnMsg += "for enumeration as the counterpart to database "
warnMsg += "names on other DBMSes" warnMsg += "names on other DBMSes"
logger.warn(warnMsg) logger.warn(warnMsg)
@ -118,7 +119,7 @@ class Databases(object):
infoMsg = "fetching database (schema) names" infoMsg = "fetching database (schema) names"
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.CUBRID): elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.CUBRID):
warnMsg = "user names are going to be used on %s " % Backend.getIdentifiedDbms() warnMsg = "user names are going to be used on '%s' " % Backend.getIdentifiedDbms()
warnMsg += "for enumeration as the counterpart to database " warnMsg += "for enumeration as the counterpart to database "
warnMsg += "names on other DBMSes" warnMsg += "names on other DBMSes"
logger.warn(warnMsg) logger.warn(warnMsg)
@ -157,7 +158,7 @@ class Databases(object):
errMsg = "unable to retrieve the number of databases" errMsg = "unable to retrieve the number of databases"
logger.error(errMsg) logger.error(errMsg)
else: else:
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE) plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
indexRange = getLimitRange(count, plusOne=plusOne) indexRange = getLimitRange(count, plusOne=plusOne)
for index in indexRange: for index in indexRange:
@ -342,7 +343,7 @@ class Databases(object):
infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db) infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db)
logger.info(infoMsg) logger.info(infoMsg)
else: else:
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms() warnMsg = "on '%s' it is not " % Backend.getIdentifiedDbms()
warnMsg += "possible to get table comments" warnMsg += "possible to get table comments"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
@ -388,7 +389,7 @@ class Databases(object):
tables = [] tables = []
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE) plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
indexRange = getLimitRange(count, plusOne=plusOne) indexRange = getLimitRange(count, plusOne=plusOne)
for index in indexRange: for index in indexRange:
@ -424,7 +425,7 @@ class Databases(object):
infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db) infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db)
logger.info(infoMsg) logger.info(infoMsg)
else: else:
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms() warnMsg = "on '%s' it is not " % Backend.getIdentifiedDbms()
warnMsg += "possible to get table comments" warnMsg += "possible to get table comments"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
@ -604,7 +605,7 @@ class Databases(object):
condQueryStr = "%%s%s" % colCondParam condQueryStr = "%%s%s" % colCondParam
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList)) condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE):
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db)) query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery query += condQuery
@ -697,7 +698,7 @@ class Databases(object):
infoMsg = "retrieved comment '%s' for column '%s'" % (comment, name) infoMsg = "retrieved comment '%s' for column '%s'" % (comment, name)
logger.info(infoMsg) logger.info(infoMsg)
else: else:
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms() warnMsg = "on '%s' it is not " % Backend.getIdentifiedDbms()
warnMsg += "possible to get column comments" warnMsg += "possible to get column comments"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
@ -751,7 +752,7 @@ class Databases(object):
condQueryStr = "%%s%s" % colCondParam condQueryStr = "%%s%s" % colCondParam
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList)) condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE):
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db)) query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery query += condQuery
@ -818,7 +819,7 @@ class Databases(object):
continue continue
for index in getLimitRange(count): for index in getLimitRange(count):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE):
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db)) query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery query += condQuery
field = None field = None
@ -867,12 +868,12 @@ class Databases(object):
infoMsg = "retrieved comment '%s' for column '%s'" % (comment, column) infoMsg = "retrieved comment '%s' for column '%s'" % (comment, column)
logger.info(infoMsg) logger.info(infoMsg)
else: else:
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms() warnMsg = "on '%s' it is not " % Backend.getIdentifiedDbms()
warnMsg += "possible to get column comments" warnMsg += "possible to get column comments"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
if not onlyColNames: if not onlyColNames:
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE):
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db)) query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper())) query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))
@ -1058,7 +1059,7 @@ class Databases(object):
errMsg = "unable to retrieve the number of statements" errMsg = "unable to retrieve the number of statements"
raise SqlmapNoneDataException(errMsg) raise SqlmapNoneDataException(errMsg)
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE) plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
indexRange = getLimitRange(count, plusOne=plusOne) indexRange = getLimitRange(count, plusOne=plusOne)
for index in indexRange: for index in indexRange:

View File

@ -43,6 +43,7 @@ from lib.core.exception import SqlmapUnsupportedFeatureException
from lib.core.settings import CHECK_ZERO_COLUMNS_THRESHOLD from lib.core.settings import CHECK_ZERO_COLUMNS_THRESHOLD
from lib.core.settings import CURRENT_DB from lib.core.settings import CURRENT_DB
from lib.core.settings import NULL from lib.core.settings import NULL
from lib.core.settings import PLUS_ONE_DBMSES
from lib.core.settings import UPPER_CASE_DBMSES from lib.core.settings import UPPER_CASE_DBMSES
from lib.request import inject from lib.request import inject
from lib.utils.hash import attackDumpedTable from lib.utils.hash import attackDumpedTable
@ -233,7 +234,7 @@ class Entries(object):
entries = BigArray(_zip(*[entries[colName] for colName in colList])) entries = BigArray(_zip(*[entries[colName] for colName in colList]))
else: else:
query = rootQuery.inband.query % (colString, conf.db, tbl) query = rootQuery.inband.query % (colString, conf.db, tbl)
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB): elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE):
query = rootQuery.inband.query % (colString, conf.db, tbl, prioritySortColumns(colList)[0]) query = rootQuery.inband.query % (colString, conf.db, tbl, prioritySortColumns(colList)[0])
else: else:
query = rootQuery.inband.query % (colString, conf.db, tbl) query = rootQuery.inband.query % (colString, conf.db, tbl)
@ -379,7 +380,7 @@ class Entries(object):
else: else:
emptyColumns = [] emptyColumns = []
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE) plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
indexRange = getLimitRange(count, plusOne=plusOne) indexRange = getLimitRange(count, plusOne=plusOne)
if len(colList) < len(indexRange) > CHECK_ZERO_COLUMNS_THRESHOLD: if len(colList) < len(indexRange) > CHECK_ZERO_COLUMNS_THRESHOLD:
@ -404,7 +405,7 @@ class Entries(object):
if column not in entries: if column not in entries:
entries[column] = BigArray() entries[column] = BigArray()
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE):
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, sorted(colList, key=len)[0], index) query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, sorted(colList, key=len)[0], index)
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE,): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE,):
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index) query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index)

View File

@ -41,6 +41,7 @@ from lib.core.enums import PAYLOAD
from lib.core.exception import SqlmapNoneDataException from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import CURRENT_USER from lib.core.settings import CURRENT_USER
from lib.core.settings import PLUS_ONE_DBMSES
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
from lib.request import inject from lib.request import inject
from lib.utils.hash import attackCachedUsersPasswords from lib.utils.hash import attackCachedUsersPasswords
@ -140,7 +141,7 @@ class Users(object):
errMsg = "unable to retrieve the number of database users" errMsg = "unable to retrieve the number of database users"
raise SqlmapNoneDataException(errMsg) raise SqlmapNoneDataException(errMsg)
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE) plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
indexRange = getLimitRange(count, plusOne=plusOne) indexRange = getLimitRange(count, plusOne=plusOne)
for index in indexRange: for index in indexRange:
@ -308,7 +309,7 @@ class Users(object):
passwords = [] passwords = []
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE) plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
indexRange = getLimitRange(count, plusOne=plusOne) indexRange = getLimitRange(count, plusOne=plusOne)
for index in indexRange: for index in indexRange:
@ -556,7 +557,7 @@ class Users(object):
privileges = set() privileges = set()
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE) plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
indexRange = getLimitRange(count, plusOne=plusOne) indexRange = getLimitRange(count, plusOne=plusOne)
for index in indexRange: for index in indexRange: