Adding support for MemSQL (MySQL fork)

This commit is contained in:
Miroslav Stampar 2020-01-20 23:11:37 +01:00
parent 9f85412017
commit b25181f061
7 changed files with 30 additions and 4 deletions

View File

@ -7,7 +7,7 @@
<error regexp="Warning.*?\Wmysqli?_"/> <error regexp="Warning.*?\Wmysqli?_"/>
<error regexp="MySQLSyntaxErrorException"/> <error regexp="MySQLSyntaxErrorException"/>
<error regexp="valid MySQL result"/> <error regexp="valid MySQL result"/>
<error regexp="check the manual that (corresponds to|fits) your (MySQL|MariaDB) server version"/> <error regexp="check the manual that (corresponds to|fits) your MySQL server version"/>
<error regexp="Unknown column '[^ ]+' in 'field list'"/> <error regexp="Unknown column '[^ ]+' in 'field list'"/>
<error regexp="MySqlClient\."/> <error regexp="MySqlClient\."/>
<error regexp="com\.mysql\.jdbc"/> <error regexp="com\.mysql\.jdbc"/>
@ -15,6 +15,10 @@
<error regexp="Pdo[./_\\]Mysql"/> <error regexp="Pdo[./_\\]Mysql"/>
<error regexp="MySqlException"/> <error regexp="MySqlException"/>
<error regexp="SQLSTATE\[\d+\]: Syntax error or access violation"/> <error regexp="SQLSTATE\[\d+\]: Syntax error or access violation"/>
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/>
<error regexp="MemSQL does not support this type of query" fork="MemSQL"/>
<error regexp="is not supported by MemSQL" fork="MemSQL"/>
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/>
</dbms> </dbms>
<!-- PostgreSQL --> <!-- PostgreSQL -->

View File

@ -13,6 +13,7 @@ from lib.core.common import filterNone
from lib.core.common import getSQLSnippet from lib.core.common import getSQLSnippet
from lib.core.common import getTechnique from lib.core.common import getTechnique
from lib.core.common import getTechniqueData from lib.core.common import getTechniqueData
from lib.core.common import hashDBRetrieve
from lib.core.common import isDBMSVersionAtLeast from lib.core.common import isDBMSVersionAtLeast
from lib.core.common import isNumber from lib.core.common import isNumber
from lib.core.common import isTechniqueAvailable from lib.core.common import isTechniqueAvailable
@ -34,6 +35,8 @@ from lib.core.data import queries
from lib.core.dicts import DUMP_DATA_PREPROCESS from lib.core.dicts import DUMP_DATA_PREPROCESS
from lib.core.dicts import FROM_DUMMY_TABLE from lib.core.dicts import FROM_DUMMY_TABLE
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import FORK
from lib.core.enums import HASHDB_KEYS
from lib.core.enums import HTTP_HEADER from lib.core.enums import HTTP_HEADER
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE from lib.core.enums import PLACE
@ -381,6 +384,11 @@ class Agent(object):
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)): for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
payload = payload.replace(_, randomStr()) payload = payload.replace(_, randomStr())
if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) == FORK.MEMSQL:
payload = re.sub(r"(?i)\bORD\(", "ASCII(", payload)
payload = re.sub(r"(?i)\bMID\(", "SUBSTR(", payload)
payload = re.sub(r"(?i)\bNCHAR\b", "CHAR", payload)
return payload return payload
def getComment(self, request): def getComment(self, request):

View File

@ -65,6 +65,10 @@ class DBMS_DIRECTORY_NAME(object):
MONETDB = "monetdb" MONETDB = "monetdb"
DERBY = "derby" DERBY = "derby"
class FORK(object):
MARIADB = "MariaDB"
MEMSQL = "MemSQL"
class CUSTOM_LOGGING(object): class CUSTOM_LOGGING(object):
PAYLOAD = 9 PAYLOAD = 9
TRAFFIC_OUT = 8 TRAFFIC_OUT = 8

View File

@ -1919,6 +1919,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.forcePartialUnion = False kb.forcePartialUnion = False
kb.forceThreads = None kb.forceThreads = None
kb.forceWhere = None kb.forceWhere = None
kb.forkNote = None
kb.futileUnion = None kb.futileUnion = None
kb.heavilyDynamic = False kb.heavilyDynamic = False
kb.headersFile = None kb.headersFile = None

View File

@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.4.1.30" VERSION = "1.4.1.31"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@ -262,7 +262,7 @@ MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler")
DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT") DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT")
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
MYSQL_ALIASES = ("mysql", "my", "mariadb", "maria") MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql")
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg")
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or") ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
SQLITE_ALIASES = ("sqlite", "sqlite3") SQLITE_ALIASES = ("sqlite", "sqlite3")

View File

@ -52,6 +52,7 @@ class HTMLHandler(ContentHandler):
if kb.cache.regex[regexp] in self._lower_page and re.search(regexp, self._urldecoded_page, re.I): if kb.cache.regex[regexp] in self._lower_page and re.search(regexp, self._urldecoded_page, re.I):
self.dbms = self._dbms self.dbms = self._dbms
self._markAsErrorPage() self._markAsErrorPage()
kb.forkNote = kb.forkNote or attrs.get("fork")
def htmlParser(page): def htmlParser(page):
""" """

View File

@ -17,6 +17,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import FORK
from lib.core.enums import HASHDB_KEYS from lib.core.enums import HASHDB_KEYS
from lib.core.enums import OS from lib.core.enums import OS
from lib.core.session import setDbms from lib.core.session import setDbms
@ -175,6 +176,13 @@ class Fingerprint(GenericFingerprint):
result = inject.checkBooleanExpression("SESSION_USER() LIKE USER()") result = inject.checkBooleanExpression("SESSION_USER() LIKE USER()")
if not result:
# Note: MemSQL doesn't support SESSION_USER()
result = inject.checkBooleanExpression("GEOGRAPHY_AREA(NULL) IS NULL")
if result:
hashDBWrite(HASHDB_KEYS.DBMS_FORK, FORK.MEMSQL)
if not result: if not result:
warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
logger.warn(warnMsg) logger.warn(warnMsg)
@ -182,7 +190,7 @@ class Fingerprint(GenericFingerprint):
return False return False
if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) is None: if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) is None:
hashDBWrite(HASHDB_KEYS.DBMS_FORK, inject.checkBooleanExpression("VERSION() LIKE '%MariaDB%'") and "MariaDB" or "") hashDBWrite(HASHDB_KEYS.DBMS_FORK, inject.checkBooleanExpression("VERSION() LIKE '%MariaDB%'") and FORK.MARIADB or "")
# reading information_schema on some platforms is causing annoying timeout exits # reading information_schema on some platforms is causing annoying timeout exits
# Reference: http://bugs.mysql.com/bug.php?id=15855 # Reference: http://bugs.mysql.com/bug.php?id=15855