Adding support for CrateDB

This commit is contained in:
Miroslav Stampar 2020-02-02 14:51:24 +01:00
parent e448905eb1
commit 0e4232f533
21 changed files with 401 additions and 60 deletions

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<root> <root>
<!-- MySQL -->
<dbms value="MySQL"> <dbms value="MySQL">
<!-- http://dba.fyicenter.com/faq/mysql/Difference-between-CHAR-and-NCHAR.html --> <!-- http://dba.fyicenter.com/faq/mysql/Difference-between-CHAR-and-NCHAR.html -->
<cast query="CAST(%s AS NCHAR)"/> <cast query="CAST(%s AS NCHAR)"/>
@ -78,7 +77,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- PostgreSQL -->
<dbms value="PostgreSQL"> <dbms value="PostgreSQL">
<cast query="CAST(%s AS CHARACTER(10000))"/> <cast query="CAST(%s AS CHARACTER(10000))"/>
<length query="LENGTH(%s)"/> <length query="LENGTH(%s)"/>
@ -153,7 +151,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- Microsoft SQL Server -->
<dbms value="Microsoft SQL Server"> <dbms value="Microsoft SQL Server">
<cast query="CAST(%s AS NVARCHAR(4000))"/> <cast query="CAST(%s AS NVARCHAR(4000))"/>
<length query="LTRIM(STR(LEN(%s)))"/> <length query="LTRIM(STR(LEN(%s)))"/>
@ -225,7 +222,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- Oracle -->
<dbms value="Oracle"> <dbms value="Oracle">
<cast query="CAST(%s AS VARCHAR(4000))"/> <cast query="CAST(%s AS VARCHAR(4000))"/>
<length query="LENGTH(%s)"/> <length query="LENGTH(%s)"/>
@ -322,7 +318,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- SQLite -->
<dbms value="SQLite"> <dbms value="SQLite">
<cast query="CAST(%s AS TEXT)" dbms_version="&gt;=3.0"/> <cast query="CAST(%s AS TEXT)" dbms_version="&gt;=3.0"/>
<!-- NOTE: On SQLite version 2 everything is stored as a string (Reference: http://www.mono-project.com/SQLite) --> <!-- NOTE: On SQLite version 2 everything is stored as a string (Reference: http://www.mono-project.com/SQLite) -->
@ -376,7 +371,6 @@
<search_column/> <search_column/>
</dbms> </dbms>
<!-- Microsoft Access -->
<dbms value="Microsoft Access"> <dbms value="Microsoft Access">
<cast query="RTRIM(CVAR(%s))"/> <cast query="RTRIM(CVAR(%s))"/>
<length query="LEN(RTRIM(CVAR(%s)))"/> <length query="LEN(RTRIM(CVAR(%s)))"/>
@ -421,7 +415,6 @@
<search_column/> <search_column/>
</dbms> </dbms>
<!-- Firebird -->
<dbms value="Firebird"> <dbms value="Firebird">
<cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/> <cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/>
<length query="CHAR_LENGTH(TRIM(%s))"/> <length query="CHAR_LENGTH(TRIM(%s))"/>
@ -478,12 +471,6 @@
<search_column/> <search_column/>
</dbms> </dbms>
<!-- SAP MaxDB -->
<!-- http://dev.mysql.com/tech-resources/articles/maxdb-php-ready-for-web.html -->
<!-- http://dev.mysql.com/doc/refman/5.0/es/maxdb-reserved-words.html -->
<!-- http://maxdb.sap.com/doc/7_6/default.htm -->
<!-- http://www.sapdb.org/7.4/htmhelp/35/f8823cb7e5d42be10000000a114027/content.htm -->
<!-- http://www.ximido.de/research/PenTestingMaxDB.pdf -->
<dbms value="SAP MaxDB"> <dbms value="SAP MaxDB">
<length query="LENGTH(%s)"/> <length query="LENGTH(%s)"/>
<isnull query="VALUE(%s,' ')" query2="IFNULL(%s,' ')"/> <isnull query="VALUE(%s,' ')" query2="IFNULL(%s,' ')"/>
@ -536,7 +523,6 @@
</dump_table> </dump_table>
</dbms> </dbms>
<!-- Sybase -->
<dbms value="Sybase"> <dbms value="Sybase">
<cast query="CONVERT(VARCHAR(4000),%s)"/> <cast query="CONVERT(VARCHAR(4000),%s)"/>
<length query="LTRIM(STR(LEN(%s)))"/> <length query="LTRIM(STR(LEN(%s)))"/>
@ -606,7 +592,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- IBM DB2 -->
<dbms value="IBM DB2"> <dbms value="IBM DB2">
<!-- Casting to varchar does not work with version < v9, so we had to use char(254) instead --> <!-- Casting to varchar does not work with version < v9, so we had to use char(254) instead -->
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/> <cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
@ -679,7 +664,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- Hyper SQL Database -->
<dbms value="HSQLDB"> <dbms value="HSQLDB">
<cast query="CAST(%s AS LONGVARCHAR)"/> <cast query="CAST(%s AS LONGVARCHAR)"/>
<length query="CHAR_LENGTH(%s)"/> <length query="CHAR_LENGTH(%s)"/>
@ -813,9 +797,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- Informix -->
<!-- https://www.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.sqlr.doc/ids_sqr_072.htm -->
<!-- https://www.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sec.doc/ids_am_041.htm -->
<dbms value="Informix"> <dbms value="Informix">
<cast query="RTRIM(TO_CHAR(%s))"/> <cast query="RTRIM(TO_CHAR(%s))"/>
<length query="CHAR_LENGTH(RTRIM(%s))"/> <length query="CHAR_LENGTH(RTRIM(%s))"/>
@ -877,7 +858,6 @@
<search_column/> <search_column/>
</dbms> </dbms>
<!-- MonetDB -->
<dbms value="MonetDB"> <dbms value="MonetDB">
<cast query="CAST(%s AS VARCHAR(4000))"/> <cast query="CAST(%s AS VARCHAR(4000))"/>
<length query="LENGTH(%s)"/> <length query="LENGTH(%s)"/>
@ -942,7 +922,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- Apache Derby -->
<dbms value="Apache Derby"> <dbms value="Apache Derby">
<!-- NOTE: CHAR(%s) causes 'A truncation error was encountered trying to shrink CHAR' --> <!-- NOTE: CHAR(%s) causes 'A truncation error was encountered trying to shrink CHAR' -->
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/> <cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
@ -1011,7 +990,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- Vertica -->
<dbms value="Vertica"> <dbms value="Vertica">
<cast query="CAST(%s AS CHARACTER(10000))"/> <cast query="CAST(%s AS CHARACTER(10000))"/>
<length query="LENGTH(%s)"/> <length query="LENGTH(%s)"/>
@ -1088,9 +1066,8 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- Mckoi -->
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
<dbms value="Mckoi"> <dbms value="Mckoi">
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
<cast query="CONCAT('',%s)"/> <cast query="CONCAT('',%s)"/>
<length query="LENGTH(%s)"/> <length query="LENGTH(%s)"/>
<isnull query="IF(%s IS NULL,' ', %s)"/> <isnull query="IF(%s IS NULL,' ', %s)"/>
@ -1130,7 +1107,6 @@
<search_column/> <search_column/>
</dbms> </dbms>
<!-- Presto -->
<dbms value="Presto"> <dbms value="Presto">
<cast query="CAST(%s AS VARCHAR(4000))"/> <cast query="CAST(%s AS VARCHAR(4000))"/>
<length query="LENGTH(%s)"/> <length query="LENGTH(%s)"/>
@ -1192,7 +1168,6 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- Altibase -->
<dbms value="Altibase"> <dbms value="Altibase">
<cast query="CAST(%s AS VARCHAR(4000))"/> <cast query="CAST(%s AS VARCHAR(4000))"/>
<length query="LENGTH(%s)"/> <length query="LENGTH(%s)"/>
@ -1265,9 +1240,8 @@
</search_column> </search_column>
</dbms> </dbms>
<!-- MimerSQL -->
<!-- NOTE: DBMS with stohastic output of rows (ORDER BY required) -->
<dbms value="MimerSQL"> <dbms value="MimerSQL">
<!-- NOTE: DBMS with stohastic output of rows (ORDER BY required) -->
<!-- NOTE: NVARCHAR(4000) causes problems in boolean (e.g. 'Required temporary table row length is 32006, only 32000 is possible') --> <!-- NOTE: NVARCHAR(4000) causes problems in boolean (e.g. 'Required temporary table row length is 32006, only 32000 is possible') -->
<cast query="CAST(%s AS NVARCHAR(1000))"/> <cast query="CAST(%s AS NVARCHAR(1000))"/>
<length query="CHAR_LENGTH(%s)"/> <length query="CHAR_LENGTH(%s)"/>
@ -1334,4 +1308,77 @@
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s ORDER BY table_schema" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s' ORDER BY table_name" 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"/> <blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s ORDER BY table_schema" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s' ORDER BY table_name" 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> </search_column>
</dbms> </dbms>
<dbms value="CrateDB">
<cast query="CAST(%s AS TEXT)"/>
<length query="CHAR_LENGTH((%s)::text)"/>
<isnull query="COALESCE(%s,' ')"/>
<delimiter query="||"/>
<limit query="LIMIT %d OFFSET %d"/>
<limitregexp query="\s+LIMIT\s+([\d]+)\s+OFFSET\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
<limitgroupstart query="2"/>
<limitgroupstop query="1"/>
<limitstring query=" LIMIT "/>
<order query="ORDER BY %s ASC"/>
<count query="COUNT(%s)"/>
<!-- NOTE: non-; version(s) doesn't work properly -->
<comment query=";--" query2=";/*"/>
<substring query="SUBSTR((%s)::text,%d,%d)"/>
<concatenate query="%s||%s"/>
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
<hex/>
<!-- NOTE: ASCII() only available in >= 4.1 -->
<inference query="SUBSTR((%s)::text,%d,1)>'%c'" query2="ASCII(SUBSTR((%s)::text,%d,1))>%d"/>
<banner query="SELECT version['number'] FROM sys.nodes" query2="VERSION()"/>
<current_user query="CURRENT_USER"/>
<current_db query="CURRENT_SCHEMA()"/>
<hostname query="SELECT hostname FROM sys.nodes"/>
<!--<table_comment query="SELECT pg_catalog.obj_description(c.oid) FROM pg_catalog.pg_class c WHERE c.relname='%s'"/>-->
<table_comment query="SELECT description FROM pg_description JOIN pg_class ON pg_description.objoid=pg_class.oid JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid WHERE nspname='%s' AND relname='%s'"/>
<column_comment/>
<is_dba query="(SELECT superuser=true FROM sys.users WHERE name=CURRENT_USER)"/>
<check_udf/>
<users>
<inband query="SELECT name FROM sys.users"/>
<blind query="SELECT name FROM sys.users LIMIT 1 OFFSET %d" count="SELECT COUNT(name) FROM sys.users"/>
</users>
<passwords/>
<privileges>
<inband query="SELECT grantee,type FROM sys.privileges" condition="grantee"/>
<blind query="SELECT DISTINCT(type) FROM sys.privileges WHERE grantee %s '%s' LIMIT 1 OFFSET %d" count="SELECT COUNT(DISTINCT(type)) FROM sys.privileges WHERE grantee %s '%s'"/>
</privileges>
<roles/>
<statements>
<inband query="SELECT stmt FROM sys.jobs"/>
<blind query="SELECT stmt FROM sys.jobs LIMIT 1 OFFSET %d" count="SELECT COUNT(stmt) FROM sys.jobs"/>
</statements>
<dbs>
<inband query="SELECT schema_name FROM information_schema.schemata"/>
<blind query="SELECT schema_name FROM information_schema.schemata ORDER BY schema_name LIMIT 1 OFFSET %d" count="SELECT COUNT(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 table_name FROM information_schema.tables WHERE table_schema='%s' LIMIT 1 OFFSET %d" count="SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='%s'"/>
</tables>
<columns>
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
</columns>
<dump_table>
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
<blind query="SELECT %s FROM %s.%s ORDER BY %s LIMIT 1 OFFSET %d" count="SELECT COUNT(*) FROM %s.%s"/>
</dump_table>
<search_db>
<inband query="SELECT schema_name FROM information_schema.schemata WHERE %s" condition="schema_name"/>
<blind query="SELECT schema_name FROM information_schema.schemata WHERE %s" count="SELECT COUNT(DISTINCT(schema_name)) FROM information_schema.schemata WHERE %s" condition="schema_name"/>
</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 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(table_name) FROM information_schema.tables WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
</search_table>
<search_column>
<inband query="SELECT nspname,relname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
<blind query="SELECT DISTINCT(nspname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname" condition3="relname"/>
</search_column>
</dbms>
</root> </root>

View File

@ -885,11 +885,15 @@ def heuristicCheckDbms(injection):
Backend.forceDbms(dbms) Backend.forceDbms(dbms)
if (randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1: if dbms in HEURISTIC_NULL_EVAL:
continue result = checkBooleanExpression("(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, "")))
elif not ((randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1):
result = checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER))
else:
result = False
if checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)): if result:
if dbms in HEURISTIC_NULL_EVAL and checkBooleanExpression("(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, ""))) or not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)): if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
retVal = dbms retVal = dbms
break break

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 CRATEDB_ALIASES
from lib.core.settings import DB2_ALIASES from lib.core.settings import DB2_ALIASES
from lib.core.settings import DERBY_ALIASES from lib.core.settings import DERBY_ALIASES
from lib.core.settings import FIREBIRD_ALIASES from lib.core.settings import FIREBIRD_ALIASES
@ -37,6 +38,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.cratedb.connector import Connector as CrateDBConn
from plugins.dbms.cratedb import CrateDBMap
from plugins.dbms.db2.connector import Connector as DB2Conn from plugins.dbms.db2.connector import Connector as DB2Conn
from plugins.dbms.db2 import DB2Map from plugins.dbms.db2 import DB2Map
from plugins.dbms.derby.connector import Connector as DerbyConn from plugins.dbms.derby.connector import Connector as DerbyConn
@ -101,6 +104,7 @@ def setHandler():
(DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn), (DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn),
(DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn), (DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn),
(DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn), (DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn),
(DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, CrateDBConn),
] ]
_ = 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

