diff --git a/data/xml/errors.xml b/data/xml/errors.xml
index 3afdbc91c..77c46bde3 100644
--- a/data/xml/errors.xml
+++ b/data/xml/errors.xml
@@ -202,4 +202,12 @@
+
+
+
+
+
+
+
+
diff --git a/data/xml/queries.xml b/data/xml/queries.xml
index c606cbce7..ea2de83a5 100644
--- a/data/xml/queries.xml
+++ b/data/xml/queries.xml
@@ -1130,4 +1130,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/controller/handler.py b/lib/controller/handler.py
index 5fca7156a..86ee67f21 100644
--- a/lib/controller/handler.py
+++ b/lib/controller/handler.py
@@ -11,59 +11,62 @@ from lib.core.data import kb
from lib.core.dicts import DBMS_DICT
from lib.core.enums import DBMS
from lib.core.exception import SqlmapConnectionException
+from lib.core.settings import ACCESS_ALIASES
+from lib.core.settings import DB2_ALIASES
+from lib.core.settings import DERBY_ALIASES
+from lib.core.settings import FIREBIRD_ALIASES
+from lib.core.settings import H2_ALIASES
+from lib.core.settings import HSQLDB_ALIASES
+from lib.core.settings import INFORMIX_ALIASES
+from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import MCKOI_ALIASES
+from lib.core.settings import MONETDB_ALIASES
from lib.core.settings import MSSQL_ALIASES
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 SQLITE_ALIASES
-from lib.core.settings import ACCESS_ALIASES
-from lib.core.settings import FIREBIRD_ALIASES
-from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES
-from lib.core.settings import DB2_ALIASES
-from lib.core.settings import HSQLDB_ALIASES
-from lib.core.settings import H2_ALIASES
-from lib.core.settings import INFORMIX_ALIASES
-from lib.core.settings import MONETDB_ALIASES
-from lib.core.settings import DERBY_ALIASES
from lib.core.settings import VERTICA_ALIASES
from lib.utils.sqlalchemy import SQLAlchemy
-from plugins.dbms.mckoi import MckoiMap
-from plugins.dbms.mckoi.connector import Connector as MckoiConn
-from plugins.dbms.mssqlserver import MSSQLServerMap
-from plugins.dbms.mssqlserver.connector import Connector as MSSQLServerConn
-from plugins.dbms.mysql import MySQLMap
-from plugins.dbms.mysql.connector import Connector as MySQLConn
-from plugins.dbms.oracle import OracleMap
-from plugins.dbms.oracle.connector import Connector as OracleConn
-from plugins.dbms.postgresql import PostgreSQLMap
-from plugins.dbms.postgresql.connector import Connector as PostgreSQLConn
-from plugins.dbms.sqlite import SQLiteMap
-from plugins.dbms.sqlite.connector import Connector as SQLiteConn
-from plugins.dbms.access import AccessMap
from plugins.dbms.access.connector import Connector as AccessConn
-from plugins.dbms.firebird import FirebirdMap
-from plugins.dbms.firebird.connector import Connector as FirebirdConn
-from plugins.dbms.maxdb import MaxDBMap
-from plugins.dbms.maxdb.connector import Connector as MaxDBConn
-from plugins.dbms.sybase import SybaseMap
-from plugins.dbms.sybase.connector import Connector as SybaseConn
-from plugins.dbms.db2 import DB2Map
+from plugins.dbms.access import AccessMap
from plugins.dbms.db2.connector import Connector as DB2Conn
-from plugins.dbms.hsqldb import HSQLDBMap
-from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
-from plugins.dbms.h2 import H2Map
-from plugins.dbms.h2.connector import Connector as H2Conn
-from plugins.dbms.informix import InformixMap
-from plugins.dbms.informix.connector import Connector as InformixConn
-from plugins.dbms.monetdb import MonetDBMap
-from plugins.dbms.monetdb.connector import Connector as MonetDBConn
-from plugins.dbms.derby import DerbyMap
+from plugins.dbms.db2 import DB2Map
from plugins.dbms.derby.connector import Connector as DerbyConn
-from plugins.dbms.vertica import VerticaMap
+from plugins.dbms.derby import DerbyMap
+from plugins.dbms.firebird.connector import Connector as FirebirdConn
+from plugins.dbms.firebird import FirebirdMap
+from plugins.dbms.h2.connector import Connector as H2Conn
+from plugins.dbms.h2 import H2Map
+from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
+from plugins.dbms.hsqldb import HSQLDBMap
+from plugins.dbms.informix.connector import Connector as InformixConn
+from plugins.dbms.informix import InformixMap
+from plugins.dbms.maxdb.connector import Connector as MaxDBConn
+from plugins.dbms.maxdb import MaxDBMap
+from plugins.dbms.mckoi.connector import Connector as MckoiConn
+from plugins.dbms.mckoi import MckoiMap
+from plugins.dbms.monetdb.connector import Connector as MonetDBConn
+from plugins.dbms.monetdb import MonetDBMap
+from plugins.dbms.mssqlserver.connector import Connector as MSSQLServerConn
+from plugins.dbms.mssqlserver import MSSQLServerMap
+from plugins.dbms.mysql.connector import Connector as MySQLConn
+from plugins.dbms.mysql import MySQLMap
+from plugins.dbms.oracle.connector import Connector as OracleConn
+from plugins.dbms.oracle import OracleMap
+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.sqlite.connector import Connector as SQLiteConn
+from plugins.dbms.sqlite import SQLiteMap
+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
def setHandler():
"""
@@ -89,6 +92,7 @@ def setHandler():
(DBMS.DERBY, DERBY_ALIASES, DerbyMap, DerbyConn),
(DBMS.VERTICA, VERTICA_ALIASES, VerticaMap, VerticaConn),
(DBMS.MCKOI, MCKOI_ALIASES, MckoiMap, MckoiConn),
+ (DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn),
]
_ = 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 dd6cc5dae..301118201 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -657,7 +657,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):
+ 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):
if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -946,7 +946,7 @@ class Agent(object):
fromFrom = limitedQuery[fromIndex + 1:]
orderBy = None
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr
diff --git a/lib/core/common.py b/lib/core/common.py
index b35e1074b..2dbaaa2ae 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -1461,7 +1461,7 @@ def parseTargetDirect():
remote = False
for dbms in SUPPORTED_DBMS:
- details = re.search(r"^(?P%s)://(?P(?P.+?)\:(?P.*)\@)?(?P(?P[\w.-]+?)\:(?P[\d]+)\/)?(?P[\w\d\ \:\.\_\-\/\\]+?)$" % dbms, conf.direct, re.I)
+ details = re.search(r"^(?P%s)://(?P(?P.*?)\:(?P.*)\@)?(?P(?P[\w.-]+?)\:(?P[\d]+)\/)?(?P[\w\d\ \:\.\_\-\/\\]+?)$" % dbms, conf.direct, re.I)
if details:
conf.dbms = details.group("dbms")
@@ -4069,7 +4069,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)
retVal = "`%s`" % retVal
- elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI):
+ elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO):
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
retVal = "\"%s\"" % retVal.upper()
@@ -4107,7 +4107,7 @@ def unsafeSQLIdentificatorNaming(name):
if isinstance(name, six.string_types):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.SQLITE):
retVal = name.replace("`", "")
- elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.INFORMIX, DBMS.HSQLDB, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI):
+ elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.INFORMIX, DBMS.HSQLDB, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO):
retVal = name.replace("\"", "")
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
retVal = name.replace("\"", "").upper()
diff --git a/lib/core/dicts.py b/lib/core/dicts.py
index c1aa9278f..561502372 100644
--- a/lib/core/dicts.py
+++ b/lib/core/dicts.py
@@ -25,6 +25,7 @@ from lib.core.settings import MYSQL_ALIASES
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 SQLITE_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import VERTICA_ALIASES
@@ -206,6 +207,7 @@ DBMS_DICT = {
DBMS.DERBY: (DERBY_ALIASES, "pydrda", "https://github.com/nakagami/pydrda/", None),
DBMS.VERTICA: (VERTICA_ALIASES, "vertica-python", "https://github.com/vertica/vertica-python", "vertica+vertica_python"),
DBMS.MCKOI: (MCKOI_ALIASES, None, None, None),
+ DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None),
}
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
diff --git a/lib/core/enums.py b/lib/core/enums.py
index 2d51dd080..76d0760af 100644
--- a/lib/core/enums.py
+++ b/lib/core/enums.py
@@ -49,6 +49,7 @@ class DBMS(object):
DERBY = "Apache Derby"
VERTICA = "Vertica"
MCKOI = "Mckoi"
+ PRESTO = "Presto"
class DBMS_DIRECTORY_NAME(object):
ACCESS = "access"
@@ -68,6 +69,7 @@ class DBMS_DIRECTORY_NAME(object):
DERBY = "derby"
VERTICA = "vertica"
MCKOI = "mckoi"
+ PRESTO = "presto"
class FORK(object):
MARIADB = "MariaDB"
diff --git a/lib/core/settings.py b/lib/core/settings.py
index 7a1f6205f..3ea1fef5f 100644
--- a/lib/core/settings.py
+++ b/lib/core/settings.py
@@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr
# sqlmap version (...)
-VERSION = "1.4.1.42"
+VERSION = "1.4.1.43"
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)
@@ -263,6 +263,7 @@ MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler")
DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT")
VERTICA_SYSTEM_DBS = ("v_catalog", "v_internal", "v_monitor",)
MCKOI_SYSTEM_DBS = ("",)
+PRESTO_SYSTEM_DBS = ("information_schema",)
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql")
@@ -281,15 +282,16 @@ MONETDB_ALIASES = ("monet", "monetdb",)
DERBY_ALIASES = ("derby", "apache derby",)
VERTICA_ALIASES = ("vertica",)
MCKOI_ALIASES = ("mckoi",)
+PRESTO_ALIASES = ("presto",)
UPPER_CASE_IDENTIFIERS = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.MAXDB, DBMS.H2, DBMS.DERBY))
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
+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
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_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))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer")
diff --git a/lib/utils/deps.py b/lib/utils/deps.py
index 006bc2e5e..19fab922f 100644
--- a/lib/utils/deps.py
+++ b/lib/utils/deps.py
@@ -52,6 +52,8 @@ def checkDependencies():
__import__("drda")
elif dbmsName == DBMS.VERTICA:
__import__("vertica_python")
+ elif dbmsName == DBMS.PRESTO:
+ __import__("prestodb")
except:
warnMsg = "sqlmap requires '%s' third-party library " % data[1]
warnMsg += "in order to directly connect to the DBMS "
diff --git a/plugins/dbms/presto/__init__.py b/plugins/dbms/presto/__init__.py
new file mode 100644
index 000000000..05f883134
--- /dev/null
+++ b/plugins/dbms/presto/__init__.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
+See the file 'LICENSE' for copying permission
+"""
+
+from lib.core.enums import DBMS
+from lib.core.settings import PRESTO_SYSTEM_DBS
+from lib.core.unescaper import unescaper
+
+from plugins.dbms.presto.enumeration import Enumeration
+from plugins.dbms.presto.filesystem import Filesystem
+from plugins.dbms.presto.fingerprint import Fingerprint
+from plugins.dbms.presto.syntax import Syntax
+from plugins.dbms.presto.takeover import Takeover
+from plugins.generic.misc import Miscellaneous
+
+class PrestoMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
+ """
+ This class defines Presto methods
+ """
+
+ def __init__(self):
+ self.excludeDbsList = PRESTO_SYSTEM_DBS
+
+ for cls in self.__class__.__bases__:
+ cls.__init__(self)
+
+ unescaper[DBMS.PRESTO] = Syntax.escape
diff --git a/plugins/dbms/presto/connector.py b/plugins/dbms/presto/connector.py
new file mode 100644
index 000000000..86b18d1e2
--- /dev/null
+++ b/plugins/dbms/presto/connector.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
+See the file 'LICENSE' for copying permission
+"""
+
+try:
+ import prestodb
+except:
+ pass
+
+import logging
+import struct
+
+from lib.core.common import getSafeExString
+from lib.core.data import conf
+from lib.core.data import logger
+from lib.core.exception import SqlmapConnectionException
+from plugins.generic.connector import Connector as GenericConnector
+
+class Connector(GenericConnector):
+ """
+ Homepage: https://github.com/prestodb/presto-python-client
+ User guide: https://github.com/prestodb/presto-python-client/blob/master/README.md
+ API: https://www.python.org/dev/peps/pep-0249/
+ PyPI package: presto-python-client
+ License: Apache License 2.0
+ """
+
+ def connect(self):
+ self.initConnection()
+
+ try:
+ self.connector = prestodb.dbapi.connect(host=self.hostname, user=self.user, catalog=self.db, port=self.port, request_timeout=conf.timeout)
+ except (prestodb.exceptions.OperationalError, prestodb.exceptions.InternalError, prestodb.exceptions.ProgrammingError, struct.error) as ex:
+ raise SqlmapConnectionException(getSafeExString(ex))
+
+ self.initCursor()
+ self.printConnected()
+
+ def fetchall(self):
+ try:
+ return self.cursor.fetchall()
+ except prestodb.exceptions.ProgrammingError as ex:
+ logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
+ return None
+
+ def execute(self, query):
+ retVal = False
+
+ try:
+ self.cursor.execute(query)
+ retVal = True
+ except (prestodb.exceptions.OperationalError, prestodb.exceptions.ProgrammingError) as ex:
+ logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
+ except prestodb.exceptions.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
diff --git a/plugins/dbms/presto/enumeration.py b/plugins/dbms/presto/enumeration.py
new file mode 100644
index 000000000..e36ed2ab9
--- /dev/null
+++ b/plugins/dbms/presto/enumeration.py
@@ -0,0 +1,58 @@
+#!/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 getBanner(self):
+ warnMsg = "on Presto it is not possible to get a banner"
+ logger.warn(warnMsg)
+
+ return None
+
+ def getCurrentDb(self):
+ warnMsg = "on Presto it is not possible to get name of the current database (schema)"
+ logger.warn(warnMsg)
+
+ def isDba(self, user=None):
+ warnMsg = "on Presto it is not possible to test if current user is DBA"
+ logger.warn(warnMsg)
+
+ def getUsers(self):
+ warnMsg = "on Presto it is not possible to enumerate the users"
+ logger.warn(warnMsg)
+
+ return []
+
+ def getPasswordHashes(self):
+ warnMsg = "on Presto it is not possible to enumerate the user password hashes"
+ logger.warn(warnMsg)
+
+ return {}
+
+ def getPrivileges(self, *args, **kwargs):
+ warnMsg = "on Presto it is not possible to enumerate the user privileges"
+ logger.warn(warnMsg)
+
+ return {}
+
+ def getRoles(self, *args, **kwargs):
+ warnMsg = "on Presto it is not possible to enumerate the user roles"
+ logger.warn(warnMsg)
+
+ return {}
+
+ def getHostname(self):
+ warnMsg = "on Presto it is not possible to enumerate the hostname"
+ logger.warn(warnMsg)
+
+ def getStatements(self):
+ warnMsg = "on Presto it is not possible to enumerate the SQL statements"
+ logger.warn(warnMsg)
+
+ return []
diff --git a/plugins/dbms/presto/filesystem.py b/plugins/dbms/presto/filesystem.py
new file mode 100644
index 000000000..68a6bf093
--- /dev/null
+++ b/plugins/dbms/presto/filesystem.py
@@ -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 lib.core.exception import SqlmapUnsupportedFeatureException
+from plugins.generic.filesystem import Filesystem as GenericFilesystem
+
+class Filesystem(GenericFilesystem):
+ def readFile(self, remoteFile):
+ errMsg = "on Presto it is not possible to read files"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def writeFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
+ errMsg = "on Presto it is not possible to write files"
+ raise SqlmapUnsupportedFeatureException(errMsg)
diff --git a/plugins/dbms/presto/fingerprint.py b/plugins/dbms/presto/fingerprint.py
new file mode 100644
index 000000000..aa0dc14fd
--- /dev/null
+++ b/plugins/dbms/presto/fingerprint.py
@@ -0,0 +1,137 @@
+#!/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 PRESTO_ALIASES
+from lib.request import inject
+from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
+
+class Fingerprint(GenericFingerprint):
+ def __init__(self):
+ GenericFingerprint.__init__(self, DBMS.PRESTO)
+
+ 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.PRESTO
+ 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(PRESTO_ALIASES):
+ setDbms(DBMS.PRESTO)
+
+ self.getBanner()
+
+ return True
+
+ infoMsg = "testing %s" % DBMS.PRESTO
+ logger.info(infoMsg)
+
+ result = inject.checkBooleanExpression("TO_BASE64URL(NULL) IS NULL")
+
+ if result:
+ infoMsg = "confirming %s" % DBMS.PRESTO
+ logger.info(infoMsg)
+
+ result = inject.checkBooleanExpression("TO_HEX(FROM_HEX(NULL)) IS NULL")
+
+ if not result:
+ warnMsg = "the back-end DBMS is not %s" % DBMS.PRESTO
+ logger.warn(warnMsg)
+
+ return False
+
+ setDbms(DBMS.PRESTO)
+
+ if not conf.extensiveFp:
+ return True
+
+ infoMsg = "actively fingerprinting %s" % DBMS.PRESTO
+ logger.info(infoMsg)
+
+ # Reference: https://prestodb.io/docs/current/release/release-0.200.html
+ if inject.checkBooleanExpression("FROM_IEEE754_32(NULL) IS NULL"):
+ Backend.setVersion(">= 0.200")
+ # Reference: https://prestodb.io/docs/current/release/release-0.193.html
+ elif inject.checkBooleanExpression("NORMAL_CDF(NULL,NULL,NULL) IS NULL"):
+ Backend.setVersion(">= 0.193")
+ # Reference: https://prestodb.io/docs/current/release/release-0.183.html
+ elif inject.checkBooleanExpression("MAP_ENTRIES(NULL) IS NULL"):
+ Backend.setVersion(">= 0.183")
+ # Reference: https://prestodb.io/docs/current/release/release-0.171.html
+ elif inject.checkBooleanExpression("CODEPOINT(NULL) IS NULL"):
+ Backend.setVersion(">= 0.171")
+ # Reference: https://prestodb.io/docs/current/release/release-0.162.html
+ elif inject.checkBooleanExpression("XXHASH64(NULL) IS NULL"):
+ Backend.setVersion(">= 0.162")
+ # Reference: https://prestodb.io/docs/current/release/release-0.151.html
+ elif inject.checkBooleanExpression("COSINE_SIMILARITY(NULL,NULL) IS NULL"):
+ Backend.setVersion(">= 0.151")
+ # Reference: https://prestodb.io/docs/current/release/release-0.143.html
+ elif inject.checkBooleanExpression("TRUNCATE(NULL) IS NULL"):
+ Backend.setVersion(">= 0.143")
+ # Reference: https://prestodb.io/docs/current/release/release-0.137.html
+ elif inject.checkBooleanExpression("BIT_COUNT(NULL,NULL) IS NULL"):
+ Backend.setVersion(">= 0.137")
+ # Reference: https://prestodb.io/docs/current/release/release-0.130.html
+ elif inject.checkBooleanExpression("MAP_CONCAT(NULL,NULL) IS NULL"):
+ Backend.setVersion(">= 0.130")
+ # Reference: https://prestodb.io/docs/current/release/release-0.115.html
+ elif inject.checkBooleanExpression("SHA1(NULL) IS NULL"):
+ Backend.setVersion(">= 0.115")
+ # Reference: https://prestodb.io/docs/current/release/release-0.100.html
+ elif inject.checkBooleanExpression("SPLIT(NULL,NULL) IS NULL"):
+ Backend.setVersion(">= 0.100")
+ # Reference: https://prestodb.io/docs/current/release/release-0.70.html
+ elif inject.checkBooleanExpression("GREATEST(NULL,NULL) IS NULL"):
+ Backend.setVersion(">= 0.70")
+ else:
+ Backend.setVersion("< 0.100")
+
+ return True
+ else:
+ warnMsg = "the back-end DBMS is not %s" % DBMS.PRESTO
+ logger.warn(warnMsg)
+
+ return False
diff --git a/plugins/dbms/presto/syntax.py b/plugins/dbms/presto/syntax.py
new file mode 100644
index 000000000..f9355c077
--- /dev/null
+++ b/plugins/dbms/presto/syntax.py
@@ -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.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/presto/takeover.py b/plugins/dbms/presto/takeover.py
new file mode 100644
index 000000000..e27563c47
--- /dev/null
+++ b/plugins/dbms/presto/takeover.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+"""
+Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
+See the file 'LICENSE' for copying permission
+"""
+
+from lib.core.exception import SqlmapUnsupportedFeatureException
+from plugins.generic.takeover import Takeover as GenericTakeover
+
+class Takeover(GenericTakeover):
+ def osCmd(self):
+ errMsg = "on Presto it is not possible to execute commands"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osShell(self):
+ errMsg = "on Presto it is not possible to execute commands"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osPwn(self):
+ errMsg = "on Presto it is not possible to establish an "
+ errMsg += "out-of-band connection"
+ raise SqlmapUnsupportedFeatureException(errMsg)
+
+ def osSmb(self):
+ errMsg = "on Presto 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 5eb713b59..b8389d089 100644
--- a/plugins/generic/databases.py
+++ b/plugins/generic/databases.py
@@ -82,7 +82,7 @@ class Databases(object):
if not kb.data.currentDb and Backend.isDbms(DBMS.VERTICA):
kb.data.currentDb = VERTICA_DEFAULT_SCHEMA
- if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA):
+ if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO):
warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms()
warnMsg += "schema names for enumeration as the counterpart to database "
warnMsg += "names on other DBMSes"
@@ -102,7 +102,7 @@ class Databases(object):
warnMsg += "names will be fetched from 'mysql' database"
logger.warn(warnMsg)
- elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.DERBY):
+ elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO):
warnMsg = "schema names are going to be used on %s " % Backend.getIdentifiedDbms()
warnMsg += "for enumeration as the counterpart to database "
warnMsg += "names on other DBMSes"
@@ -589,7 +589,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):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO):
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
@@ -731,7 +731,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):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO):
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
@@ -798,7 +798,7 @@ class Databases(object):
continue
for index in getLimitRange(count):
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO):
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
field = None
@@ -848,7 +848,7 @@ class Databases(object):
singleTimeWarnMessage(warnMsg)
if not onlyColNames:
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO):
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY):
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 74d664564..99fd9d646 100644
--- a/plugins/generic/entries.py
+++ b/plugins/generic/entries.py
@@ -232,7 +232,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):
+ elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO):
query = rootQuery.inband.query % (colString, conf.db, tbl, prioritySortColumns(colList)[0])
else:
query = rootQuery.inband.query % (colString, conf.db, tbl)
@@ -405,7 +405,7 @@ class Entries(object):
if column not in entries:
entries[column] = BigArray()
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO):
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):
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index)