diff --git a/data/xml/errors.xml b/data/xml/errors.xml
index 29bb39a2d..de6786dc9 100644
--- a/data/xml/errors.xml
+++ b/data/xml/errors.xml
@@ -223,4 +223,12 @@
+
+
+
+
+
+
+
+
diff --git a/data/xml/queries.xml b/data/xml/queries.xml
index 75a6f4b53..ff824b87e 100644
--- a/data/xml/queries.xml
+++ b/data/xml/queries.xml
@@ -1665,4 +1665,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/controller/handler.py b/lib/controller/handler.py
index a54a13140..79364c103 100644
--- a/lib/controller/handler.py
+++ b/lib/controller/handler.py
@@ -37,6 +37,7 @@ 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
+from lib.core.settings import VIRTUOSO_ALIASES
from lib.utils.sqlalchemy import SQLAlchemy
from plugins.dbms.access.connector import Connector as AccessConn
@@ -91,6 +92,8 @@ from plugins.dbms.sybase.connector import Connector as SybaseConn
from plugins.dbms.sybase import SybaseMap
from plugins.dbms.vertica.connector import Connector as VerticaConn
from plugins.dbms.vertica import VerticaMap
+from plugins.dbms.virtuoso.connector import Connector as VirtuosoConn
+from plugins.dbms.virtuoso import VirtuosoMap
def setHandler():
"""
@@ -125,6 +128,7 @@ def setHandler():
(DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, ExtremeDBConn),
(DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, FrontBaseConn),
(DBMS.RAIMA, RAIMA_ALIASES, RaimaMap, RaimaConn),
+ (DBMS.VIRTUOSO, VIRTUOSO_ALIASES, VirtuosoMap, VirtuosoConn),
]
_ = 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 d0df1a1cc..82d78febf 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -699,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, DBMS.RAIMA):
+ 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, DBMS.VIRTUOSO):
if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -1021,7 +1021,7 @@ class Agent(object):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
limitedQuery += " %s" % limitStr
- elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE,):
+ elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE, DBMS.VIRTUOSO):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
if query.startswith("SELECT "):
limitedQuery = query.replace("SELECT ", "SELECT %s " % limitStr, 1)
diff --git a/lib/core/common.py b/lib/core/common.py
index aead6ab6c..91dd82df7 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -4200,7 +4200,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, DBMS.RAIMA):
+ 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, DBMS.VIRTUOSO):
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper()
@@ -4238,7 +4238,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, DBMS.RAIMA):
+ 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, DBMS.VIRTUOSO):
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 27077f08f..89a9eee41 100644
--- a/lib/core/dicts.py
+++ b/lib/core/dicts.py
@@ -37,6 +37,7 @@ 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
+from lib.core.settings import VIRTUOSO_ALIASES
FIREBIRD_TYPES = {
261: "BLOB",
@@ -246,6 +247,7 @@ DBMS_DICT = {
DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None),
DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
DBMS.RAIMA: (RAIMA_ALIASES, None, None, None),
+ DBMS.VIRTUOSO: (VIRTUOSO_ALIASES, None, None, None),
}
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
@@ -283,6 +285,7 @@ HEURISTIC_NULL_EVAL = {
DBMS.CACHE: "%SQLUPPER NULL",
DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))",
DBMS.RAIMA: "IF(ROWNUMBER()>0,CONVERT(NULL,TINYINT),NULL))",
+ DBMS.VIRTUOSO: "__MAX_NOTNULL(NULL)",
}
SQL_STATEMENTS = {
diff --git a/lib/core/dump.py b/lib/core/dump.py
index 89d4b0ac0..b21473a1a 100644
--- a/lib/core/dump.py
+++ b/lib/core/dump.py
@@ -166,7 +166,7 @@ class Dump(object):
def currentDb(self, data):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
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, DBMS.VIRTUOSO):
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
else:
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
diff --git a/lib/core/enums.py b/lib/core/enums.py
index 9423c499f..e693b6e31 100644
--- a/lib/core/enums.py
+++ b/lib/core/enums.py
@@ -58,6 +58,7 @@ class DBMS(object):
EXTREMEDB = "eXtremeDB"
FRONTBASE = "FrontBase"
RAIMA = "Raima Database Manager"
+ VIRTUOSO = "Virtuoso"
class DBMS_DIRECTORY_NAME(object):
ACCESS = "access"
@@ -86,6 +87,7 @@ class DBMS_DIRECTORY_NAME(object):
EXTREMEDB = "extremedb"
FRONTBASE = "frontbase"
RAIMA = "raima"
+ VIRTUOSO = "virtuoso"
class FORK(object):
MARIADB = "MariaDB"
diff --git a/lib/core/settings.py b/lib/core/settings.py
index 8211bd917..3d93b5a7f 100644
--- a/lib/core/settings.py
+++ b/lib/core/settings.py
@@ -283,6 +283,7 @@ CACHE_SYSTEM_DBS = ("%Dictionary", "INFORMATION_SCHEMA", "%SYS")
EXTREMEDB_SYSTEM_DBS = ("",)
FRONTBASE_SYSTEM_DBS = ("DEFINITION_SCHEMA", "INFORMATION_SCHEMA")
RAIMA_SYSTEM_DBS = ("",)
+VIRTUOSO_SYSTEM_DBS = ("",)
# Note: () + ()
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
@@ -311,13 +312,14 @@ CACHE_ALIASES = ("intersystems cache", "cachedb", "cache")
EXTREMEDB_ALIASES = ("extremedb", "extreme")
FRONTBASE_ALIASES = ("frontbase",)
RAIMA_ALIASES = ("raima database manager", "raima", "raimadb", "raimadm", "rdm", "rds", "velocis")
+VIRTUOSO_ALIASES = ("virtuoso", "openlink virtuoso")
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 + RAIMA_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 + VIRTUOSO_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.RAIMA, RAIMA_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), (DBMS.VIRTUOSO, VIRTUOSO_ALIASES))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer")
diff --git a/plugins/dbms/virtuoso/__init__.py b/plugins/dbms/virtuoso/__init__.py
new file mode 100644
index 000000000..7e7ae0677
--- /dev/null
+++ b/plugins/dbms/virtuoso/__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 VIRTUOSO_SYSTEM_DBS
+from lib.core.unescaper import unescaper
+from plugins.dbms.virtuoso.enumeration import Enumeration
+from plugins.dbms.virtuoso.filesystem import Filesystem
+from plugins.dbms.virtuoso.fingerprint import Fingerprint
+from plugins.dbms.virtuoso.syntax import Syntax
+from plugins.dbms.virtuoso.takeover import Takeover
+from plugins.generic.misc import Miscellaneous
+
+class VirtuosoMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
+ """
+ This class defines Virtuoso methods
+ """
+
+ def __init__(self):
+ self.excludeDbsList = VIRTUOSO_SYSTEM_DBS
+
+ for cls in self.__class__.__bases__:
+ cls.__init__(self)
+
+ unescaper[DBMS.VIRTUOSO] = Syntax.escape
diff --git a/plugins/dbms/virtuoso/connector.py b/plugins/dbms/virtuoso/connector.py
new file mode 100644
index 000000000..4724e7a78
--- /dev/null
+++ b/plugins/dbms/virtuoso/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 Virtuoso it is not (currently) possible to establish a "
+ errMsg += "direct connection"
+ raise SqlmapUnsupportedFeatureException(errMsg)
diff --git a/plugins/dbms/virtuoso/enumeration.py b/plugins/dbms/virtuoso/enumeration.py
new file mode 100644
index 000000000..1bce85ade
--- /dev/null
+++ b/plugins/dbms/virtuoso/enumeration.py
@@ -0,0 +1,56 @@
+#!/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 getPasswordHashes(self):
+ warnMsg = "on Virtuoso it is not possible to enumerate the user password hashes"
+ logger.warn(warnMsg)
+
+ return {}
+
+ def getPrivileges(self, *args, **kwargs):
+ warnMsg = "on Virtuoso it is not possible to enumerate the user privileges"
+ logger.warn(warnMsg)
+
+ return {}
+
+ def getRoles(self, *args, **kwargs):
+ warnMsg = "on Virtuoso it is not possible to enumerate the user roles"
+ logger.warn(warnMsg)
+
+ return {}
+
+ def searchDb(self):
+ warnMsg = "on Virtuoso it is not possible to search databases"
+ logger.warn(warnMsg)
+
+ return []
+
+ def searchTable(self):
+ warnMsg = "on Virtuoso it is not possible to search tables"
+ logger.warn(warnMsg)
+
+ return []
+
+ def searchColumn(self):
+ warnMsg = "on Virtuoso it is not possible to search columns"
+ logger.warn(warnMsg)
+
+ return []
+
+ def search(self):
+ warnMsg = "on Virtuoso search option is not available"
+ logger.warn(warnMsg)
+
+ def getStatements(self):
+ warnMsg = "on Virtuoso it is not possible to enumerate the SQL statements"
+ logger.warn(warnMsg)
+
+ return []
diff --git a/plugins/dbms/virtuoso/filesystem.py b/plugins/dbms/virtuoso/filesystem.py
new file mode 100644
index 000000000..1e4dd8aa1
--- /dev/null
+++ b/plugins/dbms/virtuoso/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 Virtuoso it is not possible to read files"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def writeFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
+ errMsg = "on Virtuoso it is not possible to write files"
+ raise SqlmapUnsupportedFeatureException(errMsg)
diff --git a/plugins/dbms/virtuoso/fingerprint.py b/plugins/dbms/virtuoso/fingerprint.py
new file mode 100644
index 000000000..a88208588
--- /dev/null
+++ b/plugins/dbms/virtuoso/fingerprint.py
@@ -0,0 +1,89 @@
+#!/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 VIRTUOSO_ALIASES
+from lib.request import inject
+from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
+
+class Fingerprint(GenericFingerprint):
+ def __init__(self):
+ GenericFingerprint.__init__(self, DBMS.VIRTUOSO)
+
+ 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.VIRTUOSO
+ 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(VIRTUOSO_ALIASES):
+ setDbms(DBMS.VIRTUOSO)
+ return True
+
+ infoMsg = "testing %s" % DBMS.VIRTUOSO
+ logger.info(infoMsg)
+
+ result = inject.checkBooleanExpression("GET_KEYWORD(NULL,NULL) IS NULL")
+
+ if result:
+ infoMsg = "confirming %s" % DBMS.VIRTUOSO
+ logger.info(infoMsg)
+
+ result = inject.checkBooleanExpression("RDF_NOW_IMPL() IS NOT NULL")
+
+ if not result:
+ warnMsg = "the back-end DBMS is not %s" % DBMS.VIRTUOSO
+ logger.warn(warnMsg)
+
+ return False
+
+ setDbms(DBMS.VIRTUOSO)
+
+ return True
+ else:
+ warnMsg = "the back-end DBMS is not %s" % DBMS.VIRTUOSO
+ logger.warn(warnMsg)
+
+ return False
diff --git a/plugins/dbms/virtuoso/syntax.py b/plugins/dbms/virtuoso/syntax.py
new file mode 100644
index 000000000..f59b9cb9c
--- /dev/null
+++ b/plugins/dbms/virtuoso/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 CHR(97)||CHR(98)||CHR(99)||CHR(100)||CHR(101)||CHR(102)||CHR(103)||CHR(104) FROM foobar"
+ True
+ """
+
+ def escaper(value):
+ return "||".join("CHR(%d)" % _ for _ in getOrds(value))
+
+ return Syntax._escape(expression, quote, escaper)
diff --git a/plugins/dbms/virtuoso/takeover.py b/plugins/dbms/virtuoso/takeover.py
new file mode 100644
index 000000000..1ddcd068a
--- /dev/null
+++ b/plugins/dbms/virtuoso/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 Virtuoso it is not possible to execute commands"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osShell(self):
+ errMsg = "on Virtuoso it is not possible to execute commands"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osPwn(self):
+ errMsg = "on Virtuoso it is not possible to establish an "
+ errMsg += "out-of-band connection"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osSmb(self):
+ errMsg = "on Virtuoso 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 58ee2fb00..02a6d2fd2 100644
--- a/plugins/generic/databases.py
+++ b/plugins/generic/databases.py
@@ -398,7 +398,7 @@ class Databases(object):
query = rootQuery.blind.query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):
query = rootQuery.blind.query % index
- elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX, DBMS.FRONTBASE):
+ elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX, DBMS.FRONTBASE, DBMS.VIRTUOSO):
query = rootQuery.blind.query % (index, unsafeSQLIdentificatorNaming(db))
else:
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(db), index)
@@ -614,7 +614,7 @@ class Databases(object):
condQueryStr = "%%s%s" % colCondParam
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, DBMS.CACHE, DBMS.FRONTBASE):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
@@ -750,7 +750,7 @@ class Databases(object):
condQueryStr = "%%s%s" % colCondParam
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, DBMS.CACHE, DBMS.FRONTBASE):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
@@ -819,7 +819,7 @@ class Databases(object):
continue
for index in getLimitRange(count):
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
field = None
@@ -873,7 +873,7 @@ class Databases(object):
singleTimeWarnMessage(warnMsg)
if not onlyColNames:
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))
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()))
diff --git a/plugins/generic/entries.py b/plugins/generic/entries.py
index 3cb50a0fd..1ab3ce7e4 100644
--- a/plugins/generic/entries.py
+++ b/plugins/generic/entries.py
@@ -239,7 +239,7 @@ class Entries(object):
entries = BigArray(_zip(*[entries[colName] for colName in colList]))
else:
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, DBMS.CACHE):
+ elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.VIRTUOSO):
query = rootQuery.inband.query % (colString, conf.db, tbl, prioritySortColumns(colList)[0])
else:
query = rootQuery.inband.query % (colString, conf.db, tbl)
@@ -418,7 +418,7 @@ class Entries(object):
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl, index)
elif Backend.isDbms(DBMS.FIREBIRD):
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl)
- elif Backend.isDbms(DBMS.INFORMIX):
+ elif Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO):
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, sorted(colList, key=len)[0])
elif Backend.isDbms(DBMS.FRONTBASE):
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl)
diff --git a/plugins/generic/users.py b/plugins/generic/users.py
index e21cfe4c1..a8fa76ee4 100644
--- a/plugins/generic/users.py
+++ b/plugins/generic/users.py
@@ -276,7 +276,7 @@ class Users(object):
if user in retrievedUsers:
continue
- if Backend.isDbms(DBMS.INFORMIX):
+ if Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO):
count = 1
else:
infoMsg = "fetching number of password hashes "
@@ -322,7 +322,7 @@ class Users(object):
if fallback:
query = query.replace("master.dbo.fn_varbintohexstr", "sys.fn_sqlvarbasetostr")
- elif Backend.isDbms(DBMS.INFORMIX):
+ elif Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO):
query = rootQuery.blind.query % (user,)
elif Backend.isDbms(DBMS.HSQLDB):