@ -659,7 +659,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): 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):
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
@ -956,7 +956,7 @@ class Agent(object):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
elif Backend.getIdentifiedDbms() in (DBMS.DERBY,): elif Backend.getIdentifiedDbms() in (DBMS.DERBY, DBMS.CRATEDB):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr

View File

@ -4072,7 +4072,7 @@ def safeSQLIdentificatorNaming(name, isTable=False):
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.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): 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 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()
@ -4110,7 +4110,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.SQLITE): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, 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): 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("\"", "") 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 CRATEDB_ALIASES
from lib.core.settings import DB2_ALIASES from lib.core.settings import DB2_ALIASES
from lib.core.settings import DERBY_ALIASES from lib.core.settings import DERBY_ALIASES
from lib.core.settings import FIREBIRD_ALIASES from lib.core.settings import FIREBIRD_ALIASES
@ -212,6 +213,7 @@ DBMS_DICT = {
DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None), DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None),
DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None), DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None),
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"),
} }
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/ # Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
@ -241,7 +243,8 @@ HEURISTIC_NULL_EVAL = {
DBMS.MCKOI: "TONUMBER(NULL)", DBMS.MCKOI: "TONUMBER(NULL)",
DBMS.PRESTO: "FROM_HEX(NULL)", DBMS.PRESTO: "FROM_HEX(NULL)",
DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)", DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)",
DBMS.MIMERSQL: "ASCII_CHAR(256) IS NULL", DBMS.MIMERSQL: "ASCII_CHAR(256)",
DBMS.CRATEDB: "(NULL~NULL)",
} }
SQL_STATEMENTS = { SQL_STATEMENTS = {

View File

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

View File

@ -52,6 +52,7 @@ class DBMS(object):
PRESTO = "Presto" PRESTO = "Presto"
ALTIBASE = "Altibase" ALTIBASE = "Altibase"
MIMERSQL = "MimerSQL" MIMERSQL = "MimerSQL"
CRATEDB = "CrateDB"
class DBMS_DIRECTORY_NAME(object): class DBMS_DIRECTORY_NAME(object):
ACCESS = "access" ACCESS = "access"
@ -74,6 +75,7 @@ class DBMS_DIRECTORY_NAME(object):
PRESTO = "presto" PRESTO = "presto"
ALTIBASE = "altibase" ALTIBASE = "altibase"
MIMERSQL = "mimersql" MIMERSQL = "mimersql"
CRATEDB = "cratedb"
class FORK(object): class FORK(object):
MARIADB = "MariaDB" MARIADB = "MariaDB"

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.2" VERSION = "1.4.2.3"
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)
@ -266,6 +266,7 @@ MCKOI_SYSTEM_DBS = ("",)
PRESTO_SYSTEM_DBS = ("information_schema",) PRESTO_SYSTEM_DBS = ("information_schema",)
ALTIBASE_SYSTEM_DBS = ("SYSTEM_",) ALTIBASE_SYSTEM_DBS = ("SYSTEM_",)
MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",) MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",)
CRATEDB_SYSTEM_DBS = ("information_schema", "pg_catalog", "sys")
# Note: (<regular>) + (<forks>) # Note: (<regular>) + (<forks>)
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
@ -288,13 +289,14 @@ MCKOI_ALIASES = ("mckoi",)
PRESTO_ALIASES = ("presto",) PRESTO_ALIASES = ("presto",)
ALTIBASE_ALIASES = ("altibase",) ALTIBASE_ALIASES = ("altibase",)
MIMERSQL_ALIASES = ("mimersql", "mimer") MIMERSQL_ALIASES = ("mimersql", "mimer")
CRATEDB_ALIASES = ("cratedb", "crate")
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 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_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_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))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent") USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer") REFERER_ALIASES = ("ref", "referer", "referrer")
@ -745,7 +747,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10 CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns" # Boldify all logger messages containing these "patterns"
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than") BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than", "connection to ")
# TLDs used in randomization of email-alike parameter values # TLDs used in randomization of email-alike parameter values
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe") RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe")

View File

@ -21,10 +21,15 @@ class Unescaper(AttribDict):
identifiedDbms = Backend.getIdentifiedDbms() identifiedDbms = Backend.getIdentifiedDbms()
if dbms is not None: if dbms is not None:
return self[dbms](expression, quote=quote) retVal = self[dbms](expression, quote=quote)
elif identifiedDbms is not None: elif identifiedDbms is not None:
return self[identifiedDbms](expression, quote=quote) retVal = self[identifiedDbms](expression, quote=quote)
else: else:
return expression retVal = expression
# e.g. inference comparison for '
retVal = retVal.replace("'''", "''''")
return retVal
unescaper = Unescaper() unescaper = Unescaper()

View File

@ -105,7 +105,7 @@ def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search(r"(COUNT|LTRIM)\(", expression, re.I) and not (timeBasedCompare and not kb.forceThreads): if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search(r"(COUNT|LTRIM)\(", expression, re.I) and not (timeBasedCompare and not kb.forceThreads):
if field and re.search(r"\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I): if field and re.search(r"\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.MONETDB, DBMS.VERTICA): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB):
alias = randomStr(lowercase=True, seed=hash(expression)) alias = randomStr(lowercase=True, seed=hash(expression))
expression = "SELECT %s FROM (%s)" % (field if '.' not in field else re.sub(r".+\.", "%s." % alias, field), expression) # Note: MonetDB as a prime example expression = "SELECT %s FROM (%s)" % (field if '.' not in field else re.sub(r".+\.", "%s." % alias, field), expression) # Note: MonetDB as a prime example
expression += " AS %s" % alias expression += " AS %s" % alias
@ -496,7 +496,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
if not any((kb.testMode, conf.dummy, conf.offline)) and value is None and Backend.getDbms() and conf.dbmsHandler and not conf.noCast and not conf.hexConvert: if not any((kb.testMode, conf.dummy, conf.offline)) and value is None and Backend.getDbms() and conf.dbmsHandler and not conf.noCast and not conf.hexConvert:
warnMsg = "in case of continuous data retrieval problems you are advised to try " warnMsg = "in case of continuous data retrieval problems you are advised to try "
warnMsg += "a switch '--no-cast' " warnMsg += "a switch '--no-cast' "
warnMsg += "or switch '--hex'" if Backend.getIdentifiedDbms() not in (DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MONETDB, DBMS.MCKOI, DBMS.MIMERSQL) else "" warnMsg += "or switch '--hex'" if Backend.getIdentifiedDbms() not in (DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MONETDB, DBMS.MCKOI, DBMS.MIMERSQL, DBMS.CRATEDB) else ""
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
# Dirty patch (safe-encoded unicode characters) # Dirty patch (safe-encoded unicode characters)

