diff --git a/data/xml/errors.xml b/data/xml/errors.xml
index 568b61bbe..99af38203 100644
--- a/data/xml/errors.xml
+++ b/data/xml/errors.xml
@@ -217,4 +217,9 @@
+
+
+
+
+
diff --git a/data/xml/queries.xml b/data/xml/queries.xml
index b61bdb7c6..75a6f4b53 100644
--- a/data/xml/queries.xml
+++ b/data/xml/queries.xml
@@ -1626,4 +1626,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/controller/handler.py b/lib/controller/handler.py
index 106b8051f..a54a13140 100644
--- a/lib/controller/handler.py
+++ b/lib/controller/handler.py
@@ -33,6 +33,7 @@ from lib.core.settings import MYSQL_ALIASES
from lib.core.settings import ORACLE_ALIASES
from lib.core.settings import PGSQL_ALIASES
from lib.core.settings import PRESTO_ALIASES
+from lib.core.settings import RAIMA_ALIASES
from lib.core.settings import SQLITE_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import VERTICA_ALIASES
@@ -82,6 +83,8 @@ from plugins.dbms.postgresql.connector import Connector as PostgreSQLConn
from plugins.dbms.postgresql import PostgreSQLMap
from plugins.dbms.presto.connector import Connector as PrestoConn
from plugins.dbms.presto import PrestoMap
+from plugins.dbms.raima.connector import Connector as RaimaConn
+from plugins.dbms.raima import RaimaMap
from plugins.dbms.sqlite.connector import Connector as SQLiteConn
from plugins.dbms.sqlite import SQLiteMap
from plugins.dbms.sybase.connector import Connector as SybaseConn
@@ -121,6 +124,7 @@ def setHandler():
(DBMS.CACHE, CACHE_ALIASES, CacheMap, CacheConn),
(DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, ExtremeDBConn),
(DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, FrontBaseConn),
+ (DBMS.RAIMA, RAIMA_ALIASES, RaimaMap, RaimaConn),
]
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items)
diff --git a/lib/core/agent.py b/lib/core/agent.py
index c17407c48..d0df1a1cc 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -487,7 +487,10 @@ class Agent(object):
else:
if not (Backend.isDbms(DBMS.SQLITE) and not isDBMSVersionAtLeast('3')):
nulledCastedField = rootQuery.cast.query % field
- if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI):
+
+ if re.search("COUNT\(", field) and Backend.getIdentifiedDbms() in (DBMS.RAIMA,):
+ pass
+ elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI):
nulledCastedField = rootQuery.isnull.query % (nulledCastedField, nulledCastedField)
else:
nulledCastedField = rootQuery.isnull.query % nulledCastedField
@@ -696,7 +699,7 @@ class Agent(object):
elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
- elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
+ 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, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA):
if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -1006,7 +1009,7 @@ class Agent(object):
fromFrom = limitedQuery[fromIndex + 1:]
orderBy = None
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID, DBMS.EXTREMEDB):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID, DBMS.EXTREMEDB, DBMS.RAIMA):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr
diff --git a/lib/core/common.py b/lib/core/common.py
index 3f643e992..d161feeee 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -4193,7 +4193,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)
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, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
+ 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, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA):
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper()
@@ -4231,7 +4231,7 @@ def unsafeSQLIdentificatorNaming(name):
if isinstance(name, six.string_types):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE):
retVal = name.replace("`", "")
- elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
+ 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, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA):
retVal = name.replace("\"", "")
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = name.replace("\"", "").upper()
diff --git a/lib/core/dicts.py b/lib/core/dicts.py
index 29389b333..5aa1bdda9 100644
--- a/lib/core/dicts.py
+++ b/lib/core/dicts.py
@@ -33,6 +33,7 @@ from lib.core.settings import NULL
from lib.core.settings import ORACLE_ALIASES
from lib.core.settings import PGSQL_ALIASES
from lib.core.settings import PRESTO_ALIASES
+from lib.core.settings import RAIMA_ALIASES
from lib.core.settings import SQLITE_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import VERTICA_ALIASES
@@ -244,6 +245,7 @@ DBMS_DICT = {
DBMS.CACHE: (CACHE_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None),
DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
+ DBMS.RAIMA: (RAIMA_ALIASES, None, None, None),
}
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
@@ -280,6 +282,7 @@ HEURISTIC_NULL_EVAL = {
DBMS.CUBRID: "(NULL SETEQ NULL)",
DBMS.CACHE: "%SQLUPPER NULL",
DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))",
+ DBMS.RAIMA: "IF(ROWNUMBER()>0,CONVERT(NULL,TINYINT),NULL))",
}
SQL_STATEMENTS = {
diff --git a/lib/core/dump.py b/lib/core/dump.py
index a9d0d81d4..89d4b0ac0 100644
--- a/lib/core/dump.py
+++ b/lib/core/dump.py
@@ -243,7 +243,7 @@ class Dump(object):
for db, tables in dbTables.items():
tables = sorted(filter(None, tables))
- self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db else "Current database")
+ self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "")
if len(tables) == 1:
self._write("[1 table]")
@@ -298,7 +298,7 @@ class Dump(object):
maxlength2 = max(maxlength2, len("TYPE"))
lines2 = "-" * (maxlength2 + 2)
- self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db else "Current database", unsafeSQLIdentificatorNaming(table)))
+ self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "", unsafeSQLIdentificatorNaming(table)))
if len(columns) == 1:
self._write("[1 column]")
@@ -353,7 +353,7 @@ class Dump(object):
maxlength1 = max(maxlength1, getConsoleLength(getUnicode(table)))
for db, counts in dbTables.items():
- self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db else "Current database")
+ self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "")
lines1 = "-" * (maxlength1 + 2)
blank1 = " " * (maxlength1 - len("Table"))
@@ -479,7 +479,7 @@ class Dump(object):
separator += "+%s" % lines
separator += "+"
- self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db else "Current database", unsafeSQLIdentificatorNaming(table)))
+ self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "", unsafeSQLIdentificatorNaming(table)))
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
cols = []
diff --git a/lib/core/enums.py b/lib/core/enums.py
index aedf1934e..deb2beacf 100644
--- a/lib/core/enums.py
+++ b/lib/core/enums.py
@@ -57,6 +57,7 @@ class DBMS(object):
CACHE = "InterSystems Cache"
EXTREMEDB = "eXtremeDB"
FRONTBASE = "FrontBase"
+ RAIMA = "Raima Database Manager"
class DBMS_DIRECTORY_NAME(object):
ACCESS = "access"
@@ -84,6 +85,7 @@ class DBMS_DIRECTORY_NAME(object):
CACHE = "cache"
EXTREMEDB = "extremedb"
FRONTBASE = "frontbase"
+ RAIMA = "raima"
class FORK(object):
MARIADB = "MariaDB"
diff --git a/lib/core/profiling.py b/lib/core/profiling.py
index 8d4f643a0..84a8558e1 100644
--- a/lib/core/profiling.py
+++ b/lib/core/profiling.py
@@ -5,14 +5,11 @@ Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
-import codecs
import cProfile
import os
-from lib.core.common import getSafeExString
from lib.core.data import logger
from lib.core.data import paths
-from lib.core.settings import UNICODE_ENCODING
def profile(profileOutputFile=None):
"""
diff --git a/lib/core/settings.py b/lib/core/settings.py
index 01443d3c2..f0d5a11ee 100644
--- a/lib/core/settings.py
+++ b/lib/core/settings.py
@@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr
# sqlmap version (...)
-VERSION = "1.5.1.17"
+VERSION = "1.5.1.18"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@@ -282,6 +282,7 @@ CUBRID_SYSTEM_DBS = ("DBA",)
CACHE_SYSTEM_DBS = ("%Dictionary", "INFORMATION_SCHEMA", "%SYS")
EXTREMEDB_SYSTEM_DBS = ("",)
FRONTBASE_SYSTEM_DBS = ("DEFINITION_SCHEMA", "INFORMATION_SCHEMA")
+RAIMA_SYSTEM_DBS = ("",)
# Note: () + ()
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
@@ -289,7 +290,7 @@ MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percon
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "redshift", "greenplum", "yellowbrick", "enterprisedb", "aurora")
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
SQLITE_ALIASES = ("sqlite", "sqlite3")
-ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access")
+ACCESS_ALIASES = ("microsoft access", "msaccess", "access", "jet")
FIREBIRD_ALIASES = ("firebird", "mozilla firebird", "interbase", "ibase", "fb")
MAXDB_ALIASES = ("max", "maxdb", "sap maxdb", "sap db")
SYBASE_ALIASES = ("sybase", "sybase sql server")
@@ -309,13 +310,14 @@ CUBRID_ALIASES = ("cubrid",)
CACHE_ALIASES = ("intersystems cache", "cachedb", "cache")
EXTREMEDB_ALIASES = ("extremedb", "extreme")
FRONTBASE_ALIASES = ("frontbase",)
+RAIMA_ALIASES = ("raima database manager", "raima", "raimadb", "raimadm", "rdm", "rds", "velocis")
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
-SUPPORTED_DBMS = set(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 + EXTREMEDB_ALIASES)
+SUPPORTED_DBMS = set(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 + EXTREMEDB_ALIASES + RAIMA_ALIASES)
SUPPORTED_OS = ("linux", "windows")
-DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_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), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES), (DBMS.RAIMA, RAIMA_ALIASES))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer")
diff --git a/lib/request/inject.py b/lib/request/inject.py
index 66871a960..2de0e5e93 100644
--- a/lib/request/inject.py
+++ b/lib/request/inject.py
@@ -113,7 +113,7 @@ def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar
else:
expression = "SELECT %s FROM (%s)" % (field, expression)
- if field and conf.hexConvert or conf.binaryFields and field in conf.binaryFields:
+ if field and conf.hexConvert or conf.binaryFields and field in conf.binaryFields or Backend.getIdentifiedDbms() in (DBMS.RAIMA,):
nulledCastedField = agent.nullAndCastField(field)
injExpression = expression.replace(field, nulledCastedField, 1)
else:
diff --git a/lib/utils/brute.py b/lib/utils/brute.py
index a03fe1b40..7fdc140e2 100644
--- a/lib/utils/brute.py
+++ b/lib/utils/brute.py
@@ -104,7 +104,7 @@ def tableExists(tableFile, regex=None):
tables = filterListValue(tables, regex)
for conf.db in (conf.db.split(',') if conf.db else [conf.db]):
- if conf.db:
+ if conf.db and METADB_SUFFIX not in conf.db:
infoMsg = "checking database '%s'" % conf.db
logger.info(infoMsg)
diff --git a/lib/utils/pivotdumptable.py b/lib/utils/pivotdumptable.py
index fd9128d94..1d33797fd 100644
--- a/lib/utils/pivotdumptable.py
+++ b/lib/utils/pivotdumptable.py
@@ -30,6 +30,7 @@ from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapNoneDataException
from lib.core.settings import MAX_INT
from lib.core.settings import NULL
+from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.unescaper import unescaper
from lib.request import inject
from lib.utils.safe2bin import safechardecode
@@ -128,7 +129,7 @@ def pivotDumpTable(table, colList, count=None, blind=True, alias=None):
if column == colList[0]:
query = dumpNode.query.replace("'%s'" if unescaper.escape(pivotValue, False) != pivotValue else "%s", "%s") % (agent.preprocessField(table, column), table, agent.preprocessField(table, column), unescaper.escape(pivotValue, False))
else:
- query = dumpNode.query2.replace("'%s'" if unescaper.escape(pivotValue, False) != pivotValue else "%s", "%s") % (agent.preprocessField(table, column), table, agent.preprocessField(table, colList[0]), unescaper.escape(pivotValue, False))
+ query = dumpNode.query2.replace("'%s'" if unescaper.escape(pivotValue, False) != pivotValue else "%s", "%s") % (agent.preprocessField(table, column), table, agent.preprocessField(table, colList[0]), unescaper.escape(pivotValue, False) if SINGLE_QUOTE_MARKER not in dumpNode.query2 else pivotValue)
query = agent.whereQuery(query)
return unArrayizeValue(inject.getValue(query, blind=blind, time=blind, union=not blind, error=not blind))
diff --git a/plugins/dbms/raima/__init__.py b/plugins/dbms/raima/__init__.py
new file mode 100644
index 000000000..565c30629
--- /dev/null
+++ b/plugins/dbms/raima/__init__.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
+See the file 'LICENSE' for copying permission
+"""
+
+from lib.core.enums import DBMS
+from lib.core.settings import RAIMA_SYSTEM_DBS
+from lib.core.unescaper import unescaper
+from plugins.dbms.raima.enumeration import Enumeration
+from plugins.dbms.raima.filesystem import Filesystem
+from plugins.dbms.raima.fingerprint import Fingerprint
+from plugins.dbms.raima.syntax import Syntax
+from plugins.dbms.raima.takeover import Takeover
+from plugins.generic.misc import Miscellaneous
+
+class RaimaMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
+ """
+ This class defines Raima methods
+ """
+
+ def __init__(self):
+ self.excludeDbsList = RAIMA_SYSTEM_DBS
+
+ for cls in self.__class__.__bases__:
+ cls.__init__(self)
+
+ unescaper[DBMS.RAIMA] = Syntax.escape
diff --git a/plugins/dbms/raima/connector.py b/plugins/dbms/raima/connector.py
new file mode 100644
index 000000000..1ddfb7181
--- /dev/null
+++ b/plugins/dbms/raima/connector.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
+See the file 'LICENSE' for copying permission
+"""
+
+from lib.core.exception import SqlmapUnsupportedFeatureException
+from plugins.generic.connector import Connector as GenericConnector
+
+class Connector(GenericConnector):
+ def connect(self):
+ errMsg = "on Raima it is not (currently) possible to establish a "
+ errMsg += "direct connection"
+ raise SqlmapUnsupportedFeatureException(errMsg)
diff --git a/plugins/dbms/raima/enumeration.py b/plugins/dbms/raima/enumeration.py
new file mode 100644
index 000000000..980d2e3a2
--- /dev/null
+++ b/plugins/dbms/raima/enumeration.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2021 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 getBanner(self):
+ warnMsg = "on Raima it is not possible to get the banner"
+ logger.warn(warnMsg)
+
+ return None
+
+ def getCurrentUser(self):
+ warnMsg = "on Raima it is not possible to enumerate the current user"
+ logger.warn(warnMsg)
+
+ def getCurrentDb(self):
+ warnMsg = "on Raima it is not possible to get name of the current database"
+ logger.warn(warnMsg)
+
+ def isDba(self, user=None):
+ warnMsg = "on Raima it is not possible to test if current user is DBA"
+ logger.warn(warnMsg)
+
+ def getUsers(self):
+ warnMsg = "on Raima it is not possible to enumerate the users"
+ logger.warn(warnMsg)
+
+ return []
+
+ def getPasswordHashes(self):
+ warnMsg = "on Raima it is not possible to enumerate the user password hashes"
+ logger.warn(warnMsg)
+
+ return {}
+
+ def getPrivileges(self, *args, **kwargs):
+ warnMsg = "on Raima it is not possible to enumerate the user privileges"
+ logger.warn(warnMsg)
+
+ return {}
+
+ def getDbs(self):
+ warnMsg = "on Raima it is not possible to enumerate databases (use only '--tables')"
+ logger.warn(warnMsg)
+
+ return []
+
+ def searchDb(self):
+ warnMsg = "on Raima it is not possible to search databases"
+ logger.warn(warnMsg)
+
+ return []
+
+ def searchTable(self):
+ warnMsg = "on Raima it is not possible to search tables"
+ logger.warn(warnMsg)
+
+ return []
+
+ def searchColumn(self):
+ warnMsg = "on Raima it is not possible to search columns"
+ logger.warn(warnMsg)
+
+ return []
+
+ def search(self):
+ warnMsg = "on Raima search option is not available"
+ logger.warn(warnMsg)
+
+ def getHostname(self):
+ warnMsg = "on Raima it is not possible to enumerate the hostname"
+ logger.warn(warnMsg)
+
+ def getStatements(self):
+ warnMsg = "on Raima it is not possible to enumerate the SQL statements"
+ logger.warn(warnMsg)
+
+ return []
diff --git a/plugins/dbms/raima/filesystem.py b/plugins/dbms/raima/filesystem.py
new file mode 100644
index 000000000..f9982e22c
--- /dev/null
+++ b/plugins/dbms/raima/filesystem.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
+See the file 'LICENSE' for copying permission
+"""
+
+from lib.core.exception import SqlmapUnsupportedFeatureException
+from plugins.generic.filesystem import Filesystem as GenericFilesystem
+
+class Filesystem(GenericFilesystem):
+ def readFile(self, remoteFile):
+ errMsg = "on Raima it is not possible to read files"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def writeFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
+ errMsg = "on Raima it is not possible to write files"
+ raise SqlmapUnsupportedFeatureException(errMsg)
diff --git a/plugins/dbms/raima/fingerprint.py b/plugins/dbms/raima/fingerprint.py
new file mode 100644
index 000000000..12b17937c
--- /dev/null
+++ b/plugins/dbms/raima/fingerprint.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2021 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 METADB_SUFFIX
+from lib.core.settings import RAIMA_ALIASES
+from lib.request import inject
+from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
+
+class Fingerprint(GenericFingerprint):
+ def __init__(self):
+ GenericFingerprint.__init__(self, DBMS.RAIMA)
+
+ 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.RAIMA
+ 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(RAIMA_ALIASES):
+ setDbms(DBMS.RAIMA)
+ return True
+
+ infoMsg = "testing %s" % DBMS.RAIMA
+ logger.info(infoMsg)
+
+ result = inject.checkBooleanExpression("ROWNUMBER()=ROWNUMBER()")
+
+ if result:
+ infoMsg = "confirming %s" % DBMS.RAIMA
+ logger.info(infoMsg)
+
+ result = inject.checkBooleanExpression("INSSTR('[RANDSTR1]',0,0,'[RANDSTR2]') IS NOT NULL")
+
+ if not result:
+ warnMsg = "the back-end DBMS is not %s" % DBMS.RAIMA
+ logger.warn(warnMsg)
+
+ return False
+
+ setDbms(DBMS.RAIMA)
+
+ return True
+ else:
+ warnMsg = "the back-end DBMS is not %s" % DBMS.RAIMA
+ logger.warn(warnMsg)
+
+ return False
+
+ def forceDbmsEnum(self):
+ conf.db = ("%s%s" % (DBMS.RAIMA, METADB_SUFFIX)).replace(' ', '_')
diff --git a/plugins/dbms/raima/syntax.py b/plugins/dbms/raima/syntax.py
new file mode 100644
index 000000000..19853b3e8
--- /dev/null
+++ b/plugins/dbms/raima/syntax.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2021 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):
+ """
+ >>> 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)
diff --git a/plugins/dbms/raima/takeover.py b/plugins/dbms/raima/takeover.py
new file mode 100644
index 000000000..17ba3671c
--- /dev/null
+++ b/plugins/dbms/raima/takeover.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2021 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 Raima it is not possible to execute commands"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osShell(self):
+ errMsg = "on Raima it is not possible to execute commands"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osPwn(self):
+ errMsg = "on Raima it is not possible to establish an "
+ errMsg += "out-of-band connection"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osSmb(self):
+ errMsg = "on Raima it is not possible to establish an "
+ errMsg += "out-of-band connection"
+ raise SqlmapUnsupportedFeatureException(errMsg)
diff --git a/plugins/generic/databases.py b/plugins/generic/databases.py
index 289d73454..37386a80b 100644
--- a/plugins/generic/databases.py
+++ b/plugins/generic/databases.py
@@ -47,6 +47,7 @@ from lib.core.exception import SqlmapMissingMandatoryOptionException
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import CURRENT_DB
+from lib.core.settings import METADB_SUFFIX
from lib.core.settings import PLUS_ONE_DBMSES
from lib.core.settings import REFLECTED_VALUE_MARKER
from lib.core.settings import UPPER_CASE_DBMSES
@@ -222,7 +223,7 @@ class Databases(object):
logger.warn(warnMsg)
bruteForce = True
- elif Backend.getIdentifiedDbms() in (DBMS.MCKOI, DBMS.EXTREMEDB):
+ elif Backend.getIdentifiedDbms() in (DBMS.MCKOI, DBMS.EXTREMEDB, DBMS.RAIMA):
bruteForce = True
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS,):
@@ -336,8 +337,9 @@ class Databases(object):
comment = unArrayizeValue(inject.getValue(query, blind=False, time=False))
if not isNoneValue(comment):
- infoMsg = "retrieved comment '%s' for table '%s' " % (comment, unsafeSQLIdentificatorNaming(table))
- infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db)
+ infoMsg = "retrieved comment '%s' for table '%s'" % (comment, unsafeSQLIdentificatorNaming(table))
+ if METADB_SUFFIX not in db:
+ infoMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(db)
logger.info(infoMsg)
else:
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()
@@ -418,8 +420,9 @@ class Databases(object):
comment = unArrayizeValue(inject.getValue(query, union=False, error=False))
if not isNoneValue(comment):
- infoMsg = "retrieved comment '%s' for table '%s' " % (comment, unsafeSQLIdentificatorNaming(table))
- infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(db)
+ infoMsg = "retrieved comment '%s' for table '%s'" % (comment, unsafeSQLIdentificatorNaming(table))
+ if METADB_SUFFIX not in db:
+ infoMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(db)
logger.info(infoMsg)
else:
warnMsg = "on %s it is not " % Backend.getIdentifiedDbms()
@@ -516,8 +519,9 @@ class Databases(object):
tblList = list(tblList)
elif not conf.search:
- errMsg = "unable to retrieve the tables "
- errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
+ errMsg = "unable to retrieve the tables"
+ if METADB_SUFFIX not in conf.db:
+ errMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
raise SqlmapNoneDataException(errMsg)
else:
return kb.data.cachedColumns
@@ -534,7 +538,7 @@ class Databases(object):
logger.warn(warnMsg)
bruteForce = True
- elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB):
+ elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB, DBMS.RAIMA):
warnMsg = "cannot retrieve column names, "
warnMsg += "back-end DBMS is %s" % Backend.getIdentifiedDbms()
logger.warn(warnMsg)
@@ -549,7 +553,7 @@ class Databases(object):
resumeAvailable = True
break
- if resumeAvailable and not conf.freshQueries:
+ if resumeAvailable and not (conf.freshQueries and not colList):
columns = {}
for column in colList:
@@ -632,7 +636,8 @@ class Databases(object):
values = [(_,) for _ in colList]
else:
infoMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)
- infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
+ if METADB_SUFFIX not in conf.db:
+ infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
logger.info(infoMsg)
values = None
@@ -781,7 +786,8 @@ class Databases(object):
columns[safeSQLIdentificatorNaming(value)] = None
else:
infoMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)
- infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
+ if METADB_SUFFIX not in conf.db:
+ infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
logger.info(infoMsg)
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
@@ -802,7 +808,8 @@ class Databases(object):
if not columns:
errMsg = "unable to retrieve the %scolumns " % ("number of " if not Backend.isDbms(DBMS.MSSQL) else "")
errMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)
- errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
+ if METADB_SUFFIX not in conf.db:
+ errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
logger.error(errMsg)
continue
@@ -904,7 +911,8 @@ class Databases(object):
if not kb.data.cachedColumns:
warnMsg = "unable to retrieve column names for "
warnMsg += ("table '%s' " % unsafeSQLIdentificatorNaming(unArrayizeValue(tblList))) if len(tblList) == 1 else "any table "
- warnMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
+ if METADB_SUFFIX not in conf.db:
+ warnMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
logger.warn(warnMsg)
if bruteForce is None:
diff --git a/plugins/generic/entries.py b/plugins/generic/entries.py
index 8cc32b538..3cb50a0fd 100644
--- a/plugins/generic/entries.py
+++ b/plugins/generic/entries.py
@@ -42,6 +42,7 @@ from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapUnsupportedFeatureException
from lib.core.settings import CHECK_ZERO_COLUMNS_THRESHOLD
from lib.core.settings import CURRENT_DB
+from lib.core.settings import METADB_SUFFIX
from lib.core.settings import NULL
from lib.core.settings import PLUS_ONE_DBMSES
from lib.core.settings import UPPER_CASE_DBMSES
@@ -137,9 +138,9 @@ class Entries(object):
kb.dumpTable = "%s.%s" % (conf.db, tbl)
if safeSQLIdentificatorNaming(conf.db) not in kb.data.cachedColumns or safeSQLIdentificatorNaming(tbl, True) not in kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] or not kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]:
- warnMsg = "unable to enumerate the columns for table "
- warnMsg += "'%s' in database" % unsafeSQLIdentificatorNaming(tbl)
- warnMsg += " '%s'" % unsafeSQLIdentificatorNaming(conf.db)
+ warnMsg = "unable to enumerate the columns for table '%s'" % unsafeSQLIdentificatorNaming(tbl)
+ if METADB_SUFFIX not in conf.db:
+ warnMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
warnMsg += ", skipping" if len(tblList) > 1 else ""
logger.warn(warnMsg)
@@ -153,7 +154,8 @@ class Entries(object):
if not colList:
warnMsg = "skipping table '%s'" % unsafeSQLIdentificatorNaming(tbl)
- warnMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
+ if METADB_SUFFIX not in conf.db:
+ warnMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
warnMsg += " (no usable column names)"
logger.warn(warnMsg)
continue
@@ -166,7 +168,8 @@ class Entries(object):
if conf.col:
infoMsg += " of column(s) '%s'" % colNames
infoMsg += " for table '%s'" % unsafeSQLIdentificatorNaming(tbl)
- infoMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
+ if METADB_SUFFIX not in conf.db:
+ infoMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
logger.info(infoMsg)
for column in colList:
@@ -182,7 +185,7 @@ class Entries(object):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
query = rootQuery.inband.query % (colString, tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())))
- elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.MCKOI, DBMS.EXTREMEDB):
+ elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.MCKOI, DBMS.EXTREMEDB, DBMS.RAIMA):
query = rootQuery.inband.query % (colString, tbl)
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
# Partial inband and error
@@ -291,12 +294,10 @@ class Entries(object):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
query = rootQuery.blind.count % (tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())))
- elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI, DBMS.EXTREMEDB):
+ elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.MAXDB, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI, DBMS.EXTREMEDB, DBMS.RAIMA):
query = rootQuery.blind.count % tbl
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
query = rootQuery.blind.count % ("%s.%s" % (conf.db, tbl))
- elif Backend.isDbms(DBMS.MAXDB):
- query = rootQuery.blind.count % tbl
elif Backend.isDbms(DBMS.INFORMIX):
query = rootQuery.blind.count % (conf.db, tbl)
else:
@@ -329,8 +330,8 @@ class Entries(object):
continue
- elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB, DBMS.MSSQL, DBMS.INFORMIX, DBMS.MCKOI):
- if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB):
+ elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB, DBMS.MSSQL, DBMS.INFORMIX, DBMS.MCKOI, DBMS.RAIMA):
+ if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.RAIMA):
table = tbl
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL, DBMS.MAXDB):
table = "%s.%s" % (conf.db, tbl)
diff --git a/sqlmap.py b/sqlmap.py
index 18e1d58ac..f18df7fbe 100755
--- a/sqlmap.py
+++ b/sqlmap.py
@@ -80,7 +80,6 @@ try:
from lib.core.settings import VERSION
from lib.parse.cmdline import cmdLineParser
from lib.utils.crawler import crawl
- from thirdparty import six
except KeyboardInterrupt:
errMsg = "user aborted"