diff --git a/data/xml/queries.xml b/data/xml/queries.xml index 7a8592438..d2ac995be 100644 --- a/data/xml/queries.xml +++ b/data/xml/queries.xml @@ -3,7 +3,8 @@ - + + @@ -242,6 +243,9 @@ + diff --git a/extra/vulnserver/vulnserver.py b/extra/vulnserver/vulnserver.py index 401d77c47..d1f954b1f 100644 --- a/extra/vulnserver/vulnserver.py +++ b/extra/vulnserver/vulnserver.py @@ -16,7 +16,9 @@ import sys import threading import traceback -if sys.version_info >= (3, 0): +PY3 = sys.version_info >= (3, 0) + +if PY3: from http.client import INTERNAL_SERVER_ERROR from http.client import NOT_FOUND from http.client import OK @@ -169,7 +171,7 @@ class ReqHandler(BaseHTTPRequestHandler): self.end_headers() else: self.end_headers() - self.wfile.write(output.encode("utf8")) + self.wfile.write(output.encode("utf8") if PY3 else output) else: self.send_response(NOT_FOUND) self.send_header("Connection", "close") diff --git a/lib/core/common.py b/lib/core/common.py index eb3e86730..944c208c3 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -3617,16 +3617,20 @@ def decodeIntToUnicode(value): try: if value > 255: _ = "%x" % value + if len(_) % 2 == 1: _ = "0%s" % _ + raw = decodeHex(_) if Backend.isDbms(DBMS.MYSQL): + # Reference: https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_ord # Note: https://github.com/sqlmapproject/sqlmap/issues/1531 retVal = getUnicode(raw, conf.encoding or UNICODE_ENCODING) elif Backend.isDbms(DBMS.MSSQL): - retVal = getUnicode(raw, "UTF-16-BE") # References: https://docs.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-2017 and https://stackoverflow.com/a/14488478 - elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE): + # Reference: https://docs.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-2017 and https://stackoverflow.com/a/14488478 + retVal = getUnicode(raw, "UTF-16-BE") + elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE): # Note: cases with Unicode code points (e.g. http://www.postgresqltutorial.com/postgresql-ascii/) retVal = _unichr(value) else: retVal = getUnicode(raw, conf.encoding) diff --git a/lib/core/settings.py b/lib/core/settings.py index 16320f006..032854bc6 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.3.11.114" +VERSION = "1.3.11.115" 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) diff --git a/lib/core/testing.py b/lib/core/testing.py index de1764c0a..db1c8712a 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -65,6 +65,8 @@ def vulnTest(): """ TESTS = ( + (u"-u --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'",)), + (u"-u --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape", (u": '\u0161u\u0107uraj'",)), ("--list-tampers", ("between", "MySQL", "xforwardedfor")), ("-r --flush-session -v 5", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar")), ("-l --flush-session --skip-waf -v 3 --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell")), diff --git a/plugins/generic/syntax.py b/plugins/generic/syntax.py index fcbaf4adc..5a5b1e0e1 100644 --- a/plugins/generic/syntax.py +++ b/plugins/generic/syntax.py @@ -7,8 +7,10 @@ See the file 'LICENSE' for copying permission import re +from lib.core.common import Backend from lib.core.convert import getBytes from lib.core.data import conf +from lib.core.enums import DBMS from lib.core.exception import SqlmapUndefinedMethod class Syntax(object): @@ -31,7 +33,7 @@ class Syntax(object): if replacement != original: retVal = retVal.replace(item, replacement) - elif len(original) != len(getBytes(original)) and "n'%s'" % original not in retVal: + elif len(original) != len(getBytes(original)) and "n'%s'" % original not in retVal and Backend.getDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.ORACLE, DBMS.MSSQL): retVal = retVal.replace("'%s'" % original, "n'%s'" % original) else: retVal = escaper(expression)