View File

@ -29,7 +29,7 @@ def checkDependencies():
logger.warn(warnMsg) logger.warn(warnMsg)
elif dbmsName == DBMS.MYSQL: elif dbmsName == DBMS.MYSQL:
__import__("pymysql") __import__("pymysql")
elif dbmsName == DBMS.PGSQL: elif dbmsName in (DBMS.PGSQL, DBMS.CRATEDB):
__import__("psycopg2") __import__("psycopg2")
elif dbmsName == DBMS.ORACLE: elif dbmsName == DBMS.ORACLE:
__import__("cx_Oracle") __import__("cx_Oracle")

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

View File

@ -0,0 +1,73 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
try:
import psycopg2
import psycopg2.extensions
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
except:
pass
from lib.core.common import getSafeExString
from lib.core.data import logger
from lib.core.exception import SqlmapConnectionException
from plugins.generic.connector import Connector as GenericConnector
class Connector(GenericConnector):
"""
Homepage: http://initd.org/psycopg/
User guide: http://initd.org/psycopg/docs/
API: http://initd.org/psycopg/docs/genindex.html
Debian package: python-psycopg2
License: GPL
Possible connectors: http://wiki.python.org/moin/PostgreSQL
"""
def connect(self):
self.initConnection()
try:
self.connector = psycopg2.connect(host=self.hostname, user=self.user, password=self.password, database=self.db, port=self.port)
except psycopg2.OperationalError as ex:
raise SqlmapConnectionException(getSafeExString(ex))
self.connector.set_client_encoding('UNICODE')
self.initCursor()
self.printConnected()
def fetchall(self):
try:
return self.cursor.fetchall()
except psycopg2.ProgrammingError as ex:
logger.warn(getSafeExString(ex))
return None
def execute(self, query):
retVal = False
try:
self.cursor.execute(query)
retVal = True
except (psycopg2.OperationalError, psycopg2.ProgrammingError) as ex:
logger.warn(("(remote) '%s'" % getSafeExString(ex)).strip())
except psycopg2.InternalError as ex:
raise SqlmapConnectionException(getSafeExString(ex))
self.connector.commit()
return retVal
def select(self, query):
retVal = None
if self.execute(query):
retVal = self.fetchall()
return retVal

View File

@ -0,0 +1,22 @@
#!/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 CrateDB it is not possible to enumerate the user password hashes"
logger.warn(warnMsg)
return {}
def getRoles(self, *args, **kwargs):
warnMsg = "on CrateDB it is not possible to enumerate the user roles"
logger.warn(warnMsg)
return {}

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

View File

@ -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 CRATEDB_ALIASES
from lib.request import inject
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
class Fingerprint(GenericFingerprint):
def __init__(self):
GenericFingerprint.__init__(self, DBMS.CRATEDB)
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.CRATEDB
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(CRATEDB_ALIASES):
setDbms(DBMS.CRATEDB)
self.getBanner()
return True
infoMsg = "testing %s" % DBMS.CRATEDB
logger.info(infoMsg)
result = inject.checkBooleanExpression("IGNORE3VL(NULL IS NULL)")
if result:
infoMsg = "confirming %s" % DBMS.CRATEDB
logger.info(infoMsg)
result = inject.checkBooleanExpression("1~1")
if not result:
warnMsg = "the back-end DBMS is not %s" % DBMS.CRATEDB
logger.warn(warnMsg)
return False
setDbms(DBMS.CRATEDB)
self.getBanner()
return True
else:
warnMsg = "the back-end DBMS is not %s" % DBMS.CRATEDB
logger.warn(warnMsg)
return False

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
"""
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
True
"""
return expression

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

