diff --git a/lib/core/common.py b/lib/core/common.py index d45409daa..ba69a3e26 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -2484,6 +2484,18 @@ def getBytes(value, encoding=UNICODE_ENCODING, errors="strict"): return retVal +def getOrds(value): + """ + Returns ORD(...) representation of provided string value + + >>> getOrds(u'fo\xf6bar') + [102, 111, 246, 98, 97, 114] + >>> getOrds(b"fo\xc3\xb6bar") + [102, 111, 195, 182, 98, 97, 114] + """ + + return [_ if isinstance(_, int) else ord(_) for _ in value] + def longestCommonPrefix(*sequences): """ Returns longest common prefix occuring in given sequences @@ -3635,8 +3647,8 @@ def maskSensitiveData(msg): """ Masks sensitive data in the supplied message - >>> maskSensitiveData('python sqlmap.py -u "http://www.test.com/vuln.php?id=1" --banner') - u'python sqlmap.py -u *********************************** --banner' + >>> maskSensitiveData('python sqlmap.py -u "http://www.test.com/vuln.php?id=1" --banner') == 'python sqlmap.py -u *********************************** --banner' + True """ retVal = getUnicode(msg) diff --git a/lib/core/settings.py b/lib/core/settings.py index 5e75d9bb9..10cbbdf5f 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -17,7 +17,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.3.5.2" +VERSION = "1.3.5.3" 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/plugins/dbms/access/syntax.py b/plugins/dbms/access/syntax.py index c6fedfd61..18021a359 100644 --- a/plugins/dbms/access/syntax.py +++ b/plugins/dbms/access/syntax.py @@ -5,12 +5,18 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common 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)" % ord(_) for _ in value) + return "&".join("CHR(%d)" % _ for _ in getOrds(value)) return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/db2/syntax.py b/plugins/dbms/db2/syntax.py index b22f4bfc0..8b2ca8910 100644 --- a/plugins/dbms/db2/syntax.py +++ b/plugins/dbms/db2/syntax.py @@ -5,17 +5,18 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common 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' + >>> 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)" % ord(_) for _ in value) + return "||".join("CHR(%d)" % _ for _ in getOrds(value)) return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/firebird/syntax.py b/plugins/dbms/firebird/syntax.py index 1dc01e7a2..b95da3a67 100644 --- a/plugins/dbms/firebird/syntax.py +++ b/plugins/dbms/firebird/syntax.py @@ -5,6 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common import getOrds from lib.core.common import isDBMSVersionAtLeast from plugins.generic.syntax import Syntax as GenericSyntax @@ -15,16 +16,16 @@ class Syntax(GenericSyntax): >>> from lib.core.common import Backend >>> Backend.setVersion('2.0') ['2.0'] - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - "SELECT 'abcdefgh' FROM foobar" + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar" + True >>> Backend.setVersion('2.1') ['2.1'] - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - 'SELECT ASCII_CHAR(97)||ASCII_CHAR(98)||ASCII_CHAR(99)||ASCII_CHAR(100)||ASCII_CHAR(101)||ASCII_CHAR(102)||ASCII_CHAR(103)||ASCII_CHAR(104) FROM foobar' + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT ASCII_CHAR(97)||ASCII_CHAR(98)||ASCII_CHAR(99)||ASCII_CHAR(100)||ASCII_CHAR(101)||ASCII_CHAR(102)||ASCII_CHAR(103)||ASCII_CHAR(104) FROM foobar" + True """ def escaper(value): - return "||".join("ASCII_CHAR(%d)" % ord(_) for _ in value) + return "||".join("ASCII_CHAR(%d)" %_ for _ in getOrds(value)) retVal = expression diff --git a/plugins/dbms/h2/syntax.py b/plugins/dbms/h2/syntax.py index 0d7cc45a7..c0208c936 100644 --- a/plugins/dbms/h2/syntax.py +++ b/plugins/dbms/h2/syntax.py @@ -5,6 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common import getOrds from lib.core.compat import xrange from plugins.generic.syntax import Syntax as GenericSyntax @@ -12,11 +13,11 @@ class Syntax(GenericSyntax): @staticmethod def escape(expression, quote=True): """ - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - 'SELECT CHAR(97)||CHAR(98)||CHAR(99)||CHAR(100)||CHAR(101)||CHAR(102)||CHAR(103)||CHAR(104) FROM foobar' + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97)||CHAR(98)||CHAR(99)||CHAR(100)||CHAR(101)||CHAR(102)||CHAR(103)||CHAR(104) FROM foobar" + True """ def escaper(value): - return "||".join("CHAR(%d)" % ord(value[i]) for i in xrange(len(value))) + return "||".join("CHAR(%d)" % _ for _ in getOrds(value)) return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/hsqldb/syntax.py b/plugins/dbms/hsqldb/syntax.py index 0d7cc45a7..c0208c936 100644 --- a/plugins/dbms/hsqldb/syntax.py +++ b/plugins/dbms/hsqldb/syntax.py @@ -5,6 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common import getOrds from lib.core.compat import xrange from plugins.generic.syntax import Syntax as GenericSyntax @@ -12,11 +13,11 @@ class Syntax(GenericSyntax): @staticmethod def escape(expression, quote=True): """ - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - 'SELECT CHAR(97)||CHAR(98)||CHAR(99)||CHAR(100)||CHAR(101)||CHAR(102)||CHAR(103)||CHAR(104) FROM foobar' + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97)||CHAR(98)||CHAR(99)||CHAR(100)||CHAR(101)||CHAR(102)||CHAR(103)||CHAR(104) FROM foobar" + True """ def escaper(value): - return "||".join("CHAR(%d)" % ord(value[i]) for i in xrange(len(value))) + return "||".join("CHAR(%d)" % _ for _ in getOrds(value)) return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/informix/syntax.py b/plugins/dbms/informix/syntax.py index 8c8f066ed..e74e95907 100644 --- a/plugins/dbms/informix/syntax.py +++ b/plugins/dbms/informix/syntax.py @@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission import re +from lib.core.common import getOrds from lib.core.common import isDBMSVersionAtLeast from lib.core.common import randomStr from plugins.generic.syntax import Syntax as GenericSyntax @@ -18,12 +19,12 @@ class Syntax(GenericSyntax): >>> from lib.core.common import Backend >>> Backend.setVersion('12.10') ['12.10'] - >>> 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' + >>> 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)" % ord(_) for _ in value) + return "||".join("CHR(%d)" % _ for _ in getOrds(value)) retVal = expression diff --git a/plugins/dbms/maxdb/syntax.py b/plugins/dbms/maxdb/syntax.py index 6e03dab9a..b8c8447f6 100644 --- a/plugins/dbms/maxdb/syntax.py +++ b/plugins/dbms/maxdb/syntax.py @@ -11,8 +11,8 @@ class Syntax(GenericSyntax): @staticmethod def escape(expression, quote=True): """ - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - "SELECT 'abcdefgh' FROM foobar" + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar" + True """ return expression diff --git a/plugins/dbms/mssqlserver/syntax.py b/plugins/dbms/mssqlserver/syntax.py index a2169de3f..847106d82 100644 --- a/plugins/dbms/mssqlserver/syntax.py +++ b/plugins/dbms/mssqlserver/syntax.py @@ -5,6 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common import getOrds from lib.core.compat import xrange from plugins.generic.syntax import Syntax as GenericSyntax @@ -12,11 +13,13 @@ class Syntax(GenericSyntax): @staticmethod def escape(expression, quote=True): """ - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - 'SELECT CHAR(97)+CHAR(98)+CHAR(99)+CHAR(100)+CHAR(101)+CHAR(102)+CHAR(103)+CHAR(104) FROM foobar' + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97)+CHAR(98)+CHAR(99)+CHAR(100)+CHAR(101)+CHAR(102)+CHAR(103)+CHAR(104) FROM foobar" + True + >>> Syntax.escape(u"SELECT 'abcd\xebfgh' FROM foobar") == "SELECT CHAR(97)+CHAR(98)+CHAR(99)+CHAR(100)+NCHAR(235)+CHAR(102)+CHAR(103)+CHAR(104) FROM foobar" + True """ def escaper(value): - return "+".join("%s(%d)" % ("CHAR" if ord(value[i]) < 256 else "NCHAR", ord(value[i])) for i in xrange(len(value))) + return "+".join("%s(%d)" % ("CHAR" if _ < 128 else "NCHAR", _) for _ in getOrds(value)) return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/mysql/syntax.py b/plugins/dbms/mysql/syntax.py index 14be4bd1c..7885bed41 100644 --- a/plugins/dbms/mysql/syntax.py +++ b/plugins/dbms/mysql/syntax.py @@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission import binascii from lib.core.common import getBytes +from lib.core.common import getOrds from lib.core.common import getUnicode from plugins.generic.syntax import Syntax as GenericSyntax @@ -15,11 +16,16 @@ class Syntax(GenericSyntax): @staticmethod def escape(expression, quote=True): """ - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - 'SELECT 0x6162636465666768 FROM foobar' + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 0x6162636465666768 FROM foobar" + True + >>> Syntax.escape(u"SELECT 'abcd\xebfgh' FROM foobar") == "SELECT CONVERT(0x61626364c3ab666768 USING utf8) FROM foobar" + True """ def escaper(value): - return "0x%s" % getUnicode(binascii.hexlify(getBytes(value))) + if all(_ < 128 for _ in getOrds(value)): + return "0x%s" % getUnicode(binascii.hexlify(getBytes(value))) + else: + return "CONVERT(0x%s USING utf8)" % getUnicode(binascii.hexlify(getBytes(value))) return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/oracle/syntax.py b/plugins/dbms/oracle/syntax.py index 3177b3542..0953a85e8 100644 --- a/plugins/dbms/oracle/syntax.py +++ b/plugins/dbms/oracle/syntax.py @@ -5,6 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common import getOrds from lib.core.compat import xrange from plugins.generic.syntax import Syntax as GenericSyntax @@ -12,11 +13,13 @@ 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' + >>> 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 + >>> Syntax.escape(u"SELECT 'abcd\xebfgh' FROM foobar") == "SELECT CHR(97)||CHR(98)||CHR(99)||CHR(100)||NCHR(235)||CHR(102)||CHR(103)||CHR(104) FROM foobar" + True """ def escaper(value): - return "||".join("%s(%d)" % ("CHR" if ord(value[i]) < 256 else "NCHR", ord(value[i])) for i in xrange(len(value))) + return "||".join("%s(%d)" % ("CHR" if _ < 128 else "NCHR", _) for _ in getOrds(value)) return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/postgresql/syntax.py b/plugins/dbms/postgresql/syntax.py index 4f9d691fa..4502ddf71 100644 --- a/plugins/dbms/postgresql/syntax.py +++ b/plugins/dbms/postgresql/syntax.py @@ -5,6 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): @@ -14,11 +15,11 @@ class Syntax(GenericSyntax): Note: PostgreSQL has a general problem with concenation operator (||) precedence (hence the parentheses enclosing) e.g. SELECT 1 WHERE 'a'!='a'||'b' will trigger error ("argument of WHERE must be type boolean, not type text") - >>> 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' + >>> 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 "(%s)" % "||".join("CHR(%d)" % ord(_) for _ in value) # Postgres CHR() function already accepts Unicode code point of character(s) + return "(%s)" % "||".join("CHR(%d)" % _ for _ in getOrds(value)) # Postgres CHR() function already accepts Unicode code point of character(s) return Syntax._escape(expression, quote, escaper) diff --git a/plugins/dbms/sqlite/syntax.py b/plugins/dbms/sqlite/syntax.py index 09cc7cc7c..7a35b0467 100644 --- a/plugins/dbms/sqlite/syntax.py +++ b/plugins/dbms/sqlite/syntax.py @@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission import binascii from lib.core.common import getBytes +from lib.core.common import getUnicode from lib.core.common import isDBMSVersionAtLeast from plugins.generic.syntax import Syntax as GenericSyntax @@ -18,17 +19,17 @@ class Syntax(GenericSyntax): >>> from lib.core.common import Backend >>> Backend.setVersion('2') ['2'] - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - "SELECT 'abcdefgh' FROM foobar" + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar" + True >>> Backend.setVersion('3') ['3'] - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - "SELECT CAST(X'6162636465666768' AS TEXT) FROM foobar" + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CAST(X'6162636465666768' AS TEXT) FROM foobar" + True """ def escaper(value): # Reference: http://stackoverflow.com/questions/3444335/how-do-i-quote-a-utf-8-string-literal-in-sqlite3 - return "CAST(X'%s' AS TEXT)" % binascii.hexlify(getBytes(value)) + return "CAST(X'%s' AS TEXT)" % getUnicode(binascii.hexlify(getBytes(value))) retVal = expression diff --git a/plugins/dbms/sybase/syntax.py b/plugins/dbms/sybase/syntax.py index 617afb010..58e8eae80 100644 --- a/plugins/dbms/sybase/syntax.py +++ b/plugins/dbms/sybase/syntax.py @@ -1,10 +1,11 @@ -#!/usr/bin/env python2 +1#!/usr/bin/env python2 """ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +from lib.core.common import getOrds from lib.core.compat import xrange from plugins.generic.syntax import Syntax as GenericSyntax @@ -12,11 +13,13 @@ class Syntax(GenericSyntax): @staticmethod def escape(expression, quote=True): """ - >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") - 'SELECT CHAR(97)+CHAR(98)+CHAR(99)+CHAR(100)+CHAR(101)+CHAR(102)+CHAR(103)+CHAR(104) FROM foobar' + >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97)+CHAR(98)+CHAR(99)+CHAR(100)+CHAR(101)+CHAR(102)+CHAR(103)+CHAR(104) FROM foobar" + True + >>> Syntax.escape(u"SELECT 'abcd\xebfgh' FROM foobar") == "SELECT CHAR(97)+CHAR(98)+CHAR(99)+CHAR(100)+TO_UNICHAR(235)+CHAR(102)+CHAR(103)+CHAR(104) FROM foobar" + True """ def escaper(value): - return "+".join("%s(%d)" % ("CHAR" if ord(value[i]) < 256 else "TO_UNICHAR", ord(value[i])) for i in xrange(len(value))) + return "+".join("%s(%d)" % ("CHAR" if _ < 128 else "TO_UNICHAR", _) for _ in getOrds(value)) return Syntax._escape(expression, quote, escaper)