diff --git a/data/xml/errors.xml b/data/xml/errors.xml
index f32b82734..ae17201d7 100644
--- a/data/xml/errors.xml
+++ b/data/xml/errors.xml
@@ -7,7 +7,7 @@
-
+
@@ -15,6 +15,10 @@
+
+
+
+
diff --git a/lib/core/agent.py b/lib/core/agent.py
index 98a0abb2e..0b66e728d 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -13,6 +13,7 @@ from lib.core.common import filterNone
from lib.core.common import getSQLSnippet
from lib.core.common import getTechnique
from lib.core.common import getTechniqueData
+from lib.core.common import hashDBRetrieve
from lib.core.common import isDBMSVersionAtLeast
from lib.core.common import isNumber
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 FROM_DUMMY_TABLE
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 PAYLOAD
from lib.core.enums import PLACE
@@ -381,6 +384,11 @@ class Agent(object):
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
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
def getComment(self, request):
diff --git a/lib/core/enums.py b/lib/core/enums.py
index b429cd895..6ed406fb9 100644
--- a/lib/core/enums.py
+++ b/lib/core/enums.py
@@ -65,6 +65,10 @@ class DBMS_DIRECTORY_NAME(object):
MONETDB = "monetdb"
DERBY = "derby"
+class FORK(object):
+ MARIADB = "MariaDB"
+ MEMSQL = "MemSQL"
+
class CUSTOM_LOGGING(object):
PAYLOAD = 9
TRAFFIC_OUT = 8
diff --git a/lib/core/option.py b/lib/core/option.py
index 3400e1612..fbc2981a1 100644
--- a/lib/core/option.py
+++ b/lib/core/option.py
@@ -1919,6 +1919,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.forcePartialUnion = False
kb.forceThreads = None
kb.forceWhere = None
+ kb.forkNote = None
kb.futileUnion = None
kb.heavilyDynamic = False
kb.headersFile = None
diff --git a/lib/core/settings.py b/lib/core/settings.py
index cb6214364..e4d2fe0d8 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.30"
+VERSION = "1.4.1.31"
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)
@@ -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")
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")
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
SQLITE_ALIASES = ("sqlite", "sqlite3")
diff --git a/lib/parse/html.py b/lib/parse/html.py
index 9357ab39f..68fe55621 100644
--- a/lib/parse/html.py
+++ b/lib/parse/html.py
@@ -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):
self.dbms = self._dbms
self._markAsErrorPage()
+ kb.forkNote = kb.forkNote or attrs.get("fork")
def htmlParser(page):
"""
diff --git a/plugins/dbms/mysql/fingerprint.py b/plugins/dbms/mysql/fingerprint.py
index 228ba311a..367b5969e 100644
--- a/plugins/dbms/mysql/fingerprint.py
+++ b/plugins/dbms/mysql/fingerprint.py
@@ -17,6 +17,7 @@ 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.enums import FORK
from lib.core.enums import HASHDB_KEYS
from lib.core.enums import OS
from lib.core.session import setDbms
@@ -175,6 +176,13 @@ class Fingerprint(GenericFingerprint):
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:
warnMsg = "the back-end DBMS is not %s" % DBMS.MYSQL
logger.warn(warnMsg)
@@ -182,7 +190,7 @@ class Fingerprint(GenericFingerprint):
return False
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
# Reference: http://bugs.mysql.com/bug.php?id=15855