View File

@ -82,7 +82,7 @@ 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): if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CRATEDB):
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"
@ -107,7 +107,7 @@ 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): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CRATEDB):
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"
@ -602,7 +602,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): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB):
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db)) query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery query += condQuery
@ -744,7 +744,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): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB):
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db)) query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery query += condQuery
@ -811,7 +811,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): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB):
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
@ -865,7 +865,7 @@ class Databases(object):
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): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB):
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()))

View File

@ -233,7 +233,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): elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB):
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)
@ -329,9 +329,7 @@ class Entries(object):
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB, DBMS.MSSQL, DBMS.INFORMIX, DBMS.MCKOI): elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB, DBMS.MSSQL, DBMS.INFORMIX, DBMS.MCKOI):
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI): if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI):
table = tbl table = tbl
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL): elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL, DBMS.MAXDB):
table = "%s.%s" % (conf.db, tbl)
elif Backend.isDbms(DBMS.MAXDB):
table = "%s.%s" % (conf.db, tbl) table = "%s.%s" % (conf.db, tbl)
elif Backend.isDbms(DBMS.INFORMIX): elif Backend.isDbms(DBMS.INFORMIX):
table = "%s:%s" % (conf.db, tbl) table = "%s:%s" % (conf.db, tbl)
@ -406,7 +404,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): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB):
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)
@ -418,7 +416,7 @@ class Entries(object):
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl) query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl)
elif Backend.isDbms(DBMS.INFORMIX): elif Backend.isDbms(DBMS.INFORMIX):
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, sorted(colList, key=len)[0]) query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, sorted(colList, key=len)[0])
elif Backend.isDbms(DBMS.MONETDB): else:
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, tbl, index) query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, tbl, index)
query = agent.whereQuery(query) query = agent.whereQuery(query)