From f6f6844a0dd894e347f1e85890938e302ce912e3 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Fri, 3 May 2019 13:20:15 +0200 Subject: [PATCH] Stabilizing DREI --- lib/core/common.py | 137 ++++---------- lib/core/convert.py | 252 +++++++++++++++---------- lib/core/dump.py | 2 +- lib/core/settings.py | 2 +- lib/core/testing.py | 36 ++++ lib/request/basic.py | 4 +- lib/request/comparison.py | 2 +- lib/request/connect.py | 2 +- lib/takeover/web.py | 8 +- lib/takeover/xp_cmdshell.py | 4 +- lib/techniques/blind/inference.py | 4 +- lib/techniques/dns/use.py | 6 +- lib/techniques/error/use.py | 8 +- lib/techniques/union/use.py | 4 +- lib/utils/api.py | 14 +- lib/utils/hash.py | 80 ++++---- lib/utils/hashdb.py | 2 +- plugins/dbms/access/syntax.py | 2 +- plugins/dbms/db2/syntax.py | 2 +- plugins/dbms/firebird/syntax.py | 2 +- plugins/dbms/h2/syntax.py | 2 +- plugins/dbms/hsqldb/syntax.py | 2 +- plugins/dbms/informix/syntax.py | 2 +- plugins/dbms/mssqlserver/connector.py | 4 +- plugins/dbms/mssqlserver/filesystem.py | 12 +- plugins/dbms/mssqlserver/syntax.py | 2 +- plugins/dbms/mssqlserver/takeover.py | 2 +- plugins/dbms/mysql/syntax.py | 4 +- plugins/dbms/oracle/connector.py | 10 +- plugins/dbms/oracle/syntax.py | 2 +- plugins/dbms/postgresql/syntax.py | 2 +- plugins/dbms/sqlite/connector.py | 4 +- plugins/dbms/sqlite/syntax.py | 2 +- plugins/dbms/sybase/connector.py | 4 +- plugins/dbms/sybase/syntax.py | 2 +- plugins/generic/filesystem.py | 4 +- plugins/generic/users.py | 4 +- sqlmap.py | 3 +- tamper/base64encode.py | 6 +- tamper/hex2char.py | 4 +- tamper/luanginx.py | 2 +- tamper/modsecurityversioned.py | 2 +- tamper/multiplespaces.py | 9 +- tamper/randomcase.py | 2 +- tamper/randomcomments.py | 2 +- tamper/space2dash.py | 2 +- tamper/space2hash.py | 2 +- tamper/space2morehash.py | 2 +- tamper/space2mssqlblank.py | 2 +- tamper/space2mysqlblank.py | 2 +- tamper/space2randomblank.py | 2 +- thirdparty/multipart/multipartpost.py | 2 +- 52 files changed, 347 insertions(+), 334 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index fa69c9aad..1e8b85b33 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -5,7 +5,6 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ -import base64 import binascii import codecs import collections @@ -53,10 +52,12 @@ from lib.core.compat import round from lib.core.compat import xrange from lib.core.convert import base64pickle from lib.core.convert import base64unpickle -from lib.core.convert import hexdecode +from lib.core.convert import decodeBase64 +from lib.core.convert import decodeHex +from lib.core.convert import getBytes +from lib.core.convert import getText from lib.core.convert import htmlunescape from lib.core.convert import stdoutencode -from lib.core.convert import utf8encode from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger @@ -127,7 +128,6 @@ from lib.core.settings import HOST_ALIASES from lib.core.settings import HTTP_CHUNKED_SPLIT_KEYWORDS from lib.core.settings import IGNORE_SAVE_OPTIONS from lib.core.settings import INFERENCE_UNKNOWN_CHAR -from lib.core.settings import INVALID_UNICODE_PRIVATE_AREA from lib.core.settings import IP_ADDRESS_REGEX from lib.core.settings import ISSUES_PAGE from lib.core.settings import IS_WIN @@ -156,7 +156,6 @@ from lib.core.settings import REFLECTED_REPLACEMENT_REGEX from lib.core.settings import REFLECTED_REPLACEMENT_TIMEOUT from lib.core.settings import REFLECTED_VALUE_MARKER from lib.core.settings import REFLECTIVE_MISS_THRESHOLD -from lib.core.settings import SAFE_HEX_MARKER from lib.core.settings import SENSITIVE_DATA_REGEX from lib.core.settings import SENSITIVE_OPTIONS from lib.core.settings import STDIN_PIPE_DASH @@ -1113,8 +1112,9 @@ def randomRange(start=0, stop=1000, seed=None): """ Returns random integer value in given range - >>> randomRange(1, 500, seed=0) - 9 + >>> random.seed(0) + >>> randomRange(1, 500) + 152 """ if seed is not None: @@ -1130,8 +1130,9 @@ def randomInt(length=4, seed=None): """ Returns random integer value with provided number of digits - >>> randomInt(6, seed=0) - 181911 + >>> random.seed(0) + >>> randomInt(6) + 963638 """ if seed is not None: @@ -1147,8 +1148,9 @@ def randomStr(length=4, lowercase=False, alphabet=None, seed=None): """ Returns random string value with provided number of characters - >>> randomStr(6, seed=0) - 'aUfWgj' + >>> random.seed(0) + >>> randomStr(6) + 'FUPGpY' """ if seed is not None: @@ -1685,7 +1687,7 @@ def parseUnionPage(page): entry = entry.split(kb.chars.delimiter) if conf.hexConvert: - entry = applyFunctionRecursively(entry, decodeHexValue) + entry = applyFunctionRecursively(entry, decodeDbmsHexValue) if kb.safeCharEncode: entry = applyFunctionRecursively(entry, safecharencode) @@ -1882,7 +1884,7 @@ def safeStringFormat(format_, params): Avoids problems with inappropriate string format strings >>> safeStringFormat('SELECT foo FROM %s LIMIT %d', ('bar', '1')) - u'SELECT foo FROM bar LIMIT 1' + 'SELECT foo FROM bar LIMIT 1' """ if format_.count(PAYLOAD_DELIMITER) == 2: @@ -1895,7 +1897,7 @@ def safeStringFormat(format_, params): if isinstance(params, six.string_types): retVal = retVal.replace("%s", params, 1) elif not isListLike(params): - retVal = retVal.replace("%s", getUnicode(params), 1) + retVal = retVal.replace("%s", getText(params), 1) else: start, end = 0, len(retVal) match = re.search(r"%s(.+)%s" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER), retVal) @@ -1904,7 +1906,7 @@ def safeStringFormat(format_, params): if retVal.count("%s", start, end) == len(params): for param in params: index = retVal.find("%s", start) - retVal = retVal[:index] + getUnicode(param) + retVal[index + 2:] + retVal = retVal[:index] + getText(param) + retVal[index + 2:] else: if any('%s' in _ for _ in conf.parameters.values()): parts = format_.split(' ') @@ -2457,75 +2459,6 @@ def getUnicode(value, encoding=None, noneToNull=False): except UnicodeDecodeError: return six.text_type(str(value), errors="ignore") # encoding ignored for non-basestring instances -def decodeHex(value, binary=True): - """ - Returns a decoded representation of provided hexadecimal value - - >>> decodeHex("313233") == b"123" - True - >>> decodeHex("313233", binary=False) == u"123" - True - """ - - retVal = codecs.decode(value, "hex") - - if not binary: - retVal = getUnicode(retVal) - - return retVal - -def decodeBase64(value, binary=True): - """ - Returns a decoded representation of provided Base64 value - - >>> decodeBase64("MTIz") == b"123" - True - >>> decodeBase64("MTIz", binary=False) == u"123" - True - """ - - retVal = base64.b64decode(value) - - if not binary: - retVal = getUnicode(retVal) - - return retVal - -def getBytes(value, encoding=UNICODE_ENCODING, errors="strict"): - """ - Returns byte representation of provided Unicode value - - >>> getBytes(getUnicode(b"foo\\x01\\x83\\xffbar")) == b"foo\\x01\\x83\\xffbar" - True - """ - - retVal = value - - if isinstance(value, six.text_type): - if INVALID_UNICODE_PRIVATE_AREA: - for char in xrange(0xF0000, 0xF00FF + 1): - value = value.replace(six.unichr(char), "%s%02x" % (SAFE_HEX_MARKER, char - 0xF0000)) - - retVal = value.encode(encoding, errors) - retVal = re.sub(r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER, lambda _: decodeHex(_.group(1)), retVal) - else: - retVal = value.encode(encoding, errors) - retVal = re.sub(b"\\\\x([0-9a-f]{2})", lambda _: decodeHex(_.group(1)), retVal) - - 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 @@ -2774,7 +2707,7 @@ def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CH charset = set(string.printable) - set(unsafe) def _(match): - char = getUnicode(decodeHex(match.group(1))) + char = decodeHex(match.group(1), binary=False) return char if char in charset else match.group(0) if spaceplus: @@ -2817,7 +2750,7 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False): value = re.sub(r"%(?![0-9a-fA-F]{2})", "%25", value) while True: - result = _urllib.parse.quote(utf8encode(value), safe) + result = _urllib.parse.quote(getBytes(value), safe) if limit and len(result) > URLENCODE_CHAR_LIMIT: if count >= len(URLENCODE_FAILSAFE_CHARS): @@ -3488,7 +3421,7 @@ def decodeIntToUnicode(value): _ = "%x" % value if len(_) % 2 == 1: _ = "0%s" % _ - raw = hexdecode(_) + raw = decodeHex(_) if Backend.isDbms(DBMS.MYSQL): # Note: https://github.com/sqlmapproject/sqlmap/issues/1531 @@ -4113,9 +4046,9 @@ def randomizeParameterValue(value): >>> random.seed(0) >>> randomizeParameterValue('foobar') - 'rnvnav' + 'fupgpy' >>> randomizeParameterValue('17') - '83' + '36' """ retVal = value @@ -4175,8 +4108,8 @@ def asciifyUrl(url, forceQuote=False): # Reference: http://blog.elsdoerfer.name/2008/12/12/opening-iris-in-python/ - >>> asciifyUrl(u'http://www.\u0161u\u0107uraj.com') - u'http://www.xn--uuraj-gxa24d.com' + >>> asciifyUrl(u'http://www.\\u0161u\\u0107uraj.com') == u'http://www.xn--uuraj-gxa24d.com' + True """ parts = _urllib.parse.urlsplit(url) @@ -4191,7 +4124,7 @@ def asciifyUrl(url, forceQuote=False): try: hostname = parts.hostname.encode("idna") except LookupError: - hostname = parts.hostname.encode(UNICODE_ENCODING) + hostname = parts.hostname.encode("punycode") # UTF8-quote the other parts. We check each part individually if # if needs to be quoted - that should catch some additional user @@ -4203,7 +4136,7 @@ def asciifyUrl(url, forceQuote=False): # _urllib.parse.quote(s.replace('%', '')) != s.replace('%', '') # which would trigger on all %-characters, e.g. "&". if getUnicode(s).encode("ascii", "replace") != s or forceQuote: - return _urllib.parse.quote(s.encode(UNICODE_ENCODING) if isinstance(s, six.text_type) else s, safe=safe) + s = _urllib.parse.quote(getBytes(s), safe=safe) return s username = quote(parts.username, '') @@ -4212,7 +4145,7 @@ def asciifyUrl(url, forceQuote=False): query = quote(parts.query, safe="&=") # put everything back together - netloc = hostname + netloc = getText(hostname) if username or password: netloc = '@' + netloc if password: @@ -4521,13 +4454,13 @@ def applyFunctionRecursively(value, function): return retVal -def decodeHexValue(value, raw=False): +def decodeDbmsHexValue(value, raw=False): """ Returns value decoded from DBMS specific hexadecimal representation - >>> decodeHexValue('3132332031') == u'123 1' + >>> decodeDbmsHexValue('3132332031') == u'123 1' True - >>> decodeHexValue(['0x31', '0x32']) == [u'1', u'2'] + >>> decodeDbmsHexValue(['0x31', '0x32']) == [u'1', u'2'] True """ @@ -4537,10 +4470,10 @@ def decodeHexValue(value, raw=False): retVal = value if value and isinstance(value, six.string_types): if len(value) % 2 != 0: - retVal = "%s?" % hexdecode(value[:-1]) if len(value) > 1 else value + retVal = b"%s?" % decodeHex(value[:-1]) if len(value) > 1 else value singleTimeWarnMessage("there was a problem decoding value '%s' from expected hexadecimal form" % value) else: - retVal = hexdecode(value) + retVal = decodeHex(value) if not kb.binaryField and not raw: if Backend.isDbms(DBMS.MSSQL) and value.startswith("0x"): @@ -4680,7 +4613,7 @@ def decloakToTemp(filename): content = decloak(filename) - _ = utf8encode(os.path.split(filename[:-1])[-1]) + _ = getBytes(os.path.split(filename[:-1])[-1]) prefix, suffix = os.path.splitext(_) prefix = prefix.split(os.extsep)[0] @@ -5033,7 +4966,7 @@ def unsafeVariableNaming(value): """ if value.startswith(EVALCODE_ENCODED_PREFIX): - value = getUnicode(decodeHex(value[len(EVALCODE_ENCODED_PREFIX):])) + value = decodeHex(value[len(EVALCODE_ENCODED_PREFIX):], binary=False) return value @@ -5060,7 +4993,7 @@ def chunkSplitPostData(data): >>> random.seed(0) >>> chunkSplitPostData("SELECT username,password FROM users") - '5;UAqFz\\r\\nSELEC\\r\\n8;sDK4F\\r\\nT userna\\r\\n3;UMp48\\r\\nme,\\r\\n8;3tT3Q\\r\\npassword\\r\\n4;gAL47\\r\\n FRO\\r\\n5;1qXIa\\r\\nM use\\r\\n2;yZPaE\\r\\nrs\\r\\n0\\r\\n\\r\\n' + '5;4Xe90\\r\\nSELEC\\r\\n3;irWlc\\r\\nT u\\r\\n1;eT4zO\\r\\ns\\r\\n5;YB4hM\\r\\nernam\\r\\n9;2pUD8\\r\\ne,passwor\\r\\n3;mp07y\\r\\nd F\\r\\n5;8RKXi\\r\\nROM u\\r\\n4;MvMhO\\r\\nsers\\r\\n0\\r\\n\\r\\n' """ length = len(data) diff --git a/lib/core/convert.py b/lib/core/convert.py index 20a529727..fabfe69e8 100644 --- a/lib/core/convert.py +++ b/lib/core/convert.py @@ -11,36 +11,18 @@ except: import pickle import base64 -import binascii +import codecs import json import re import sys +from lib.core.settings import INVALID_UNICODE_PRIVATE_AREA from lib.core.settings import IS_WIN from lib.core.settings import PICKLE_PROTOCOL +from lib.core.settings import SAFE_HEX_MARKER from lib.core.settings import UNICODE_ENCODING from thirdparty import six -def base64decode(value): - """ - Decodes string value from Base64 to plain format - - >>> base64decode('Zm9vYmFy') == b'foobar' - True - """ - - return base64.b64decode(unicodeencode(value)) - -def base64encode(value): - """ - Encodes string value from plain to Base64 format - - >>> base64encode('foobar') == b'Zm9vYmFy' - True - """ - - return base64.b64encode(unicodeencode(value)) - def base64pickle(value): """ Serializes (with pickle) and encodes to Base64 format supplied (binary) value @@ -52,16 +34,16 @@ def base64pickle(value): retVal = None try: - retVal = base64encode(pickle.dumps(value, PICKLE_PROTOCOL)) + retVal = encodeBase64(pickle.dumps(value, PICKLE_PROTOCOL)) except: warnMsg = "problem occurred while serializing " warnMsg += "instance of a type '%s'" % type(value) singleTimeWarnMessage(warnMsg) try: - retVal = base64encode(pickle.dumps(value)) + retVal = encodeBase64(pickle.dumps(value)) except: - retVal = base64encode(pickle.dumps(str(value), PICKLE_PROTOCOL)) + retVal = encodeBase64(pickle.dumps(str(value), PICKLE_PROTOCOL)) return retVal @@ -76,83 +58,9 @@ def base64unpickle(value): retVal = None try: - retVal = pickle.loads(base64decode(value)) + retVal = pickle.loads(decodeBase64(value)) except TypeError: - retVal = pickle.loads(base64decode(bytes(value))) - - return retVal - -def hexdecode(value): - """ - Decodes string value from hex to plain format - - >>> hexdecode('666f6f626172') == b'foobar' - True - """ - - value = value.lower() - value = value[2:] if value.startswith("0x") else value - - if six.PY2: - retVal = value.decode("hex") - else: - retVal = bytes.fromhex(value) - - return retVal - -def hexencode(value, encoding=None): - """ - Encodes string value from plain to hex format - - >>> hexencode('foobar') == b'666f6f626172' - True - """ - - retVal = unicodeencode(value, encoding) - retVal = binascii.hexlify(retVal) - - return retVal - -def unicodeencode(value, encoding=None): - """ - Returns 8-bit string representation of the supplied unicode value - - >>> unicodeencode(u'foobar') == b'foobar' - True - """ - - retVal = value - - if isinstance(value, six.text_type): - try: - retVal = value.encode(encoding or UNICODE_ENCODING) - except UnicodeEncodeError: - retVal = value.encode(encoding or UNICODE_ENCODING, "replace") - - return retVal - -def utf8encode(value): - """ - Returns 8-bit string representation of the supplied UTF-8 value - - >>> utf8encode(u'foobar') == b'foobar' - True - """ - - return unicodeencode(value, "utf-8") - -def utf8decode(value): - """ - Returns UTF-8 representation of the supplied 8-bit string representation - - >>> utf8decode(b'foobar') == u'foobar' - True - """ - - retVal = value - - if isinstance(value, six.binary_type): - retVal = value.decode("utf-8") + retVal = pickle.loads(decodeBase64(bytes(value))) return retVal @@ -186,7 +94,7 @@ def stdoutencode(data): if six.PY2: try: - retVal = unicodeencode(data or "", sys.stdout.encoding) + retVal = getBytes(data or "", sys.stdout.encoding) # Reference: http://bugs.python.org/issue1602 if IS_WIN: @@ -201,7 +109,7 @@ def stdoutencode(data): singleTimeWarnMessage(warnMsg) except: - retVal = unicodeencode(data or "") + retVal = getBytes(data or "") return retVal @@ -224,3 +132,143 @@ def dejsonize(data): """ return json.loads(data) + +def decodeHex(value, binary=True): + """ + Returns a decoded representation of provided hexadecimal value + + >>> decodeHex("313233") == b"123" + True + >>> decodeHex("313233", binary=False) == u"123" + True + """ + + retVal = value + + if isinstance(value, six.binary_type): + value = value.decode(UNICODE_ENCODING) + + if value.lower().startswith("0x"): + value = value[2:] + + retVal = codecs.decode(value, "hex") + + if not binary: + retVal = getText(retVal) + + return retVal + +def encodeHex(value, binary=True): + """ + Returns a encoded representation of provided string value + + >>> encodeHex(b"123") == b"313233" + True + >>> encodeHex("123", binary=False) + '313233' + """ + + if isinstance(value, six.text_type): + value = value.encode(UNICODE_ENCODING) + + retVal = codecs.encode(value, "hex") + + if not binary: + retVal = getText(retVal) + + return retVal + +def decodeBase64(value, binary=True): + """ + Returns a decoded representation of provided Base64 value + + >>> decodeBase64("MTIz") == b"123" + True + >>> decodeBase64("MTIz", binary=False) + '123' + """ + + retVal = base64.b64decode(value) + + if not binary: + retVal = getText(retVal) + + return retVal + +def encodeBase64(value, binary=True): + """ + Returns a decoded representation of provided Base64 value + + >>> encodeBase64(b"123") == b"MTIz" + True + >>> encodeBase64(u"123", binary=False) + 'MTIz' + """ + + if isinstance(value, six.text_type): + value = value.encode(UNICODE_ENCODING) + + retVal = base64.b64encode(value) + + if not binary: + retVal = getText(retVal) + + return retVal + +def getBytes(value, encoding=UNICODE_ENCODING, errors="strict"): + """ + Returns byte representation of provided Unicode value + + >>> getBytes(u"foo\\\\x01\\\\x83\\\\xffbar") == b"foo\\x01\\x83\\xffbar" + True + """ + + retVal = value + + if isinstance(value, six.text_type): + if INVALID_UNICODE_PRIVATE_AREA: + for char in xrange(0xF0000, 0xF00FF + 1): + value = value.replace(six.unichr(char), "%s%02x" % (SAFE_HEX_MARKER, char - 0xF0000)) + + retVal = value.encode(encoding, errors) + retVal = re.sub(r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER, lambda _: decodeHex(_.group(1)), retVal) + else: + retVal = value.encode(encoding, errors) + retVal = re.sub(b"\\\\x([0-9a-f]{2})", lambda _: decodeHex(_.group(1)), retVal) + + 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 getText(value): + """ + Returns textual value of a given value (Note: not necessary Unicode on Python2) + + >>> getText(b"foobar") + 'foobar' + >>> isinstance(getText(u"fo\\u2299bar"), six.text_type) + True + """ + + retVal = value + + if isinstance(value, six.binary_type): + retVal = value.decode(UNICODE_ENCODING) + + if six.PY2: + try: + retVal = str(retVal) + except: + pass + + return retVal diff --git a/lib/core/dump.py b/lib/core/dump.py index 75f8386c5..4c5f7c683 100644 --- a/lib/core/dump.py +++ b/lib/core/dump.py @@ -17,7 +17,6 @@ from lib.core.common import Backend from lib.core.common import checkFile from lib.core.common import dataToDumpFile from lib.core.common import dataToStdout -from lib.core.common import getBytes from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import isListLike @@ -29,6 +28,7 @@ from lib.core.common import randomInt from lib.core.common import safeCSValue from lib.core.common import unsafeSQLIdentificatorNaming from lib.core.compat import xrange +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger diff --git a/lib/core/settings.py b/lib/core/settings.py index 9014379ed..8cfbaf40d 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -18,7 +18,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.3.5.9" +VERSION = "1.3.5.10" 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 3507c1e5a..c4ef74759 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -27,6 +27,7 @@ from lib.core.common import randomStr from lib.core.common import readXmlFile from lib.core.common import shellExec from lib.core.compat import round +from lib.core.compat import xrange from lib.core.data import conf from lib.core.data import logger from lib.core.data import paths @@ -47,6 +48,7 @@ class Failures(object): failedTraceBack = None _failures = Failures() +_rand = 0 def vulnTest(): """ @@ -91,11 +93,45 @@ def vulnTest(): return retVal +def dirtyPatchRandom(): + """ + Unifying random generated data across different Python versions + """ + + def _lcg(): + global _rand + a = 1140671485 + c = 128201163 + m = 2 ** 24 + _rand = (a * _rand + c) % m + return _rand + + def _randint(a, b): + _ = a + (_lcg() % (b - a + 1)) + return _ + + def _choice(seq): + return seq[_randint(0, len(seq) - 1)] + + def _sample(population, k): + return [_choice(population) for _ in xrange(k)] + + def _seed(seed): + global _rand + _rand = seed + + random.choice = _choice + random.randint = _randint + random.sample = _sample + random.seed = _seed + def smokeTest(): """ Runs the basic smoke testing of a program """ + dirtyPatchRandom() + retVal = True count, length = 0, 0 diff --git a/lib/request/basic.py b/lib/request/basic.py index 7a071a980..593cd360a 100644 --- a/lib/request/basic.py +++ b/lib/request/basic.py @@ -14,11 +14,9 @@ import struct import zlib from lib.core.common import Backend -from lib.core.common import decodeHex from lib.core.common import extractErrorMessage from lib.core.common import extractRegexResult from lib.core.common import filterNone -from lib.core.common import getBytes from lib.core.common import getPublicTypeMembers from lib.core.common import getSafeExString from lib.core.common import getUnicode @@ -29,6 +27,8 @@ from lib.core.common import resetCookieJar from lib.core.common import singleTimeLogMessage from lib.core.common import singleTimeWarnMessage from lib.core.common import unArrayizeValue +from lib.core.convert import decodeHex +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger diff --git a/lib/request/comparison.py b/lib/request/comparison.py index 3fc717d74..05eb7bedf 100644 --- a/lib/request/comparison.py +++ b/lib/request/comparison.py @@ -8,12 +8,12 @@ See the file 'LICENSE' for copying permission import re from lib.core.common import extractRegexResult -from lib.core.common import getBytes from lib.core.common import getFilteredPageContent from lib.core.common import listToStrValue from lib.core.common import removeDynamicContent from lib.core.common import wasLastResponseDBMSError from lib.core.common import wasLastResponseHTTPError +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger diff --git a/lib/request/connect.py b/lib/request/connect.py index b1f8a9ef3..8697677d5 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -34,7 +34,6 @@ from lib.core.common import evaluateCode from lib.core.common import extractRegexResult from lib.core.common import filterNone from lib.core.common import findMultipartPostBoundary -from lib.core.common import getBytes from lib.core.common import getCurrentThreadData from lib.core.common import getHeader from lib.core.common import getHostHeader @@ -60,6 +59,7 @@ from lib.core.common import urldecode from lib.core.common import urlencode from lib.core.compat import patchHeaders from lib.core.compat import xrange +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger diff --git a/lib/takeover/web.py b/lib/takeover/web.py index 95c3e50fd..13d65c688 100644 --- a/lib/takeover/web.py +++ b/lib/takeover/web.py @@ -32,8 +32,8 @@ from lib.core.common import randomStr from lib.core.common import readInput from lib.core.common import singleTimeWarnMessage from lib.core.compat import xrange -from lib.core.convert import hexencode -from lib.core.convert import utf8encode +from lib.core.convert import encodeHex +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger @@ -152,7 +152,7 @@ class Web: randInt = randomInt() query += "OR %d=%d " % (randInt, randInt) - query += getSQLSnippet(DBMS.MYSQL, "write_file_limit", OUTFILE=outFile, HEXSTRING=hexencode(uplQuery, conf.encoding)) + query += getSQLSnippet(DBMS.MYSQL, "write_file_limit", OUTFILE=outFile, HEXSTRING=encodeHex(uplQuery, binary=False)) query = agent.prefixQuery(query) # Note: No need for suffix as 'write_file_limit' already ends with comment (required) payload = agent.payload(newValue=query) page = Request.queryPage(payload) @@ -332,7 +332,7 @@ class Web: with open(filename, "w+b") as f: _ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webPlatform)) - _ = _.replace(SHELL_WRITABLE_DIR_TAG, utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)) + _ = _.replace(SHELL_WRITABLE_DIR_TAG, getBytes(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)) f.write(_) self.unionWriteFile(filename, self.webStagerFilePath, "text", forceCheck=True) diff --git a/lib/takeover/xp_cmdshell.py b/lib/takeover/xp_cmdshell.py index 788baa04c..dc2e8eaf2 100644 --- a/lib/takeover/xp_cmdshell.py +++ b/lib/takeover/xp_cmdshell.py @@ -21,7 +21,7 @@ from lib.core.common import randomStr from lib.core.common import readInput from lib.core.common import wasLastResponseDelayed from lib.core.compat import xrange -from lib.core.convert import hexencode +from lib.core.convert import encodeHex from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger @@ -166,7 +166,7 @@ class XP_cmdshell: # Obfuscate the command to execute, also useful to bypass filters # on single-quotes self._randStr = randomStr(lowercase=True) - self._cmd = "0x%s" % hexencode(cmd, conf.encoding) + self._cmd = "0x%s" % encodeHex(cmd, binary=False) self._forgedCmd = "DECLARE @%s VARCHAR(8000);" % self._randStr self._forgedCmd += "SET @%s=%s;" % (self._randStr, self._cmd) diff --git a/lib/techniques/blind/inference.py b/lib/techniques/blind/inference.py index 87fcf8e9b..34415fa6b 100644 --- a/lib/techniques/blind/inference.py +++ b/lib/techniques/blind/inference.py @@ -14,7 +14,7 @@ from lib.core.agent import agent from lib.core.common import Backend from lib.core.common import calculateDeltaSeconds from lib.core.common import dataToStdout -from lib.core.common import decodeHexValue +from lib.core.common import decodeDbmsHexValue from lib.core.common import decodeIntToUnicode from lib.core.common import filterControlChars from lib.core.common import getCharset @@ -656,7 +656,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None retrievedLength = len(finalValue or "") if finalValue is not None: - finalValue = decodeHexValue(finalValue) if conf.hexConvert else finalValue + finalValue = decodeDbmsHexValue(finalValue) if conf.hexConvert else finalValue hashDBWrite(expression, finalValue) elif partialValue: hashDBWrite(expression, "%s%s" % (PARTIAL_VALUE_MARKER if not conf.hexConvert else PARTIAL_HEX_VALUE_MARKER, partialValue)) diff --git a/lib/techniques/dns/use.py b/lib/techniques/dns/use.py index 04f4f6899..0f17f463a 100644 --- a/lib/techniques/dns/use.py +++ b/lib/techniques/dns/use.py @@ -13,7 +13,7 @@ from lib.core.agent import agent from lib.core.common import Backend from lib.core.common import calculateDeltaSeconds from lib.core.common import dataToStdout -from lib.core.common import decodeHexValue +from lib.core.common import decodeDbmsHexValue from lib.core.common import extractRegexResult from lib.core.common import getSQLSnippet from lib.core.common import hashDBRetrieve @@ -85,7 +85,7 @@ def dnsUse(payload, expression): if _: _ = extractRegexResult(r"%s\.(?P.+)\.%s" % (prefix, suffix), _, re.I) - _ = decodeHexValue(_) + _ = decodeDbmsHexValue(_) output = (output or "") + _ offset += len(_) @@ -94,7 +94,7 @@ def dnsUse(payload, expression): else: break - output = decodeHexValue(output) if conf.hexConvert else output + output = decodeDbmsHexValue(output) if conf.hexConvert else output kb.dnsMode = False diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py index ce70b8b96..47dcb3c90 100644 --- a/lib/techniques/error/use.py +++ b/lib/techniques/error/use.py @@ -16,7 +16,7 @@ from lib.core.bigarray import BigArray from lib.core.common import Backend from lib.core.common import calculateDeltaSeconds from lib.core.common import dataToStdout -from lib.core.common import decodeHexValue +from lib.core.common import decodeDbmsHexValue from lib.core.common import extractRegexResult from lib.core.common import firstNotNone from lib.core.common import getConsoleWidth @@ -33,7 +33,7 @@ from lib.core.common import readInput from lib.core.common import unArrayizeValue from lib.core.common import wasLastResponseHTTPError from lib.core.compat import xrange -from lib.core.convert import hexdecode +from lib.core.convert import decodeHex from lib.core.convert import htmlunescape from lib.core.data import conf from lib.core.data import kb @@ -201,7 +201,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False): hashDBWrite(expression, "%s%s" % (retVal, PARTIAL_VALUE_MARKER)) raise - retVal = decodeHexValue(retVal) if conf.hexConvert else retVal + retVal = decodeDbmsHexValue(retVal) if conf.hexConvert else retVal if isinstance(retVal, six.string_types): retVal = htmlunescape(retVal).replace("
", "\n") @@ -281,7 +281,7 @@ def _formatPartialContent(value): if value and isinstance(value, six.string_types): try: - value = hexdecode(value) + value = decodeHex(value, binary=False) except: pass finally: diff --git a/lib/techniques/union/use.py b/lib/techniques/union/use.py index a0e9e77bc..071398c4a 100644 --- a/lib/techniques/union/use.py +++ b/lib/techniques/union/use.py @@ -18,12 +18,10 @@ from lib.core.common import Backend from lib.core.common import calculateDeltaSeconds from lib.core.common import clearConsoleLine from lib.core.common import dataToStdout -from lib.core.common import decodeBase64 from lib.core.common import extractRegexResult from lib.core.common import firstNotNone from lib.core.common import flattenValue from lib.core.common import safeStringFormat -from lib.core.common import getBytes from lib.core.common import getConsoleWidth from lib.core.common import getPartRun from lib.core.common import getUnicode @@ -42,6 +40,8 @@ from lib.core.common import singleTimeWarnMessage from lib.core.common import unArrayizeValue from lib.core.common import wasLastResponseDBMSError from lib.core.compat import xrange +from lib.core.convert import decodeBase64 +from lib.core.convert import getBytes from lib.core.convert import htmlunescape from lib.core.data import conf from lib.core.data import kb diff --git a/lib/utils/api.py b/lib/utils/api.py index f6915613b..14c3760e4 100644 --- a/lib/utils/api.py +++ b/lib/utils/api.py @@ -20,13 +20,13 @@ import tempfile import time from lib.core.common import dataToStdout -from lib.core.common import decodeBase64 from lib.core.common import getSafeExString from lib.core.common import saveConfig from lib.core.common import unArrayizeValue from lib.core.compat import xrange -from lib.core.convert import base64encode -from lib.core.convert import hexencode +from lib.core.convert import encodeBase64 +from lib.core.convert import encodeHex +from lib.core.convert import decodeBase64 from lib.core.convert import dejsonize from lib.core.convert import jsonize from lib.core.data import conf @@ -365,7 +365,7 @@ def task_new(): """ Create a new task """ - taskid = hexencode(os.urandom(8)) + taskid = encodeHex(os.urandom(8), binary=False) remote_addr = request.remote_addr DataStore.tasks[taskid] = Task(taskid, remote_addr) @@ -650,7 +650,7 @@ def download(taskid, target, filename): logger.debug("(%s) Retrieved content of file %s" % (taskid, target)) with open(path, 'rb') as inf: file_content = inf.read() - return jsonize({"success": True, "file": base64encode(file_content)}) + return jsonize({"success": True, "file": encodeBase64(file_content, binary=False)}) else: logger.warning("[%s] File does not exist %s" % (taskid, target)) return jsonize({"success": False, "message": "File does not exist"}) @@ -660,7 +660,7 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST REST-JSON API server """ - DataStore.admin_token = hexencode(os.urandom(16)) + DataStore.admin_token = encodeHex(os.urandom(16), binary=False) DataStore.username = username DataStore.password = password @@ -717,7 +717,7 @@ def _client(url, options=None): headers = {"Content-Type": "application/json"} if DataStore.username or DataStore.password: - headers["Authorization"] = "Basic %s" % base64encode("%s:%s" % (DataStore.username or "", DataStore.password or "")) + headers["Authorization"] = "Basic %s" % encodeBase64("%s:%s" % (DataStore.username or "", DataStore.password or ""), binary=False) req = _urllib.request.Request(url, data, headers) response = _urllib.request.urlopen(req) diff --git a/lib/utils/hash.py b/lib/utils/hash.py index 0f5561603..f34a7c799 100644 --- a/lib/utils/hash.py +++ b/lib/utils/hash.py @@ -50,8 +50,6 @@ from lib.core.common import Backend from lib.core.common import checkFile from lib.core.common import clearConsoleLine from lib.core.common import dataToStdout -from lib.core.common import decodeBase64 -from lib.core.common import getBytes from lib.core.common import getFileItems from lib.core.common import getPublicTypeMembers from lib.core.common import getSafeExString @@ -64,9 +62,11 @@ from lib.core.common import readInput from lib.core.common import singleTimeLogMessage from lib.core.common import singleTimeWarnMessage from lib.core.compat import xrange -from lib.core.convert import hexdecode -from lib.core.convert import hexencode -from lib.core.convert import utf8encode +from lib.core.convert import encodeHex +from lib.core.convert import decodeBase64 +from lib.core.convert import decodeHex +from lib.core.convert import getBytes +from lib.core.convert import getText from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger @@ -161,8 +161,8 @@ def mssql_passwd(password, salt, uppercase=False): '0x01004086ceb60c90646a8ab9889fe3ed8e5c150b5460ece8425a' """ - binsalt = hexdecode(salt) - unistr = "".join(("%s\0" if ord(_) < 256 else "%s") % utf8encode(_) for _ in password) + binsalt = decodeHex(salt) + unistr = b"".join(b"%s\0" % _.encode(UNICODE_ENCODING) if ord(_) < 256 else _.encode(UNICODE_ENCODING) for _ in password) retVal = "0100%s%s" % (salt, sha1(unistr + binsalt).hexdigest()) @@ -179,8 +179,8 @@ def mssql_old_passwd(password, salt, uppercase=True): # prior to version '2005' '0x01004086CEB60C90646A8AB9889FE3ED8E5C150B5460ECE8425AC7BB7255C0C81D79AA5D0E93D4BB077FB9A51DA0' """ - binsalt = hexdecode(salt) - unistr = "".join(("%s\0" if ord(_) < 256 else "%s") % utf8encode(_) for _ in password) + binsalt = decodeHex(salt) + unistr = b"".join(b"%s\0" % _.encode(UNICODE_ENCODING) if ord(_) < 256 else _.encode(UNICODE_ENCODING) for _ in password) retVal = "0100%s%s%s" % (salt, sha1(unistr + binsalt).hexdigest(), sha1(unistr.upper() + binsalt).hexdigest()) @@ -195,8 +195,8 @@ def mssql_new_passwd(password, salt, uppercase=False): '0x02004086ceb6eb051cdbc5bdae68ffc66c918d4977e592f6bdfc2b444a7214f71fa31c35902c5b7ae773ed5f4c50676d329120ace32ee6bc81c24f70711eb0fc6400e85ebf25' """ - binsalt = hexdecode(salt) - unistr = "".join(("%s\0" if ord(_) < 256 else "%s") % utf8encode(_) for _ in password) + binsalt = decodeHex(salt) + unistr = b"".join(b"%s\0" % _.encode(UNICODE_ENCODING) if ord(_) < 256 else _.encode(UNICODE_ENCODING) for _ in password) retVal = "0200%s%s" % (salt, sha512(unistr + binsalt).hexdigest()) @@ -213,9 +213,10 @@ def oracle_passwd(password, salt, uppercase=True): 'S:2BFCFDF5895014EE9BB2B9BA067B01E0389BB5711B7B5F82B7235E9E182C' """ - binsalt = hexdecode(salt) + binsalt = decodeHex(salt) + password = getBytes(password) - retVal = "s:%s%s" % (sha1(utf8encode(password) + binsalt).hexdigest(), salt) + retVal = "s:%s%s" % (sha1(password + binsalt).hexdigest(), salt) return retVal.upper() if uppercase else retVal.lower() @@ -230,17 +231,14 @@ def oracle_old_passwd(password, username, uppercase=True): # prior to version ' IV, pad = "\0" * 8, "\0" - username = getBytes(username) - password = getBytes(password) + unistr = b"".join(b"\0%s" % _.encode(UNICODE_ENCODING) if ord(_) < 256 else _.encode(UNICODE_ENCODING) for _ in (username + password).upper()) - unistr = "".join("\0%s" % c for c in (username + password).upper()) - - cipher = des(hexdecode("0123456789ABCDEF"), CBC, IV, pad) + cipher = des(decodeHex("0123456789ABCDEF"), CBC, IV, pad) encrypted = cipher.encrypt(unistr) cipher = des(encrypted[-8:], CBC, IV, pad) encrypted = cipher.encrypt(unistr) - retVal = hexencode(encrypted[-8:]) + retVal = encodeHex(encrypted[-8:], binary=False) return retVal.upper() if uppercase else retVal.lower() @@ -270,46 +268,46 @@ def sha1_generic_passwd(password, uppercase=False): def apache_sha1_passwd(password, **kwargs): """ - >>> apache_sha1_passwd(password='testpass') == '{SHA}IGyAQTualsExLMNGt9JRe4RGPt0=' - True + >>> apache_sha1_passwd(password='testpass') + '{SHA}IGyAQTualsExLMNGt9JRe4RGPt0=' """ password = getBytes(password) - return "{SHA}%s" % getUnicode(base64.b64encode(sha1(password).digest())) + return "{SHA}%s" % getText(base64.b64encode(sha1(password).digest())) def ssha_passwd(password, salt, **kwargs): """ - >>> ssha_passwd(password='testpass', salt='salt') == '{SSHA}mU1HPTvnmoXOhE4ROHP6sWfbfoRzYWx0' - True + >>> ssha_passwd(password='testpass', salt='salt') + '{SSHA}mU1HPTvnmoXOhE4ROHP6sWfbfoRzYWx0' """ password = getBytes(password) salt = getBytes(salt) - return "{SSHA}%s" % getUnicode(base64.b64encode(sha1(password + salt).digest() + salt)) + return "{SSHA}%s" % getText(base64.b64encode(sha1(password + salt).digest() + salt)) def ssha256_passwd(password, salt, **kwargs): """ - >>> ssha256_passwd(password='testpass', salt='salt') == '{SSHA256}hhubsLrO/Aje9F/kJrgv5ZLE40UmTrVWvI7Dt6InP99zYWx0' - True + >>> ssha256_passwd(password='testpass', salt='salt') + '{SSHA256}hhubsLrO/Aje9F/kJrgv5ZLE40UmTrVWvI7Dt6InP99zYWx0' """ password = getBytes(password) salt = getBytes(salt) - return "{SSHA256}%s" % getUnicode(base64.b64encode(sha256(password + salt).digest() + salt)) + return "{SSHA256}%s" % getText(base64.b64encode(sha256(password + salt).digest() + salt)) def ssha512_passwd(password, salt, **kwargs): """ - >>> ssha512_passwd(password='testpass', salt='salt') == '{SSHA512}mCUSLfPMhXCQOJl9WHW/QMn9v9sjq7Ht/Wk7iVau8vLOfh+PeynkGMikqIE8sStFd0khdfcCD8xZmC6UyjTxsHNhbHQ=' - True + >>> ssha512_passwd(password='testpass', salt='salt') + '{SSHA512}mCUSLfPMhXCQOJl9WHW/QMn9v9sjq7Ht/Wk7iVau8vLOfh+PeynkGMikqIE8sStFd0khdfcCD8xZmC6UyjTxsHNhbHQ=' """ password = getBytes(password) salt = getBytes(salt) - return "{SSHA512}%s" % getUnicode(base64.b64encode(sha512(password + salt).digest() + salt)) + return "{SSHA512}%s" % getText(base64.b64encode(sha512(password + salt).digest() + salt)) def sha224_generic_passwd(password, uppercase=False): """ @@ -359,8 +357,8 @@ def crypt_generic_passwd(password, salt, **kwargs): http://php.net/manual/en/function.crypt.php http://carey.geek.nz/code/python-fcrypt/ - >>> crypt_generic_passwd(password='rasmuslerdorf', salt='rl', uppercase=False) == 'rl.3StKT.4T8M' - True + >>> crypt_generic_passwd(password='rasmuslerdorf', salt='rl', uppercase=False) + 'rl.3StKT.4T8M' """ return crypt(password, salt) @@ -371,7 +369,7 @@ def unix_md5_passwd(password, salt, magic="$1$", **kwargs): http://www.sabren.net/code/python/crypt/md5crypt.py >>> unix_md5_passwd(password='testpass', salt='aD9ZLmkp') - u'$1$aD9ZLmkp$DRM5a7rRZGyuuOPOjTEk61' + '$1$aD9ZLmkp$DRM5a7rRZGyuuOPOjTEk61' """ def _encode64(value, count): @@ -429,14 +427,14 @@ def unix_md5_passwd(password, salt, magic="$1$", **kwargs): final = md5(ctx1).digest() - hash_ = _encode64((int(ord(final[0])) << 16) | (int(ord(final[6])) << 8) | (int(ord(final[12]))), 4) - hash_ = hash_ + _encode64((int(ord(final[1])) << 16) | (int(ord(final[7])) << 8) | (int(ord(final[13]))), 4) - hash_ = hash_ + _encode64((int(ord(final[2])) << 16) | (int(ord(final[8])) << 8) | (int(ord(final[14]))), 4) - hash_ = hash_ + _encode64((int(ord(final[3])) << 16) | (int(ord(final[9])) << 8) | (int(ord(final[15]))), 4) - hash_ = hash_ + _encode64((int(ord(final[4])) << 16) | (int(ord(final[10])) << 8) | (int(ord(final[5]))), 4) - hash_ = hash_ + _encode64((int(ord(final[11]))), 2) + hash_ = _encode64((int(ord(final[0:1])) << 16) | (int(ord(final[6:7])) << 8) | (int(ord(final[12:13]))), 4) + hash_ = hash_ + _encode64((int(ord(final[1:2])) << 16) | (int(ord(final[7:8])) << 8) | (int(ord(final[13:14]))), 4) + hash_ = hash_ + _encode64((int(ord(final[2:3])) << 16) | (int(ord(final[8:9])) << 8) | (int(ord(final[14:15]))), 4) + hash_ = hash_ + _encode64((int(ord(final[3:4])) << 16) | (int(ord(final[9:10])) << 8) | (int(ord(final[15:16]))), 4) + hash_ = hash_ + _encode64((int(ord(final[4:5])) << 16) | (int(ord(final[10:11])) << 8) | (int(ord(final[5:6]))), 4) + hash_ = hash_ + _encode64((int(ord(final[11:12]))), 2) - return "%s%s$%s" % (magic, salt.decode(UNICODE_ENCODING), hash_.decode(UNICODE_ENCODING)) + return getText(b"%s%s$%s" % (magic, salt, getBytes(hash_))) def joomla_passwd(password, salt, **kwargs): """ diff --git a/lib/utils/hashdb.py b/lib/utils/hashdb.py index 2f415383a..d65360bbc 100644 --- a/lib/utils/hashdb.py +++ b/lib/utils/hashdb.py @@ -11,13 +11,13 @@ import sqlite3 import threading import time -from lib.core.common import getBytes from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import serializeObject from lib.core.common import singleTimeWarnMessage from lib.core.common import unserializeObject from lib.core.compat import xrange +from lib.core.convert import getBytes from lib.core.data import logger from lib.core.exception import SqlmapConnectionException from lib.core.settings import HASHDB_END_TRANSACTION_RETRIES diff --git a/plugins/dbms/access/syntax.py b/plugins/dbms/access/syntax.py index 18021a359..f792f2a57 100644 --- a/plugins/dbms/access/syntax.py +++ b/plugins/dbms/access/syntax.py @@ -5,7 +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.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/db2/syntax.py b/plugins/dbms/db2/syntax.py index 8b2ca8910..cdc83fa7d 100644 --- a/plugins/dbms/db2/syntax.py +++ b/plugins/dbms/db2/syntax.py @@ -5,7 +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.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/firebird/syntax.py b/plugins/dbms/firebird/syntax.py index b95da3a67..95029ed32 100644 --- a/plugins/dbms/firebird/syntax.py +++ b/plugins/dbms/firebird/syntax.py @@ -5,8 +5,8 @@ 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 lib.core.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/h2/syntax.py b/plugins/dbms/h2/syntax.py index f43103946..b6ce1cd27 100644 --- a/plugins/dbms/h2/syntax.py +++ b/plugins/dbms/h2/syntax.py @@ -5,7 +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.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/hsqldb/syntax.py b/plugins/dbms/hsqldb/syntax.py index f43103946..b6ce1cd27 100644 --- a/plugins/dbms/hsqldb/syntax.py +++ b/plugins/dbms/hsqldb/syntax.py @@ -5,7 +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.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/informix/syntax.py b/plugins/dbms/informix/syntax.py index e74e95907..692c7687d 100644 --- a/plugins/dbms/informix/syntax.py +++ b/plugins/dbms/informix/syntax.py @@ -7,9 +7,9 @@ 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 lib.core.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/mssqlserver/connector.py b/plugins/dbms/mssqlserver/connector.py index 17b33eec8..301a826a9 100644 --- a/plugins/dbms/mssqlserver/connector.py +++ b/plugins/dbms/mssqlserver/connector.py @@ -14,7 +14,7 @@ except: import logging from lib.core.common import getSafeExString -from lib.core.convert import utf8encode +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import logger from lib.core.exception import SqlmapConnectionException @@ -58,7 +58,7 @@ class Connector(GenericConnector): retVal = False try: - self.cursor.execute(utf8encode(query)) + self.cursor.execute(getBytes(query)) retVal = True except (pymssql.OperationalError, pymssql.ProgrammingError) as ex: logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) '%s'" % getSafeExString(ex).replace("\n", " ")) diff --git a/plugins/dbms/mssqlserver/filesystem.py b/plugins/dbms/mssqlserver/filesystem.py index 7488fe3d1..ebb8897cd 100644 --- a/plugins/dbms/mssqlserver/filesystem.py +++ b/plugins/dbms/mssqlserver/filesystem.py @@ -15,8 +15,8 @@ from lib.core.common import posixToNtSlashes from lib.core.common import randomStr from lib.core.common import readInput from lib.core.compat import xrange -from lib.core.convert import base64encode -from lib.core.convert import hexencode +from lib.core.convert import encodeBase64 +from lib.core.convert import encodeHex from lib.core.data import conf from lib.core.data import logger from lib.core.enums import CHARSET_TYPE @@ -44,7 +44,7 @@ class Filesystem(GenericFilesystem): scrString = "" for lineChar in fileContent[fileLine:fileLine + lineLen]: - strLineChar = hexencode(lineChar, conf.encoding) + strLineChar = encodeHex(lineChar, binary=False) if not scrString: scrString = "e %x %s" % (lineAddr, strLineChar) @@ -170,7 +170,7 @@ class Filesystem(GenericFilesystem): infoMsg += "to file '%s'" % dFile logger.info(infoMsg) - encodedFileContent = base64encode(wFileContent) + encodedFileContent = encodeBase64(wFileContent, binary=False) encodedBase64File = "tmpf%s.txt" % randomStr(lowercase=True) encodedBase64FilePath = "%s\\%s" % (tmpPath, encodedBase64File) @@ -330,7 +330,7 @@ class Filesystem(GenericFilesystem): End Function""" % (randFilePath, dFile) vbs = vbs.replace(" ", "") - encodedFileContent = base64encode(wFileContent) + encodedFileContent = encodeBase64(wFileContent, binary=False) logger.debug("uploading the file base64-encoded content to %s, please wait.." % randFilePath) @@ -359,7 +359,7 @@ class Filesystem(GenericFilesystem): randFile = "tmpf%s.txt" % randomStr(lowercase=True) randFilePath = "%s\\%s" % (tmpPath, randFile) - encodedFileContent = base64encode(wFileContent) + encodedFileContent = encodeBase64(wFileContent, binary=False) splittedEncodedFileContent = '\n'.join([encodedFileContent[i:i + chunkMaxSize] for i in xrange(0, len(encodedFileContent), chunkMaxSize)]) diff --git a/plugins/dbms/mssqlserver/syntax.py b/plugins/dbms/mssqlserver/syntax.py index f7f94b8de..5f6eb0c79 100644 --- a/plugins/dbms/mssqlserver/syntax.py +++ b/plugins/dbms/mssqlserver/syntax.py @@ -5,8 +5,8 @@ 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 +from lib.core.convert import getOrds class Syntax(GenericSyntax): @staticmethod diff --git a/plugins/dbms/mssqlserver/takeover.py b/plugins/dbms/mssqlserver/takeover.py index deee5c657..3903a44fa 100644 --- a/plugins/dbms/mssqlserver/takeover.py +++ b/plugins/dbms/mssqlserver/takeover.py @@ -8,8 +8,8 @@ See the file 'LICENSE' for copying permission import binascii from lib.core.common import Backend -from lib.core.common import getBytes from lib.core.compat import xrange +from lib.core.convert import getBytes from lib.core.data import logger from lib.core.exception import SqlmapUnsupportedFeatureException from lib.request import inject diff --git a/plugins/dbms/mysql/syntax.py b/plugins/dbms/mysql/syntax.py index 7885bed41..f7ea71eeb 100644 --- a/plugins/dbms/mysql/syntax.py +++ b/plugins/dbms/mysql/syntax.py @@ -7,9 +7,9 @@ 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 lib.core.convert import getBytes +from lib.core.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/oracle/connector.py b/plugins/dbms/oracle/connector.py index db61707b5..f9110311c 100644 --- a/plugins/dbms/oracle/connector.py +++ b/plugins/dbms/oracle/connector.py @@ -15,7 +15,7 @@ import os import re from lib.core.common import getSafeExString -from lib.core.convert import utf8encode +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import logger from lib.core.exception import SqlmapConnectionException @@ -34,9 +34,9 @@ class Connector(GenericConnector): def connect(self): self.initConnection() self.__dsn = cx_Oracle.makedsn(self.hostname, self.port, self.db) - self.__dsn = utf8encode(self.__dsn) - self.user = utf8encode(self.user) - self.password = utf8encode(self.password) + self.__dsn = getBytes(self.__dsn) + self.user = getBytes(self.user) + self.password = getBytes(self.password) try: self.connector = cx_Oracle.connect(dsn=self.__dsn, user=self.user, password=self.password, mode=cx_Oracle.SYSDBA) @@ -67,7 +67,7 @@ class Connector(GenericConnector): retVal = False try: - self.cursor.execute(utf8encode(query)) + self.cursor.execute(getBytes(query)) retVal = True except cx_Oracle.DatabaseError as ex: logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) '%s'" % getSafeExString(ex)) diff --git a/plugins/dbms/oracle/syntax.py b/plugins/dbms/oracle/syntax.py index 57a1e39aa..5dff48410 100644 --- a/plugins/dbms/oracle/syntax.py +++ b/plugins/dbms/oracle/syntax.py @@ -5,7 +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.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/postgresql/syntax.py b/plugins/dbms/postgresql/syntax.py index 4502ddf71..4509abc8e 100644 --- a/plugins/dbms/postgresql/syntax.py +++ b/plugins/dbms/postgresql/syntax.py @@ -5,7 +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.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/sqlite/connector.py b/plugins/dbms/sqlite/connector.py index a1832146e..c244a86ad 100644 --- a/plugins/dbms/sqlite/connector.py +++ b/plugins/dbms/sqlite/connector.py @@ -13,7 +13,7 @@ except: import logging from lib.core.common import getSafeExString -from lib.core.convert import utf8encode +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import logger from lib.core.exception import SqlmapConnectionException @@ -75,7 +75,7 @@ class Connector(GenericConnector): def execute(self, query): try: - self.cursor.execute(utf8encode(query)) + self.cursor.execute(getBytes(query)) except self.__sqlite.OperationalError as ex: logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) '%s'" % getSafeExString(ex)) except self.__sqlite.DatabaseError as ex: diff --git a/plugins/dbms/sqlite/syntax.py b/plugins/dbms/sqlite/syntax.py index 7a35b0467..21119a7a5 100644 --- a/plugins/dbms/sqlite/syntax.py +++ b/plugins/dbms/sqlite/syntax.py @@ -7,9 +7,9 @@ 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 lib.core.convert import getBytes from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/dbms/sybase/connector.py b/plugins/dbms/sybase/connector.py index b264d4306..e11a7649b 100644 --- a/plugins/dbms/sybase/connector.py +++ b/plugins/dbms/sybase/connector.py @@ -14,7 +14,7 @@ except: import logging from lib.core.common import getSafeExString -from lib.core.convert import utf8encode +from lib.core.convert import getBytes from lib.core.data import conf from lib.core.data import logger from lib.core.exception import SqlmapConnectionException @@ -58,7 +58,7 @@ class Connector(GenericConnector): retVal = False try: - self.cursor.execute(utf8encode(query)) + self.cursor.execute(getBytes(query)) retVal = True except (pymssql.OperationalError, pymssql.ProgrammingError) as ex: logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) '%s'" % getSafeExString(ex).replace("\n", " ")) diff --git a/plugins/dbms/sybase/syntax.py b/plugins/dbms/sybase/syntax.py index dc5f7e8d1..aaf515aac 100644 --- a/plugins/dbms/sybase/syntax.py +++ b/plugins/dbms/sybase/syntax.py @@ -5,7 +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.convert import getOrds from plugins.generic.syntax import Syntax as GenericSyntax class Syntax(GenericSyntax): diff --git a/plugins/generic/filesystem.py b/plugins/generic/filesystem.py index abdb53e05..f8044c611 100644 --- a/plugins/generic/filesystem.py +++ b/plugins/generic/filesystem.py @@ -13,7 +13,7 @@ from lib.core.common import dataToOutFile from lib.core.common import Backend from lib.core.common import checkFile from lib.core.common import decloakToTemp -from lib.core.common import decodeHexValue +from lib.core.common import decodeDbmsHexValue from lib.core.common import getUnicode from lib.core.common import isNumPosStrValue from lib.core.common import isListLike @@ -251,7 +251,7 @@ class Filesystem: fileContent = newFileContent if fileContent is not None: - fileContent = decodeHexValue(fileContent, True) + fileContent = decodeDbmsHexValue(fileContent, True) if fileContent: localFilePath = dataToOutFile(remoteFile, fileContent) diff --git a/plugins/generic/users.py b/plugins/generic/users.py index 96df4505b..87bb71d23 100644 --- a/plugins/generic/users.py +++ b/plugins/generic/users.py @@ -22,7 +22,7 @@ from lib.core.common import parsePasswordHash from lib.core.common import readInput from lib.core.common import unArrayizeValue from lib.core.compat import xrange -from lib.core.convert import hexencode +from lib.core.convert import encodeHex from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger @@ -239,7 +239,7 @@ class Users: if retVal: for user, password in filterPairValues(_zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])): - password = "0x%s" % hexencode(password, conf.encoding).upper() + password = "0x%s" % encodeHex(password, binary=False).upper() if user not in kb.data.cachedUsersPasswords: kb.data.cachedUsersPasswords[user] = [password] diff --git a/sqlmap.py b/sqlmap.py index 44cfa1b0c..2ec0c53f9 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -413,8 +413,7 @@ if __name__ == "__main__": except KeyboardInterrupt: pass except: - if int(os.environ.get("SQLMAP_DREI", 0)): - traceback.print_exc() + pass finally: # Reference: http://stackoverflow.com/questions/1635080/terminate-a-multi-thread-python-program if threading.activeCount() > 1: diff --git a/tamper/base64encode.py b/tamper/base64encode.py index 7c4617fa1..6a6cccc31 100644 --- a/tamper/base64encode.py +++ b/tamper/base64encode.py @@ -5,10 +5,8 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ -import base64 - +from lib.core.convert import encodeBase64 from lib.core.enums import PRIORITY -from lib.core.settings import UNICODE_ENCODING __priority__ = PRIORITY.LOW @@ -23,4 +21,4 @@ def tamper(payload, **kwargs): 'MScgQU5EIFNMRUVQKDUpIw==' """ - return base64.b64encode(payload.encode(UNICODE_ENCODING)) if payload else payload + return encodeBase64(payload, binary=False) if payload else payload diff --git a/tamper/hex2char.py b/tamper/hex2char.py index 3f86aa86f..9b843b861 100644 --- a/tamper/hex2char.py +++ b/tamper/hex2char.py @@ -7,8 +7,8 @@ See the file 'LICENSE' for copying permission import re -from lib.core.common import decodeHex -from lib.core.common import getOrds +from lib.core.convert import decodeHex +from lib.core.convert import getOrds from lib.core.enums import PRIORITY __priority__ = PRIORITY.NORMAL diff --git a/tamper/luanginx.py b/tamper/luanginx.py index f3c97b866..91d5c4fc3 100644 --- a/tamper/luanginx.py +++ b/tamper/luanginx.py @@ -26,7 +26,7 @@ def tamper(payload, **kwargs): * Lua-Nginx WAFs do not support processing of more than 100 parameters >>> random.seed(0); hints={}; payload = tamper("1 AND 2>1", hints=hints); "%s&%s" % (hints[HINT.PREPEND], payload) - '0U=&Aq=&Fz=&Ws=&DK=&4F=&rU=&Mp=&48=&Y3=&tT=&3Q=&Dg=&AL=&47=&D1=&qX=&Ia=&Sy=&ZP=&aE=&1p=&u1=&lJ=&o7=&XB=&et=&F5=&gI=&RH=&YH=&7L=&KB=&Kx=&Js=&lL=&OD=&fU=&25=&03=&5H=&yR=&rY=&03=&K6=&JB=&O9=&4X=&fL=&EN=&0p=&Th=&nX=&uY=&gj=&Rc=&J4=&HQ=&bN=&LJ=&yw=&8c=&b7=&lh=&nX=&6b=&Ag=&qn=&Ov=&lF=&cg=&9m=&wT=&Z4=&kP=&7d=&P0=&vp=&LB=&kD=&zJ=&Ft=&wZ=&pI=&aT=&uc=&ro=&7v=&rw=&6N=&MS=&yz=&Oa=&lu=&oN=&x2=&Jz=&yR=&zP=&cB=&qj=&GE=&IU=&2E=&tC=&Y2=&Yl=&9N=&fS=&9y=&Qt=&nS=&aZ=&Gg=&hO=&2r=&8g=&0y=&fr=&CX=&1i=&GO=&v2=&rb=&cQ=&I6=&64=&cU=&RO=&S3=&Nx=&Hm=&Ka=&ju=&WS=&uM=&ck=&8r=&yI=&sD=&oc=&lG=&ey=&uz=&g4=&D0=&8v=&DR=&As=&T3=&5M=&x8=&Ne=&fU=&da=&yG=&BE=&KQ=&Aw=&9q=&WA=&wd=&1R=&3B=&Ph=&ym=&c6=&nj=&mx=&Hj=&98=&jz=&Q2=&E4=&tE=&EP=&mL=&nv=&73=&Yc=&jp=&W0=&KS=&Ye=&f1=&cn=&ca=&0u=&jO=&8F=&3F=&JQ=&XU=&9U=&4m=&HL=&ZD=&Xy=&K0=&XO=&al=&Fp=&e1=&6s=&zY=&dN=&hr=&Zd=&cz=&E1=&SP=&j9=&zL=&xc=&Dj=&cM=&Ng=&Iv=&xW=&E2=&LC=&Nu=&hQ=&MW=&h4=&X4=&2Q=&YG=&Wl=&WB=&UC=&We=&c5=&E3=&6P=&Jn=&fY=&3W=&RA=&sh=&AJ=&56=&zg=&VT=&bB=&Qb=&47=&Se=&ew=&bv=&a8=&Ye=&3m=&mP=&6h=&aw=&bL=&1l=&gv=&7i=&7w=&Ds=&67=&Nl=&9g=&Kj=&36=&Xt=&pU=&sA=&ci=&be=&eA=&IT=&iA=&Nf=&Bw=&6d=&zT=&tm=&sD=&6X=&rI=&QX=&By=&VA=&pC=&6i=&CN=&Dm=&aR=&Ma=&sV=&MH=&jR=&DQ=&Vo=&Vr=&9h=&2c=&pG=&Ky=&gp=&rU=&4K=&cX=&sv=&Gp=&5k=&zr=&GJ=&MG=&zN=&zW=&Ws=&xM=&jR=&xK=&iP=&vD=&zD=&Rt=&Od=&sU=&dM=&bD=&3a=&Ge=&1Q=&UP=&ac=&M9=&2R=&To=&Ur=&gC=&uk=&A3=&AB=&RG=&i4=&BW=&yY=&yn=&m6=&Kd=&yo=&fl=&dN=&kL=&LR=&Fr=&2v=&CN=&F7=&75=&5K=&ER=&nq=&ck=&aO=&iW=&Q8=&y5=&Cv=&g2=&Xu=&Cu=&bc=&wm=&Gl=&mP=&Tt=&1p=&vS=&c5=&eC=&Sc=&Y8=&Ch=&fg=&Vz=&4B=&eA=&UZ=&cl=&Eh=&25=&tA=&Ir=&Hm=&sB=&LH=&qo=&hW=&gT=&pr=&TO=&TF=&1h=&Oh=&Tw=&PR=&On=&Zo=&GP=&oM=&rk=&YI=&uK=&bi=&y8=&Fe=&VW=&WJ=&Rn=&TY=&Vv=&KM=&3g=&ZG=&wC=&an=&OE=&7D=&t0=&qL=&RY=&Wx=&dc=&T7=&vB=&SO=&qP=&sw=&HT=&jb=&Mb=&cn=&Oe=&d8=&A3=&nA=&wk=&u9=&Ux=&zq=>=&QC=&c5=&zy=&ai=&1F=&Tj=&u0=&Yp=&bY=&kW=&Qk=&e5=&LM=&Cj=&Lp=&XT=&b5=&cf=&sj=&ow=&Tz=&qE=&yt=&3I=&8V=&Jq=&QC=&Sz=&Eb=&Tc=&QK=&Wr=&Qm=&Gv=&8m=&Ju=&85=&KS=&Qv=&43=&uU=&aY=&J7=&wM=&uW=&L9=&ai=&ch=&56=&D6=&YW=&Ul=&1 AND 2>1' + '34=&Xe=&90=&Ni=&rW=&lc=&te=&T4=&zO=&NY=&B4=&hM=&X2=&pU=&D8=&hm=&p0=&7y=&18=&RK=&Xi=&5M=&vM=&hO=&bg=&5c=&b8=&dE=&7I=&5I=&90=&R2=&BK=&bY=&p4=&lu=&po=&Vq=&bY=&3c=&ps=&Xu=&lK=&3Q=&7s=&pq=&1E=&rM=&FG=&vG=&Xy=&tQ=&lm=&rO=&pO=&rO=&1M=&vy=&La=&xW=&f8=&du=&94=&vE=&9q=&bE=&lQ=&JS=&NQ=&fE=&RO=&FI=&zm=&5A=&lE=&DK=&x8=&RQ=&Xw=&LY=&5S=&zi=&Js=&la=&3I=&r8=&re=&Xe=&5A=&3w=&vs=&zQ=&1Q=&HW=&Bw=&Xk=&LU=&Lk=&1E=&Nw=&pm=&ns=&zO=&xq=&7k=&v4=&F6=&Pi=&vo=&zY=&vk=&3w=&tU=&nW=&TG=&NM=&9U=&p4=&9A=&T8=&Xu=&xa=&Jk=&nq=&La=&lo=&zW=&xS=&v0=&Z4=&vi=&Pu=&jK=&DE=&72=&fU=&DW=&1g=&RU=&Hi=&li=&R8=&dC=&nI=&9A=&tq=&1w=&7u=&rg=&pa=&7c=&zk=&rO=&xy=&ZA=&1K=&ha=&tE=&RC=&3m=&r2=&Vc=&B6=&9A=&Pk=&Pi=&zy=&lI=&pu=&re=&vS=&zk=&RE=&xS=&Fs=&x8=&Fe=&rk=&Fi=&Tm=&fA=&Zu=&DS=&No=&lm=&lu=&li=&jC=&Do=&Tw=&xo=&zQ=&nO=&ng=&nC=&PS=&fU=&Lc=&Za=&Ta=&1y=&lw=&pA=&ZW=&nw=&pM=&pa=&Rk=&lE=&5c=&T4=&Vs=&7W=&Jm=&xG=&nC=&Js=&xM=&Rg=&zC=&Dq=&VA=&Vy=&9o=&7o=&Fk=&Ta=&Fq=&9y=&vq=&rW=&X4=&1W=&hI=&nA=&hs=&He=&No=&vy=&9C=&ZU=&t6=&1U=&1Q=&Do=&bk=&7G=&nA=&VE=&F0=&BO=&l2=&BO=&7o=&zq=&B4=&fA=&lI=&Xy=&Ji=&lk=&7M=&JG=&Be=&ts=&36=&tW=&fG=&T4=&vM=&hG=&tO=&VO=&9m=&Rm=&LA=&5K=&FY=&HW=&7Q=&t0=&3I=&Du=&Xc=&BS=&N0=&x4=&fq=&jI=&Ze=&TQ=&5i=&T2=&FQ=&VI=&Te=&Hq=&fw=&LI=&Xq=&LC=&B0=&h6=&TY=&HG=&Hw=&dK=&ru=&3k=&JQ=&5g=&9s=&HQ=&vY=&1S=&ta=&bq=&1u=&9i=&DM=&DA=&TG=&vQ=&Nu=&RK=&da=&56=&nm=&vE=&Fg=&jY=&t0=&DG=&9o=&PE=&da=&D4=&VE=&po=&nm=&lW=&X0=&BY=&NK=&pY=&5Q=&jw=&r0=&FM=&lU=&da=&ls=&Lg=&D8=&B8=&FW=&3M=&zy=&ho=&Dc=&HW=&7E=&bM=&Re=&jk=&Xe=&JC=&vs=&Ny=&D4=&fA=&DM=&1o=&9w=&3C=&Rw=&Vc=&Ro=&PK=&rw=&Re=&54=&xK=&VK=&1O=&1U=&vg=&Ls=&xq=&NA=&zU=&di=&BS=&pK=&bW=&Vq=&BC=&l6=&34=&PE=&JG=&TA=&NU=&hi=&T0=&Rs=&fw=&FQ=&NQ=&Dq=&Dm=&1w=&PC=&j2=&r6=&re=&t2=&Ry=&h2=&9m=&nw=&X4=&vI=&rY=&1K=&7m=&7g=&J8=&Pm=&RO=&7A=&fO=&1w=&1g=&7U=&7Y=&hQ=&FC=&vu=&Lw=&5I=&t0=&Na=&vk=&Te=&5S=&ZM=&Xs=&Vg=&tE=&J2=&Ts=&Dm=&Ry=&FC=&7i=&h8=&3y=&zk=&5G=&NC=&Pq=&ds=&zK=&d8=&zU=&1a=&d8=&Js=&nk=&TQ=&tC=&n8=&Hc=&Ru=&H0=&Bo=&XE=&Jm=&xK=&r2=&Fu=&FO=&NO=&7g=&PC=&Bq=&3O=&FQ=&1o=&5G=&zS=&Ps=&j0=&b0=&RM=&DQ=&RQ=&zY=&nk=&1 AND 2>1' """ hints = kwargs.get("hints", {}) diff --git a/tamper/modsecurityversioned.py b/tamper/modsecurityversioned.py index 9904708b8..6bd16a8f9 100644 --- a/tamper/modsecurityversioned.py +++ b/tamper/modsecurityversioned.py @@ -33,7 +33,7 @@ def tamper(payload, **kwargs): >>> import random >>> random.seed(0) >>> tamper('1 AND 2>1--') - '1 /*!30874AND 2>1*/--' + '1 /*!30963AND 2>1*/--' """ retVal = payload diff --git a/tamper/multiplespaces.py b/tamper/multiplespaces.py index 2de4ab929..0b3473f8e 100644 --- a/tamper/multiplespaces.py +++ b/tamper/multiplespaces.py @@ -10,6 +10,7 @@ import re from lib.core.data import kb from lib.core.enums import PRIORITY +from lib.core.datatype import OrderedSet __priority__ = PRIORITY.NORMAL @@ -28,13 +29,13 @@ def tamper(payload, **kwargs): >>> random.seed(0) >>> tamper('1 UNION SELECT foobar') - '1 UNION SELECT foobar' + '1 UNION SELECT foobar' """ retVal = payload if payload: - words = set() + words = OrderedSet() for match in re.finditer(r"\b[A-Za-z_]+\b", payload): word = match.group() @@ -43,7 +44,7 @@ def tamper(payload, **kwargs): words.add(word) for word in words: - retVal = re.sub(r"(?<=\W)%s(?=[^A-Za-z_(]|\Z)" % word, "%s%s%s" % (' ' * random.randrange(1, 4), word, ' ' * random.randrange(1, 4)), retVal) - retVal = re.sub(r"(?<=\W)%s(?=[(])" % word, "%s%s" % (' ' * random.randrange(1, 4), word), retVal) + retVal = re.sub(r"(?<=\W)%s(?=[^A-Za-z_(]|\Z)" % word, "%s%s%s" % (' ' * random.randint(1, 4), word, ' ' * random.randint(1, 4)), retVal) + retVal = re.sub(r"(?<=\W)%s(?=[(])" % word, "%s%s" % (' ' * random.randint(1, 4), word), retVal) return retVal diff --git a/tamper/randomcase.py b/tamper/randomcase.py index 0819521ad..ed23c7e73 100644 --- a/tamper/randomcase.py +++ b/tamper/randomcase.py @@ -36,7 +36,7 @@ def tamper(payload, **kwargs): >>> import random >>> random.seed(0) >>> tamper('INSERT') - 'INseRt' + 'InSeRt' """ retVal = payload diff --git a/tamper/randomcomments.py b/tamper/randomcomments.py index 2a504d3a0..9eacb2c94 100644 --- a/tamper/randomcomments.py +++ b/tamper/randomcomments.py @@ -21,7 +21,7 @@ def tamper(payload, **kwargs): >>> import random >>> random.seed(0) >>> tamper('INSERT') - 'I/**/N/**/SERT' + 'I/**/NS/**/ERT' """ retVal = payload diff --git a/tamper/space2dash.py b/tamper/space2dash.py index e5ab69af2..55fcc7b2a 100644 --- a/tamper/space2dash.py +++ b/tamper/space2dash.py @@ -28,7 +28,7 @@ def tamper(payload, **kwargs): >>> random.seed(0) >>> tamper('1 AND 9227=9227') - '1--nVNaVoPYeva%0AAND--ngNvzqu%0A9227=9227' + '1--upgPydUzKpMX%0AAND--RcDKhIr%0A9227=9227' """ retVal = "" diff --git a/tamper/space2hash.py b/tamper/space2hash.py index 79d8d01fd..5c8ca56d0 100644 --- a/tamper/space2hash.py +++ b/tamper/space2hash.py @@ -36,7 +36,7 @@ def tamper(payload, **kwargs): >>> random.seed(0) >>> tamper('1 AND 9227=9227') - '1%23nVNaVoPYeva%0AAND%23ngNvzqu%0A9227=9227' + '1%23upgPydUzKpMX%0AAND%23RcDKhIr%0A9227=9227' """ retVal = "" diff --git a/tamper/space2morehash.py b/tamper/space2morehash.py index 81168258c..42f917d59 100644 --- a/tamper/space2morehash.py +++ b/tamper/space2morehash.py @@ -39,7 +39,7 @@ def tamper(payload, **kwargs): >>> random.seed(0) >>> tamper('1 AND 9227=9227') - '1%23ngNvzqu%0AAND%23nVNaVoPYeva%0A%23lujYFWfv%0A9227=9227' + '1%23RcDKhIr%0AAND%23upgPydUzKpMX%0A%23lgbaxYjWJ%0A9227=9227' """ def process(match): diff --git a/tamper/space2mssqlblank.py b/tamper/space2mssqlblank.py index b78915186..e900ddd27 100644 --- a/tamper/space2mssqlblank.py +++ b/tamper/space2mssqlblank.py @@ -34,7 +34,7 @@ def tamper(payload, **kwargs): >>> random.seed(0) >>> tamper('SELECT id FROM users') - 'SELECT%0Eid%0DFROM%07users' + 'SELECT%0Did%0DFROM%04users' """ # ASCII table: diff --git a/tamper/space2mysqlblank.py b/tamper/space2mysqlblank.py index 1c7cc6676..5a92569f0 100644 --- a/tamper/space2mysqlblank.py +++ b/tamper/space2mysqlblank.py @@ -33,7 +33,7 @@ def tamper(payload, **kwargs): >>> random.seed(0) >>> tamper('SELECT id FROM users') - 'SELECT%A0id%0BFROM%0Cusers' + 'SELECT%A0id%0CFROM%0Dusers' """ # ASCII table: diff --git a/tamper/space2randomblank.py b/tamper/space2randomblank.py index e668292b1..009df0eb8 100644 --- a/tamper/space2randomblank.py +++ b/tamper/space2randomblank.py @@ -30,7 +30,7 @@ def tamper(payload, **kwargs): >>> random.seed(0) >>> tamper('SELECT id FROM users') - 'SELECT%0Did%0DFROM%0Ausers' + 'SELECT%0Did%0CFROM%0Ausers' """ # ASCII table: diff --git a/thirdparty/multipart/multipartpost.py b/thirdparty/multipart/multipartpost.py index 993f4ff90..524f93602 100644 --- a/thirdparty/multipart/multipartpost.py +++ b/thirdparty/multipart/multipartpost.py @@ -26,8 +26,8 @@ import os import stat import sys -from lib.core.common import getBytes from lib.core.compat import choose_boundary +from lib.core.convert import getBytes from lib.core.exception import SqlmapDataException from thirdparty.six.moves import urllib as _urllib