From 1f05e85408db4206515c209d5e1d9d8bfe1e62ed Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Thu, 2 May 2019 23:51:54 +0200 Subject: [PATCH] Some more drei updates --- extra/safe2bin/safe2bin.py | 3 +- extra/shutils/drei.sh | 10 ++-- lib/core/bigarray.py | 6 +-- lib/core/common.py | 76 ++++++++++++++++++++++-------- lib/core/compat.py | 34 ++++++++++++- lib/core/convert.py | 2 +- lib/core/option.py | 10 ++-- lib/core/settings.py | 5 +- lib/core/testing.py | 1 + lib/core/threads.py | 4 +- lib/core/update.py | 4 +- lib/request/basic.py | 4 +- lib/techniques/union/use.py | 5 +- lib/utils/api.py | 3 +- lib/utils/hash.py | 9 ++-- lib/utils/pivotdumptable.py | 3 +- lib/utils/xrange.py | 2 + plugins/dbms/maxdb/enumeration.py | 3 +- plugins/dbms/sybase/enumeration.py | 3 +- plugins/generic/entries.py | 3 +- plugins/generic/users.py | 5 +- 21 files changed, 142 insertions(+), 53 deletions(-) diff --git a/extra/safe2bin/safe2bin.py b/extra/safe2bin/safe2bin.py index 478592225..3406f1b6c 100644 --- a/extra/safe2bin/safe2bin.py +++ b/extra/safe2bin/safe2bin.py @@ -22,6 +22,7 @@ if sys.version_info >= (3, 0): xrange = range text_type = str string_types = (str,) + unichr = chr else: text_type = unicode string_types = (basestring,) @@ -88,7 +89,7 @@ def safechardecode(value, binary=False): while True: match = re.search(HEX_ENCODED_CHAR_REGEX, retVal) if match: - retVal = retVal.replace(match.group("result"), (unichr if isinstance(value, text_type) else chr)(ord(binascii.unhexlify(match.group("result").lstrip("\\x"))))) + retVal = retVal.replace(match.group("result"), unichr(ord(binascii.unhexlify(match.group("result").lstrip("\\x"))))) else: break diff --git a/extra/shutils/drei.sh b/extra/shutils/drei.sh index 39c5c6e9e..78777a39d 100755 --- a/extra/shutils/drei.sh +++ b/extra/shutils/drei.sh @@ -5,7 +5,9 @@ # Stress test against Python3 -export SQLMAP_DREI=1 -for i in $(find . -iname "*.py" | grep -v __init__); do python3 -c 'import '`echo $i | cut -d '.' -f 2 | cut -d '/' -f 2- | sed 's/\//./g'`''; done -unset SQLMAP_DREI -source `dirname "$0"`"/junk.sh" \ No newline at end of file +# export SQLMAP_DREI=1 +# for i in $(find . -iname "*.py" | grep -v __init__); do python3 -c 'import '`echo $i | cut -d '.' -f 2 | cut -d '/' -f 2- | sed 's/\//./g'`''; done +# unset SQLMAP_DREI +# source `dirname "$0"`"/junk.sh" + +for i in $(find . -iname "*.py" | grep -v __init__); do pylint --py3k $i; done diff --git a/lib/core/bigarray.py b/lib/core/bigarray.py index afe4e76c5..90874bd55 100644 --- a/lib/core/bigarray.py +++ b/lib/core/bigarray.py @@ -90,7 +90,7 @@ class BigArray(list): self.chunks[-1] = pickle.loads(bz2.decompress(f.read())) except IOError as ex: errMsg = "exception occurred while retrieving data " - errMsg += "from a temporary file ('%s')" % ex.message + errMsg += "from a temporary file ('%s')" % ex raise SqlmapSystemException(errMsg) return self.chunks[-1].pop() @@ -112,7 +112,7 @@ class BigArray(list): return filename except (OSError, IOError) as ex: errMsg = "exception occurred while storing data " - errMsg += "to a temporary file ('%s'). Please " % ex.message + errMsg += "to a temporary file ('%s'). Please " % ex errMsg += "make sure that there is enough disk space left. If problem persists, " errMsg += "try to set environment variable 'TEMP' to a location " errMsg += "writeable by the current user" @@ -129,7 +129,7 @@ class BigArray(list): self.cache = Cache(index, pickle.loads(bz2.decompress(f.read())), False) except Exception as ex: errMsg = "exception occurred while retrieving data " - errMsg += "from a temporary file ('%s')" % ex.message + errMsg += "from a temporary file ('%s')" % ex raise SqlmapSystemException(errMsg) def __getstate__(self): diff --git a/lib/core/common.py b/lib/core/common.py index 0a1f620b7..fa69c9aad 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -5,6 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ +import base64 import binascii import codecs import collections @@ -47,6 +48,8 @@ from extra.beep.beep import beep from extra.cloak.cloak import decloak from extra.safe2bin.safe2bin import safecharencode from lib.core.bigarray import BigArray +from lib.core.compat import cmp +from lib.core.compat import round from lib.core.compat import xrange from lib.core.convert import base64pickle from lib.core.convert import base64unpickle @@ -179,7 +182,9 @@ from thirdparty.odict import OrderedDict from thirdparty.six.moves import configparser as _configparser from thirdparty.six.moves import http_client as _http_client from thirdparty.six.moves import input as _input +from thirdparty.six.moves import reload_module as _reload_module from thirdparty.six.moves import urllib as _urllib +from thirdparty.six.moves import zip as _zip from thirdparty.termcolor.termcolor import colored class UnicodeRawConfigParser(_configparser.RawConfigParser): @@ -610,7 +615,7 @@ def paramToDict(place, parameters=None): if parameter in (conf.base64Parameter or []): try: oldValue = value - value = value.decode("base64") + value = decodeBase64(value, binary=False) parameters = re.sub(r"\b%s\b" % re.escape(oldValue), value, parameters) except: errMsg = "parameter '%s' does not contain " % parameter @@ -2278,7 +2283,7 @@ def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, un try: with openFile(filename, 'r', errors="ignore") if unicoded else open(filename, 'r') as f: - for line in (f.readlines() if unicoded else f.xreadlines()): # xreadlines doesn't return unicode strings when codec.open() is used + for line in f: if commentPrefix: if line.find(commentPrefix) != -1: line = line[:line.find(commentPrefix)] @@ -2452,15 +2457,39 @@ 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): +def decodeHex(value, binary=True): """ - Returns byte representation of provided hexadecimal value + Returns a decoded representation of provided hexadecimal value >>> decodeHex("313233") == b"123" True + >>> decodeHex("313233", binary=False) == u"123" + True """ - return bytes.fromhex(getUnicode(value)) if hasattr(bytes, "fromhex") else value.decode("hex") + 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"): """ @@ -2475,7 +2504,7 @@ def getBytes(value, encoding=UNICODE_ENCODING, errors="strict"): if isinstance(value, six.text_type): if INVALID_UNICODE_PRIVATE_AREA: for char in xrange(0xF0000, 0xF00FF + 1): - value = value.replace(unichr(char), "%s%02x" % (SAFE_HEX_MARKER, char - 0xF0000)) + 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) @@ -2525,7 +2554,13 @@ def longestCommonPrefix(*sequences): return sequences[0] def commonFinderOnly(initial, sequence): - return longestCommonPrefix(*filter(lambda _: _.startswith(initial), sequence)) + """ + Returns parts of sequence which start with the given initial string + + >>> commonFinderOnly("abcd", ["abcdefg", "foobar", "abcde"]) + ['abcdefg', 'abcde'] + """ + return longestCommonPrefix([_ for _ in sequence if _.startswith(initial)]) def pushValue(value): """ @@ -2811,13 +2846,13 @@ def runningAsAdmin(): if PLATFORM in ("posix", "mac"): _ = os.geteuid() - isAdmin = isinstance(_, (int, float, long)) and _ == 0 + isAdmin = isinstance(_, (float, six.integer_types)) and _ == 0 elif IS_WIN: import ctypes _ = ctypes.windll.shell32.IsUserAnAdmin() - isAdmin = isinstance(_, (int, float, long)) and _ == 1 + isAdmin = isinstance(_, (float, six.integer_types)) and _ == 1 else: errMsg = "sqlmap is not able to check if you are running it " errMsg += "as an administrator account on this platform. " @@ -3318,6 +3353,8 @@ def unArrayizeValue(value): >>> unArrayizeValue(['1']) '1' + >>> unArrayizeValue(['1', '2']) + '1' """ if isListLike(value): @@ -3326,8 +3363,8 @@ def unArrayizeValue(value): elif len(value) == 1 and not isListLike(value[0]): value = value[0] else: - _ = filter(lambda _: _ is not None, (_ for _ in flattenValue(value))) - value = _[0] if len(_) > 0 else None + value = [_ for _ in flattenValue(value) if _ is not None] + value = value[0] if len(value) > 0 else None return value @@ -3459,7 +3496,7 @@ def decodeIntToUnicode(value): elif Backend.isDbms(DBMS.MSSQL): retVal = getUnicode(raw, "UTF-16-BE") elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE): - retVal = unichr(value) + retVal = six.unichr(value) else: retVal = getUnicode(raw, conf.encoding) else: @@ -3600,7 +3637,7 @@ def createGithubIssue(errMsg, excMsg): choice = None if choice: - ex = None + _excMsg = None errMsg = errMsg[errMsg.find("\n"):] req = _urllib.request.Request(url="https://api.github.com/search/issues?q=%s" % _urllib.parse.quote("repo:sqlmapproject/sqlmap Unhandled exception (#%s)" % key)) @@ -3621,12 +3658,13 @@ def createGithubIssue(errMsg, excMsg): pass data = {"title": "Unhandled exception (#%s)" % key, "body": "```%s\n```\n```\n%s```" % (errMsg, excMsg)} - req = _urllib.request.Request(url="https://api.github.com/repos/sqlmapproject/sqlmap/issues", data=json.dumps(data), headers={"Authorization": "token %s" % GITHUB_REPORT_OAUTH_TOKEN.decode("base64")}) + req = _urllib.request.Request(url="https://api.github.com/repos/sqlmapproject/sqlmap/issues", data=json.dumps(data), headers={"Authorization": "token %s" % decodeBase64(GITHUB_REPORT_OAUTH_TOKEN, binary=False)}) try: content = _urllib.request.urlopen(req).read() except Exception as ex: content = None + _excMsg = getSafeExString(ex) issueUrl = re.search(r"https://github.com/sqlmapproject/sqlmap/issues/\d+", content or "") if issueUrl: @@ -3640,8 +3678,8 @@ def createGithubIssue(errMsg, excMsg): pass else: warnMsg = "something went wrong while creating a Github issue" - if ex: - warnMsg += " ('%s')" % getSafeExString(ex) + if _excMsg: + warnMsg += " ('%s')" % _excMsg if "Unauthorized" in warnMsg: warnMsg += ". Please update to the latest revision" logger.warn(warnMsg) @@ -4403,7 +4441,7 @@ def checkSystemEncoding(): warnMsg = "temporary switching to charset 'cp1256'" logger.warn(warnMsg) - reload(sys) + _reload_module(sys) sys.setdefaultencoding("cp1256") def evaluateCode(code, variables=None): @@ -4741,7 +4779,7 @@ def splitFields(fields, delimiter=','): commas.extend(zeroDepthSearch(fields, ',')) commas = sorted(commas) - return [fields[x + 1:y] for (x, y) in zip(commas, commas[1:])] + return [fields[x + 1:y] for (x, y) in _zip(commas, commas[1:])] def pollProcess(process, suppress_errors=False): """ @@ -4807,7 +4845,7 @@ def parseRequestFile(reqFile, checkParams=True): for match in re.finditer(BURP_XML_HISTORY_REGEX, content, re.I | re.S): port, request = match.groups() try: - request = request.decode("base64") + request = decodeBase64(request, binary=False) except binascii.Error: continue _ = re.search(r"%s:.+" % re.escape(HTTP_HEADER.HOST), request) diff --git a/lib/core/compat.py b/lib/core/compat.py index 850d86bbc..5741ef985 100644 --- a/lib/core/compat.py +++ b/lib/core/compat.py @@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission """ import binascii +import math import os import random import uuid @@ -163,13 +164,44 @@ class WichmannHill(random.Random): self.__whseed(x, y, z) def patchHeaders(headers): - if not hasattr(headers, "headers"): + if headers is not None and not hasattr(headers, "headers"): headers.headers = ["%s: %s\r\n" % (header, headers[header]) for header in headers] +def cmp(a, b): + """ + >>> cmp("a", "b") + -1 + >>> cmp(2, 1) + 1 + """ + + if a < b: + return -1 + elif a > b: + return 1 + else: + return 0 + # Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py def choose_boundary(): return uuid.uuid4().hex +# Reference: http://python3porting.com/differences.html +def round(x, d=0): + """ + >>> round(2.0) + 2.0 + >>> round(2.5) + 3.0 + """ + + p = 10 ** d + if x > 0: + return float(math.floor((x * p) + 0.5))/p + else: + return float(math.ceil((x * p) - 0.5))/p + + if sys.version_info >= (3, 0): xrange = range else: diff --git a/lib/core/convert.py b/lib/core/convert.py index 07a4e660c..20a529727 100644 --- a/lib/core/convert.py +++ b/lib/core/convert.py @@ -171,7 +171,7 @@ def htmlunescape(value): retVal = retVal.replace(code, value) try: - retVal = re.sub(r"&#x([^ ;]+);", lambda match: unichr(int(match.group(1), 16)), retVal) + retVal = re.sub(r"&#x([^ ;]+);", lambda match: six.unichr(int(match.group(1), 16)), retVal) except ValueError: pass return retVal diff --git a/lib/core/option.py b/lib/core/option.py index c694fb4ec..c77a55967 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -59,6 +59,7 @@ from lib.core.common import setOptimize from lib.core.common import setPaths from lib.core.common import singleTimeWarnMessage from lib.core.common import urldecode +from lib.core.compat import round from lib.core.compat import xrange from lib.core.data import conf from lib.core.data import kb @@ -2096,11 +2097,14 @@ def _useWizardInterface(): choice = readInput(message, default='1') if choice == '2': - map(lambda _: conf.__setitem__(_, True), WIZARD.INTERMEDIATE) + options = WIZARD.INTERMEDIATE elif choice == '3': - map(lambda _: conf.__setitem__(_, True), WIZARD.ALL) + options = WIZARD.ALL else: - map(lambda _: conf.__setitem__(_, True), WIZARD.BASIC) + options = WIZARD.BASIC + + for _ in options: + conf.__setitem__(_, True) logger.debug("muting sqlmap.. it will do the magic for you") conf.verbose = 0 diff --git a/lib/core/settings.py b/lib/core/settings.py index 7813429bd..d8dc4a402 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -15,9 +15,10 @@ import sys from lib.core.enums import DBMS from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS +from thirdparty import six # sqlmap version (...) -VERSION = "1.3.5.5" +VERSION = "1.3.5.6" 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) @@ -839,7 +840,7 @@ for key, value in os.environ.items(): def _reversible(ex): if isinstance(ex, UnicodeDecodeError): if INVALID_UNICODE_PRIVATE_AREA: - return (u"".join(unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end) + return (u"".join(six.unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end) else: return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end) diff --git a/lib/core/testing.py b/lib/core/testing.py index 663f06ecf..3507c1e5a 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -26,6 +26,7 @@ from lib.core.common import getUnicode 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.data import conf from lib.core.data import logger from lib.core.data import paths diff --git a/lib/core/threads.py b/lib/core/threads.py index 5444d460f..8ed600dcb 100644 --- a/lib/core/threads.py +++ b/lib/core/threads.py @@ -155,7 +155,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio try: thread.start() except Exception as ex: - errMsg = "error occurred while starting new thread ('%s')" % ex.message + errMsg = "error occurred while starting new thread ('%s')" % ex logger.critical(errMsg) break @@ -191,7 +191,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio except (SqlmapConnectionException, SqlmapValueException) as ex: print() kb.threadException = True - logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message)) + logger.error("thread %s: '%s'" % (threading.currentThread().getName(), ex)) if conf.get("verbose") > 1: traceback.print_exc() diff --git a/lib/core/update.py b/lib/core/update.py index aef8ffec7..9b2677316 100644 --- a/lib/core/update.py +++ b/lib/core/update.py @@ -12,7 +12,6 @@ import shutil import subprocess import sys import time -import urllib import zipfile from lib.core.common import dataToStdout @@ -29,6 +28,7 @@ from lib.core.settings import IS_WIN from lib.core.settings import VERSION from lib.core.settings import ZIPBALL_PAGE from lib.core.settings import UNICODE_ENCODING +from thirdparty.six.moves import urllib as _urllib def update(): if not conf.updateAll: @@ -71,7 +71,7 @@ def update(): logger.error(errMsg) else: try: - archive = urllib.urlretrieve(ZIPBALL_PAGE)[0] + archive = _urllib.request.urlretrieve(ZIPBALL_PAGE)[0] with zipfile.ZipFile(archive) as f: for info in f.infolist(): diff --git a/lib/request/basic.py b/lib/request/basic.py index 1191bd53e..7a071a980 100644 --- a/lib/request/basic.py +++ b/lib/request/basic.py @@ -345,14 +345,14 @@ def decodePage(page, contentEncoding, contentType): def _(match): retVal = match.group(0) try: - retVal = unichr(int(match.group(1))) + retVal = six.unichr(int(match.group(1))) except (ValueError, OverflowError): pass return retVal page = re.sub(r"&#(\d+);", _, page) # e.g. ζ - page = re.sub(r"&([^;]+);", lambda _: unichr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 0) > 255 else _.group(0), page) + page = re.sub(r"&([^;]+);", lambda _: six.unichr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 0) > 255 else _.group(0), page) return page diff --git a/lib/techniques/union/use.py b/lib/techniques/union/use.py index 82fcd462d..a0e9e77bc 100644 --- a/lib/techniques/union/use.py +++ b/lib/techniques/union/use.py @@ -18,6 +18,7 @@ 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 @@ -121,14 +122,14 @@ def _oneShotUnionUse(expression, unpack=True, limited=False): break try: - value.decode("base64") + decodeBase64(value) except binascii.Error: base64 = False break if base64: for child in root: - child.attrib[column] = child.attrib.get(column, "").decode("base64") or NULL + child.attrib[column] = decodeBase64(child.attrib.get(column, ""), binary=False) or NULL for child in root: row = [] diff --git a/lib/utils/api.py b/lib/utils/api.py index 712f9e1f2..f6915613b 100644 --- a/lib/utils/api.py +++ b/lib/utils/api.py @@ -20,6 +20,7 @@ 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 @@ -294,7 +295,7 @@ def check_authentication(): request.environ["PATH_INFO"] = "/error/401" try: - creds = match.group(1).decode("base64") + creds = decodeBase64(match.group(1), binary=False) except: request.environ["PATH_INFO"] = "/error/401" else: diff --git a/lib/utils/hash.py b/lib/utils/hash.py index 1c7c49b59..d7f998616 100644 --- a/lib/utils/hash.py +++ b/lib/utils/hash.py @@ -50,6 +50,7 @@ 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 @@ -915,15 +916,15 @@ def dictionaryAttack(attack_dict): hash_ = hash_.lower() if hash_regex in (HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64): - item = [(user, hash_.decode("base64").encode("hex")), {}] + item = [(user, decodeBase64(hash_, binary=False).encode("hex")), {}] elif hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.SHA224_GENERIC, HASH.SHA256_GENERIC, HASH.SHA384_GENERIC, HASH.SHA512_GENERIC, HASH.APACHE_SHA1): item = [(user, hash_), {}] elif hash_regex in (HASH.SSHA,): - item = [(user, hash_), {"salt": hash_.decode("base64")[20:]}] + item = [(user, hash_), {"salt": decodeBase64(hash_, binary=False)[20:]}] elif hash_regex in (HASH.SSHA256,): - item = [(user, hash_), {"salt": hash_.decode("base64")[32:]}] + item = [(user, hash_), {"salt": decodeBase64(hash_, binary=False)[32:]}] elif hash_regex in (HASH.SSHA512,): - item = [(user, hash_), {"salt": hash_.decode("base64")[64:]}] + item = [(user, hash_), {"salt": decodeBase64(hash_, binary=False)[64:]}] elif hash_regex in (HASH.ORACLE_OLD, HASH.POSTGRES): item = [(user, hash_), {'username': user}] elif hash_regex in (HASH.ORACLE,): diff --git a/lib/utils/pivotdumptable.py b/lib/utils/pivotdumptable.py index 0b07907d8..3b1b416a9 100644 --- a/lib/utils/pivotdumptable.py +++ b/lib/utils/pivotdumptable.py @@ -33,6 +33,7 @@ from lib.core.settings import MAX_INT from lib.core.settings import NULL from lib.core.unescaper import unescaper from lib.request import inject +from thirdparty import six def pivotDumpTable(table, colList, count=None, blind=True, alias=None): lengths = {} @@ -142,7 +143,7 @@ def pivotDumpTable(table, colList, count=None, blind=True, alias=None): if column == colList[0]: if isNoneValue(value): try: - for pivotValue in filterNone((" " if pivotValue == " " else None, "%s%s" % (pivotValue[0], unichr(ord(pivotValue[1]) + 1)) if len(pivotValue) > 1 else None, unichr(ord(pivotValue[0]) + 1))): + for pivotValue in filterNone((" " if pivotValue == " " else None, "%s%s" % (pivotValue[0], six.unichr(ord(pivotValue[1]) + 1)) if len(pivotValue) > 1 else None, six.unichr(ord(pivotValue[0]) + 1))): value = _(column, pivotValue) if not isNoneValue(value): break diff --git a/lib/utils/xrange.py b/lib/utils/xrange.py index 75e435605..8bdb407b9 100644 --- a/lib/utils/xrange.py +++ b/lib/utils/xrange.py @@ -7,6 +7,8 @@ See the file 'LICENSE' for copying permission import numbers +from lib.core.compat import cmp + class xrange(object): """ Advanced (re)implementation of xrange (supports slice/copy/etc.) diff --git a/plugins/dbms/maxdb/enumeration.py b/plugins/dbms/maxdb/enumeration.py index dfb8a4349..1ce611abc 100644 --- a/plugins/dbms/maxdb/enumeration.py +++ b/plugins/dbms/maxdb/enumeration.py @@ -22,6 +22,7 @@ from lib.utils.brute import columnExists from lib.utils.pivotdumptable import pivotDumpTable from plugins.generic.enumeration import Enumeration as GenericEnumeration from thirdparty import six +from thirdparty.six.moves import zip as _zip class Enumeration(GenericEnumeration): def __init__(self): @@ -207,7 +208,7 @@ class Enumeration(GenericEnumeration): table = {} columns = {} - for columnname, datatype, length in zip(retVal[0]["%s.columnname" % kb.aliasName], retVal[0]["%s.datatype" % kb.aliasName], retVal[0]["%s.len" % kb.aliasName]): + for columnname, datatype, length in _zip(retVal[0]["%s.columnname" % kb.aliasName], retVal[0]["%s.datatype" % kb.aliasName], retVal[0]["%s.len" % kb.aliasName]): columns[safeSQLIdentificatorNaming(columnname)] = "%s(%s)" % (datatype, length) table[tbl] = columns diff --git a/plugins/dbms/sybase/enumeration.py b/plugins/dbms/sybase/enumeration.py index 002991a72..0c3c19511 100644 --- a/plugins/dbms/sybase/enumeration.py +++ b/plugins/dbms/sybase/enumeration.py @@ -27,6 +27,7 @@ from lib.utils.brute import columnExists from lib.utils.pivotdumptable import pivotDumpTable from plugins.generic.enumeration import Enumeration as GenericEnumeration from thirdparty import six +from thirdparty.six.moves import zip as _zip class Enumeration(GenericEnumeration): def getUsers(self): @@ -279,7 +280,7 @@ class Enumeration(GenericEnumeration): table = {} columns = {} - for name, type_ in filterPairValues(zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.usertype" % kb.aliasName])): + for name, type_ in filterPairValues(_zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.usertype" % kb.aliasName])): columns[name] = SYBASE_TYPES.get(int(type_) if hasattr(type_, "isdigit") and type_.isdigit() else type_, type_) table[safeSQLIdentificatorNaming(tbl, True)] = columns diff --git a/plugins/generic/entries.py b/plugins/generic/entries.py index 632ad349b..b91fd5200 100644 --- a/plugins/generic/entries.py +++ b/plugins/generic/entries.py @@ -46,6 +46,7 @@ from lib.request import inject from lib.utils.hash import attackDumpedTable from lib.utils.pivotdumptable import pivotDumpTable from thirdparty import six +from thirdparty.six.moves import zip as _zip class Entries: """ @@ -224,7 +225,7 @@ class Entries: if retVal: entries, _ = retVal - entries = zip(*[entries[colName] for colName in colList]) + entries = _zip(*[entries[colName] for colName in colList]) else: query = rootQuery.inband.query % (colString, conf.db, tbl) elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2): diff --git a/plugins/generic/users.py b/plugins/generic/users.py index 3708a088b..96df4505b 100644 --- a/plugins/generic/users.py +++ b/plugins/generic/users.py @@ -43,6 +43,7 @@ from lib.request import inject from lib.utils.hash import attackCachedUsersPasswords from lib.utils.hash import storeHashesToFile from lib.utils.pivotdumptable import pivotDumpTable +from thirdparty.six.moves import zip as _zip class Users: """ @@ -192,7 +193,7 @@ class Users: retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.password' % kb.aliasName], blind=False) if retVal: - for user, password in filterPairValues(zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])): + for user, password in filterPairValues(_zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])): if user not in kb.data.cachedUsersPasswords: kb.data.cachedUsersPasswords[user] = [password] else: @@ -237,7 +238,7 @@ class Users: retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.password' % kb.aliasName], blind=True) if retVal: - for user, password in filterPairValues(zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])): + 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() if user not in kb.data.cachedUsersPasswords: