From 9b72545d097382220a0dbec309fbbc364cc543b5 Mon Sep 17 00:00:00 2001
From: Miroslav Stampar <miroslav.stampar@gmail.com>
Date: Thu, 28 Mar 2019 16:04:38 +0100
Subject: [PATCH] Some more DREI stuff

---
 extra/beep/__init__.py                  |   2 +-
 extra/beep/beep.py                      |   7 +-
 extra/cloak/__init__.py                 |   2 +-
 extra/cloak/cloak.py                    |  14 +-
 extra/dbgtool/__init__.py               |   2 +-
 extra/dbgtool/dbgtool.py                |   4 +-
 extra/shutils/duplicates.py             |   4 +-
 extra/shutils/newlines.py               |  10 +-
 extra/shutils/pylint.py                 |   2 +-
 extra/shutils/regressiontest.py         | 166 ------------------------
 lib/controller/checks.py                |   2 +-
 lib/controller/controller.py            |   2 +-
 lib/core/agent.py                       |   2 +-
 lib/core/bigarray.py                    |   2 +-
 lib/core/common.py                      |   2 +-
 lib/core/compat.py                      |   8 +-
 lib/core/dump.py                        |   2 +-
 lib/core/option.py                      |   2 +-
 lib/core/settings.py                    |   2 +-
 lib/core/target.py                      |   2 +-
 lib/core/threads.py                     |   2 +-
 lib/parse/cmdline.py                    |   2 +-
 lib/parse/payloads.py                   |   2 +-
 lib/request/connect.py                  |   2 +-
 lib/request/inject.py                   |   2 +-
 lib/takeover/udf.py                     |   4 +-
 lib/takeover/web.py                     |   2 +-
 lib/takeover/xp_cmdshell.py             |   2 +-
 lib/techniques/dns/use.py               |   2 +-
 lib/techniques/error/use.py             |   2 +-
 lib/techniques/union/test.py            |   2 +-
 lib/techniques/union/use.py             |   2 +-
 lib/utils/api.py                        |   2 +-
 lib/utils/crawler.py                    |   2 +-
 lib/utils/hash.py                       |   2 +-
 lib/utils/hashdb.py                     |   2 +-
 lib/utils/pivotdumptable.py             |   2 +-
 lib/utils/purge.py                      |   2 +-
 plugins/dbms/db2/fingerprint.py         |   2 +-
 plugins/dbms/firebird/fingerprint.py    |   2 +-
 plugins/dbms/h2/syntax.py               |   2 +-
 plugins/dbms/hsqldb/syntax.py           |   2 +-
 plugins/dbms/maxdb/fingerprint.py       |   2 +-
 plugins/dbms/mssqlserver/enumeration.py |   2 +-
 plugins/dbms/mssqlserver/filesystem.py  |   2 +-
 plugins/dbms/mssqlserver/syntax.py      |   2 +-
 plugins/dbms/mssqlserver/takeover.py    |   2 +-
 plugins/dbms/mysql/filesystem.py        |   2 +-
 plugins/dbms/mysql/fingerprint.py       |   2 +-
 plugins/dbms/oracle/enumeration.py      |   2 +-
 plugins/dbms/oracle/syntax.py           |   2 +-
 plugins/dbms/postgresql/filesystem.py   |   2 +-
 plugins/dbms/sybase/fingerprint.py      |   2 +-
 plugins/dbms/sybase/syntax.py           |   2 +-
 plugins/generic/filesystem.py           |   2 +-
 plugins/generic/users.py                |   2 +-
 tamper/ifnull2casewhenisnull.py         |   2 +-
 tamper/ifnull2ifisnull.py               |   2 +-
 tamper/luanginx.py                      |   2 +-
 tamper/plus2concat.py                   |   2 +-
 tamper/plus2fnconcat.py                 |   2 +-
 tamper/randomcase.py                    |   2 +-
 tamper/randomcomments.py                |   2 +-
 tamper/space2comment.py                 |   2 +-
 tamper/space2dash.py                    |   2 +-
 tamper/space2hash.py                    |   2 +-
 tamper/space2morecomment.py             |   2 +-
 tamper/space2morehash.py                |   2 +-
 tamper/space2mssqlblank.py              |   2 +-
 tamper/space2mssqlhash.py               |   2 +-
 tamper/space2mysqlblank.py              |   2 +-
 tamper/space2mysqldash.py               |   2 +-
 tamper/space2plus.py                    |   2 +-
 tamper/space2randomblank.py             |   2 +-
 tamper/unmagicquotes.py                 |   2 +-
 tamper/xforwardedfor.py                 |   2 +-
 76 files changed, 95 insertions(+), 258 deletions(-)
 delete mode 100755 extra/shutils/regressiontest.py

diff --git a/extra/beep/__init__.py b/extra/beep/__init__.py
index 8307a1c28..c654cbef7 100644
--- a/extra/beep/__init__.py
+++ b/extra/beep/__init__.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 
 """
 Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
diff --git a/extra/beep/beep.py b/extra/beep/beep.py
index 8e26d30cb..08cd26f92 100644
--- a/extra/beep/beep.py
+++ b/extra/beep/beep.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 
 """
 beep.py - Make a beep sound
@@ -8,7 +8,6 @@ See the file 'LICENSE' for copying permission
 """
 
 import os
-import subprocess
 import sys
 import wave
 
@@ -16,11 +15,11 @@ BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav")
 
 def beep():
     try:
-        if subprocess.mswindows:
+        if sys.platform == "nt":
             _win_wav_play(BEEP_WAV_FILENAME)
         elif sys.platform == "darwin":
             _mac_beep()
-        elif sys.platform == "linux2":
+        elif sys.platform.startswith("linux"):
             _linux_wav_play(BEEP_WAV_FILENAME)
         else:
             _speaker_beep()
diff --git a/extra/cloak/__init__.py b/extra/cloak/__init__.py
index 8307a1c28..c654cbef7 100644
--- a/extra/cloak/__init__.py
+++ b/extra/cloak/__init__.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 
 """
 Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
diff --git a/extra/cloak/cloak.py b/extra/cloak/cloak.py
index 8462dbc12..72f7fe1e2 100644
--- a/extra/cloak/cloak.py
+++ b/extra/cloak/cloak.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 
 """
 cloak.py - Simple file encryption/compression utility
@@ -10,6 +10,7 @@ See the file 'LICENSE' for copying permission
 from __future__ import print_function
 
 import os
+import struct
 import sys
 import zlib
 
@@ -20,12 +21,10 @@ if sys.version_info.major > 2:
     xrange = range
 
 def hideAscii(data):
-    retVal = ""
+    retVal = b""
     for i in xrange(len(data)):
-        if ord(data[i]) < 128:
-            retVal += chr(ord(data[i]) ^ 127)
-        else:
-            retVal += data[i]
+        value = data[i] if isinstance(data[i], int) else ord(data[i])
+        retVal += struct.pack('B', value ^ (127 if value < 128 else 0))
 
     return retVal
 
@@ -42,7 +41,8 @@ def decloak(inputFile=None, data=None):
             data = f.read()
     try:
         data = zlib.decompress(hideAscii(data))
-    except:
+    except Exception as ex:
+        print(ex)
         print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile)
         sys.exit(1)
     finally:
diff --git a/extra/dbgtool/__init__.py b/extra/dbgtool/__init__.py
index 8307a1c28..c654cbef7 100644
--- a/extra/dbgtool/__init__.py
+++ b/extra/dbgtool/__init__.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 
 """
 Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
diff --git a/extra/dbgtool/dbgtool.py b/extra/dbgtool/dbgtool.py
index ca473f39d..6cca8bdc2 100644
--- a/extra/dbgtool/dbgtool.py
+++ b/extra/dbgtool/dbgtool.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 
 """
 dbgtool.py - Portable executable to ASCII debug script converter
@@ -34,7 +34,7 @@ def convert(inputFile):
     fileContent = fp.read()
 
     for fileChar in fileContent:
-        unsignedFileChar = struct.unpack("B", fileChar)[0]
+        unsignedFileChar = fileChar if sys.version_info.major > 2 else ord(fileChar)
 
         if unsignedFileChar != 0:
             counter2 += 1
diff --git a/extra/shutils/duplicates.py b/extra/shutils/duplicates.py
index 23cc803df..c3a1ebd19 100755
--- a/extra/shutils/duplicates.py
+++ b/extra/shutils/duplicates.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 
 # Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
 # See the file 'LICENSE' for copying permission
@@ -10,7 +10,7 @@ from __future__ import print_function
 import sys
 
 if __name__ == "__main__":
-    if len(sys.argv) > 0:
+    if len(sys.argv) > 1:
         items = list()
 
         with open(sys.argv[1], 'r') as f:
diff --git a/extra/shutils/newlines.py b/extra/shutils/newlines.py
index 1d76b377f..fe28a35ba 100644
--- a/extra/shutils/newlines.py
+++ b/extra/shutils/newlines.py
@@ -1,7 +1,4 @@
-#! /usr/bin/env python2
-
-# Runs pylint on all python scripts found in a directory tree
-# Reference: http://rowinggolfer.blogspot.com/2009/08/pylint-recursively.html
+#! /usr/bin/env python
 
 from __future__ import print_function
 
@@ -11,9 +8,10 @@ import sys
 def check(filepath):
     if filepath.endswith(".py"):
         content = open(filepath, "rb").read()
+        pattern = "\n\n\n".encode("ascii")
 
-        if "\n\n\n" in content:
-            index = content.find("\n\n\n")
+        if pattern in content:
+            index = content.find(pattern)
             print(filepath, repr(content[index - 30:index + 30]))
 
 if __name__ == "__main__":
diff --git a/extra/shutils/pylint.py b/extra/shutils/pylint.py
index 13895460b..cec5321b2 100755
--- a/extra/shutils/pylint.py
+++ b/extra/shutils/pylint.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python2
+#! /usr/bin/env python
 
 # Runs pylint on all python scripts found in a directory tree
 # Reference: http://rowinggolfer.blogspot.com/2009/08/pylint-recursively.html
diff --git a/extra/shutils/regressiontest.py b/extra/shutils/regressiontest.py
deleted file mode 100755
index 6d7f8134a..000000000
--- a/extra/shutils/regressiontest.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env python2
-
-# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
-# See the file 'LICENSE' for copying permission
-
-from __future__ import print_function
-
-import codecs
-import inspect
-import os
-import re
-import smtplib
-import subprocess
-import sys
-import time
-import traceback
-
-from email.mime.multipart import MIMEMultipart
-from email.mime.text import MIMEText
-
-sys.path.append(os.path.normpath("%s/../../" % os.path.dirname(inspect.getfile(inspect.currentframe()))))
-
-from lib.core.revision import getRevisionNumber
-
-START_TIME = time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime())
-SQLMAP_HOME = "/opt/sqlmap"
-
-SMTP_SERVER = "127.0.0.1"
-SMTP_PORT = 25
-SMTP_TIMEOUT = 30
-FROM = "regressiontest@sqlmap.org"
-# TO = "dev@sqlmap.org"
-TO = ["bernardo.damele@gmail.com", "miroslav.stampar@gmail.com"]
-SUBJECT = "regression test started on %s using revision %s" % (START_TIME, getRevisionNumber())
-TARGET = "debian"
-
-def prepare_email(content):
-    global FROM
-    global TO
-    global SUBJECT
-
-    msg = MIMEMultipart()
-    msg["Subject"] = SUBJECT
-    msg["From"] = FROM
-    msg["To"] = TO if isinstance(TO, basestring) else ','.join(TO)
-
-    msg.attach(MIMEText(content))
-
-    return msg
-
-def send_email(msg):
-    global SMTP_SERVER
-    global SMTP_PORT
-    global SMTP_TIMEOUT
-
-    try:
-        s = smtplib.SMTP(host=SMTP_SERVER, port=SMTP_PORT, timeout=SMTP_TIMEOUT)
-        s.sendmail(FROM, TO, msg.as_string())
-        s.quit()
-    # Catch all for SMTP exceptions
-    except smtplib.SMTPException as ex:
-        print("Failure to send email: '%s" % ex)
-
-def failure_email(msg):
-    msg = prepare_email(msg)
-    send_email(msg)
-    sys.exit(1)
-
-def main():
-    global SUBJECT
-
-    content = ""
-    test_counts = []
-    attachments = {}
-
-    updateproc = subprocess.Popen("cd /opt/sqlmap/ ; python /opt/sqlmap/sqlmap.py --update", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    stdout, stderr = updateproc.communicate()
-
-    if stderr:
-        failure_email("Update of sqlmap failed with error:\n\n%s" % stderr)
-
-    regressionproc = subprocess.Popen("python /opt/sqlmap/sqlmap.py --live-test", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
-    stdout, stderr = regressionproc.communicate()
-
-    if stderr:
-        failure_email("Execution of regression test failed with error:\n\n%s" % stderr)
-
-    failed_tests = re.findall(r"running live test case: (.+?) \((\d+)\/\d+\)[\r]*\n.+test failed (at parsing items: (.+))?\s*\- scan folder: (\/.+) \- traceback: (.*?)( - SQL injection not detected)?[\r]*\n", stdout)
-
-    for failed_test in failed_tests:
-        title = failed_test[0]
-        test_count = int(failed_test[1])
-        parse = failed_test[3] if failed_test[3] else None
-        output_folder = failed_test[4]
-        traceback = False if failed_test[5] == "False" else bool(failed_test[5])
-        detected = False if failed_test[6] else True
-
-        test_counts.append(test_count)
-
-        console_output_file = os.path.join(output_folder, "console_output")
-        log_file = os.path.join(output_folder, TARGET, "log")
-        traceback_file = os.path.join(output_folder, "traceback")
-
-        if os.path.exists(console_output_file):
-            console_output_fd = codecs.open(console_output_file, "rb", "utf8")
-            console_output = console_output_fd.read()
-            console_output_fd.close()
-            attachments[test_count] = str(console_output)
-
-        if os.path.exists(log_file):
-            log_fd = codecs.open(log_file, "rb", "utf8")
-            log = log_fd.read()
-            log_fd.close()
-
-        if os.path.exists(traceback_file):
-            traceback_fd = codecs.open(traceback_file, "rb", "utf8")
-            traceback = traceback_fd.read()
-            traceback_fd.close()
-
-        content += "Failed test case '%s' (#%d)" % (title, test_count)
-
-        if parse:
-            content += " at parsing: %s:\n\n" % parse
-            content += "### Log file:\n\n"
-            content += "%s\n\n" % log
-        elif not detected:
-            content += " - SQL injection not detected\n\n"
-        else:
-            content += "\n\n"
-
-        if traceback:
-            content += "### Traceback:\n\n"
-            content += "%s\n\n" % str(traceback)
-
-        content += "#######################################################################\n\n"
-
-    end_string = "Regression test finished at %s" % time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime())
-
-    if content:
-        content += end_string
-        SUBJECT = "Failed %s (%s)" % (SUBJECT, ", ".join("#%d" % count for count in test_counts))
-
-        msg = prepare_email(content)
-
-        for test_count, attachment in attachments.items():
-            attachment = MIMEText(attachment)
-            attachment.add_header("Content-Disposition", "attachment", filename="test_case_%d_console_output.txt" % test_count)
-            msg.attach(attachment)
-
-        send_email(msg)
-    else:
-        SUBJECT = "Successful %s" % SUBJECT
-        msg = prepare_email("All test cases were successful\n\n%s" % end_string)
-        send_email(msg)
-
-if __name__ == "__main__":
-    log_fd = open("/tmp/sqlmapregressiontest.log", "wb")
-    log_fd.write("Regression test started at %s\n" % START_TIME)
-
-    try:
-        main()
-    except Exception:
-        log_fd.write("An exception has occurred:\n%s" % str(traceback.format_exc()))
-
-    log_fd.write("Regression test finished at %s\n\n" % time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime()))
-    log_fd.close()
diff --git a/lib/controller/checks.py b/lib/controller/checks.py
index 20a6af967..cb46ef879 100644
--- a/lib/controller/checks.py
+++ b/lib/controller/checks.py
@@ -47,6 +47,7 @@ from lib.core.common import unArrayizeValue
 from lib.core.common import urlencode
 from lib.core.common import wasLastResponseDBMSError
 from lib.core.common import wasLastResponseHTTPError
+from lib.core.compat import xrange
 from lib.core.convert import unicodeencode
 from lib.core.defaults import defaults
 from lib.core.data import conf
@@ -105,7 +106,6 @@ from lib.request.inject import checkBooleanExpression
 from lib.request.templates import getPageTemplate
 from lib.techniques.union.test import unionTest
 from lib.techniques.union.use import configUnion
-from lib.utils.xrange import xrange
 from thirdparty import six
 from thirdparty.six.moves import http_client as _http_client
 
diff --git a/lib/controller/controller.py b/lib/controller/controller.py
index 3c174618a..d2d6f7899 100644
--- a/lib/controller/controller.py
+++ b/lib/controller/controller.py
@@ -40,6 +40,7 @@ from lib.core.common import safeCSValue
 from lib.core.common import showHttpErrorCodes
 from lib.core.common import urlencode
 from lib.core.common import urldecode
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -72,7 +73,6 @@ from lib.core.settings import USER_AGENT_ALIASES
 from lib.core.target import initTargetEnv
 from lib.core.target import setupTargetEnv
 from lib.utils.hash import crackHashFile
-from lib.utils.xrange import xrange
 
 def _selectInjection():
     """
diff --git a/lib/core/agent.py b/lib/core/agent.py
index 49c313f3d..9fab4004c 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -23,6 +23,7 @@ from lib.core.common import splitFields
 from lib.core.common import unArrayizeValue
 from lib.core.common import urlencode
 from lib.core.common import zeroDepthSearch
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import queries
@@ -46,7 +47,6 @@ from lib.core.settings import REPLACEMENT_MARKER
 from lib.core.settings import SINGLE_QUOTE_MARKER
 from lib.core.settings import SLEEP_TIME_MARKER
 from lib.core.unescaper import unescaper
-from lib.utils.xrange import xrange
 
 class Agent(object):
     """
diff --git a/lib/core/bigarray.py b/lib/core/bigarray.py
index d450d5777..a1dbcfecc 100644
--- a/lib/core/bigarray.py
+++ b/lib/core/bigarray.py
@@ -16,11 +16,11 @@ import os
 import sys
 import tempfile
 
+from lib.core.compat import xrange
 from lib.core.enums import MKSTEMP_PREFIX
 from lib.core.exception import SqlmapSystemException
 from lib.core.settings import BIGARRAY_CHUNK_SIZE
 from lib.core.settings import BIGARRAY_COMPRESS_LEVEL
-from lib.utils.xrange import xrange
 
 DEFAULT_SIZE_OF = sys.getsizeof(object())
 
diff --git a/lib/core/common.py b/lib/core/common.py
index 707a1f1fe..7bdec65e0 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -45,6 +45,7 @@ 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 xrange
 from lib.core.convert import base64pickle
 from lib.core.convert import base64unpickle
 from lib.core.convert import hexdecode
@@ -167,7 +168,6 @@ from lib.core.settings import VERSION_STRING
 from lib.core.settings import WEBSCARAB_SPLITTER
 from lib.core.threads import getCurrentThreadData
 from lib.utils.sqlalchemy import _sqlalchemy
-from lib.utils.xrange import xrange
 from thirdparty import six
 from thirdparty.clientform.clientform import ParseResponse
 from thirdparty.clientform.clientform import ParseError
diff --git a/lib/core/compat.py b/lib/core/compat.py
index 7c164596f..74895c875 100644
--- a/lib/core/compat.py
+++ b/lib/core/compat.py
@@ -9,6 +9,7 @@ import binascii
 import os
 import random
 import uuid
+import sys
 
 class WichmannHill(random.Random):
     """
@@ -163,4 +164,9 @@ class WichmannHill(random.Random):
 
 # Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py
 def choose_boundary():
-    return uuid.uuid4().hex
\ No newline at end of file
+    return uuid.uuid4().hex
+
+if sys.version_info.major > 2:
+    xrange = range
+else:
+    xrange = xrange
diff --git a/lib/core/dump.py b/lib/core/dump.py
index eb6777f37..74a6d6c01 100644
--- a/lib/core/dump.py
+++ b/lib/core/dump.py
@@ -28,6 +28,7 @@ from lib.core.common import randomInt
 from lib.core.common import safeCSValue
 from lib.core.common import unicodeencode
 from lib.core.common import unsafeSQLIdentificatorNaming
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -50,7 +51,6 @@ from lib.core.settings import UNICODE_ENCODING
 from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT
 from lib.core.settings import VERSION_STRING
 from lib.core.settings import WINDOWS_RESERVED_NAMES
-from lib.utils.xrange import xrange
 from thirdparty import six
 from thirdparty.magic import magic
 
diff --git a/lib/core/option.py b/lib/core/option.py
index 1cf106ec3..8744c1951 100644
--- a/lib/core/option.py
+++ b/lib/core/option.py
@@ -58,6 +58,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 xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -147,7 +148,6 @@ from lib.utils.crawler import crawl
 from lib.utils.deps import checkDependencies
 from lib.utils.search import search
 from lib.utils.purge import purge
-from lib.utils.xrange import xrange
 from thirdparty import six
 from thirdparty.keepalive import keepalive
 from thirdparty.multipart import multipartpost
diff --git a/lib/core/settings.py b/lib/core/settings.py
index 5e6943d17..c45f89d5b 100644
--- a/lib/core/settings.py
+++ b/lib/core/settings.py
@@ -17,7 +17,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
 from lib.core.enums import OS
 
 # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
-VERSION = "1.3.3.71"
+VERSION = "1.3.3.72"
 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/target.py b/lib/core/target.py
index 45abcc0e8..c6522f490 100644
--- a/lib/core/target.py
+++ b/lib/core/target.py
@@ -26,6 +26,7 @@ from lib.core.common import randomStr
 from lib.core.common import readInput
 from lib.core.common import resetCookieJar
 from lib.core.common import urldecode
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -72,7 +73,6 @@ from lib.core.settings import URI_INJECTABLE_REGEX
 from lib.core.settings import USER_AGENT_ALIASES
 from lib.core.settings import XML_RECOGNITION_REGEX
 from lib.utils.hashdb import HashDB
-from lib.utils.xrange import xrange
 from thirdparty.odict import OrderedDict
 from thirdparty.six.moves import urllib as _urllib
 
diff --git a/lib/core/threads.py b/lib/core/threads.py
index c32ed0c5e..bf871a11d 100644
--- a/lib/core/threads.py
+++ b/lib/core/threads.py
@@ -13,6 +13,7 @@ import time
 import traceback
 
 from lib.core.compat import WichmannHill
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -25,7 +26,6 @@ from lib.core.exception import SqlmapUserQuitException
 from lib.core.exception import SqlmapValueException
 from lib.core.settings import MAX_NUMBER_OF_THREADS
 from lib.core.settings import PYVERSION
-from lib.utils.xrange import xrange
 
 shared = AttribDict()
 
diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py
index da3edf4b6..1fe1b0db4 100644
--- a/lib/parse/cmdline.py
+++ b/lib/parse/cmdline.py
@@ -22,6 +22,7 @@ from lib.core.common import checkSystemEncoding
 from lib.core.common import dataToStdout
 from lib.core.common import expandMnemonics
 from lib.core.common import getUnicode
+from lib.core.compat import xrange
 from lib.core.data import cmdLineOptions
 from lib.core.data import conf
 from lib.core.data import logger
@@ -39,7 +40,6 @@ from lib.core.shell import autoCompletion
 from lib.core.shell import clearHistory
 from lib.core.shell import loadHistory
 from lib.core.shell import saveHistory
-from lib.utils.xrange import xrange
 
 def cmdLineParser(argv=None):
     """
diff --git a/lib/parse/payloads.py b/lib/parse/payloads.py
index 37addf5d1..5765df92b 100644
--- a/lib/parse/payloads.py
+++ b/lib/parse/payloads.py
@@ -11,12 +11,12 @@ import re
 from xml.etree import ElementTree as et
 
 from lib.core.common import getSafeExString
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import paths
 from lib.core.datatype import AttribDict
 from lib.core.exception import SqlmapInstallationException
 from lib.core.settings import PAYLOAD_XML_FILES
-from lib.utils.xrange import xrange
 
 def cleanupVals(text, tag):
     if tag == "clause" and '-' in text:
diff --git a/lib/request/connect.py b/lib/request/connect.py
index ab5ce963e..3d2e354b9 100644
--- a/lib/request/connect.py
+++ b/lib/request/connect.py
@@ -57,6 +57,7 @@ from lib.core.common import unicodeencode
 from lib.core.common import unsafeVariableNaming
 from lib.core.common import urldecode
 from lib.core.common import urlencode
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -118,7 +119,6 @@ from lib.request.basic import processResponse
 from lib.request.direct import direct
 from lib.request.comparison import comparison
 from lib.request.methodrequest import MethodRequest
-from lib.utils.xrange import xrange
 from thirdparty import six
 from thirdparty.odict import OrderedDict
 from thirdparty.six.moves import http_client as _http_client
diff --git a/lib/request/inject.py b/lib/request/inject.py
index f9a798d58..5555e962d 100644
--- a/lib/request/inject.py
+++ b/lib/request/inject.py
@@ -31,6 +31,7 @@ from lib.core.common import pushValue
 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.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -59,7 +60,6 @@ from lib.techniques.dns.test import dnsTest
 from lib.techniques.dns.use import dnsUse
 from lib.techniques.error.use import errorUse
 from lib.techniques.union.use import unionUse
-from lib.utils.xrange import xrange
 from thirdparty import six
 
 def _goDns(payload, expression):
diff --git a/lib/takeover/udf.py b/lib/takeover/udf.py
index 787ac481c..45ecefc49 100644
--- a/lib/takeover/udf.py
+++ b/lib/takeover/udf.py
@@ -13,6 +13,8 @@ from lib.core.common import dataToStdout
 from lib.core.common import Backend
 from lib.core.common import isStackingAvailable
 from lib.core.common import readInput
+from lib.core.common import unArrayizeValue
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import logger
 from lib.core.data import queries
@@ -20,14 +22,12 @@ from lib.core.enums import DBMS
 from lib.core.enums import CHARSET_TYPE
 from lib.core.enums import EXPECTED
 from lib.core.enums import OS
-from lib.core.common import unArrayizeValue
 from lib.core.exception import SqlmapFilePathException
 from lib.core.exception import SqlmapMissingMandatoryOptionException
 from lib.core.exception import SqlmapUnsupportedFeatureException
 from lib.core.exception import SqlmapUserQuitException
 from lib.core.unescaper import unescaper
 from lib.request import inject
-from lib.utils.xrange import xrange
 
 class UDF:
     """
diff --git a/lib/takeover/web.py b/lib/takeover/web.py
index 9102becba..27e522ad5 100644
--- a/lib/takeover/web.py
+++ b/lib/takeover/web.py
@@ -31,6 +31,7 @@ from lib.core.common import randomInt
 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.data import conf
@@ -51,7 +52,6 @@ from lib.core.settings import SHELL_RUNCMD_EXE_TAG
 from lib.core.settings import SHELL_WRITABLE_DIR_TAG
 from lib.core.settings import VIEWSTATE_REGEX
 from lib.request.connect import Connect as Request
-from lib.utils.xrange import xrange
 from thirdparty.six.moves import urllib as _urllib
 
 class Web:
diff --git a/lib/takeover/xp_cmdshell.py b/lib/takeover/xp_cmdshell.py
index d50f08116..788baa04c 100644
--- a/lib/takeover/xp_cmdshell.py
+++ b/lib/takeover/xp_cmdshell.py
@@ -20,6 +20,7 @@ from lib.core.common import popValue
 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.data import conf
 from lib.core.data import kb
@@ -32,7 +33,6 @@ from lib.core.enums import HASHDB_KEYS
 from lib.core.enums import PAYLOAD
 from lib.core.exception import SqlmapUnsupportedFeatureException
 from lib.core.threads import getCurrentThreadData
-from lib.utils.xrange import xrange
 from lib.request import inject
 
 class XP_cmdshell:
diff --git a/lib/techniques/dns/use.py b/lib/techniques/dns/use.py
index 9d447c7d3..04f4f6899 100644
--- a/lib/techniques/dns/use.py
+++ b/lib/techniques/dns/use.py
@@ -22,6 +22,7 @@ from lib.core.common import randomInt
 from lib.core.common import randomStr
 from lib.core.common import safeStringFormat
 from lib.core.common import singleTimeWarnMessage
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -32,7 +33,6 @@ from lib.core.settings import MAX_DNS_LABEL
 from lib.core.settings import PARTIAL_VALUE_MARKER
 from lib.core.unescaper import unescaper
 from lib.request.connect import Connect as Request
-from lib.utils.xrange import xrange
 
 def dnsUse(payload, expression):
     """
diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py
index 50a56e5dc..ce70b8b96 100644
--- a/lib/techniques/error/use.py
+++ b/lib/techniques/error/use.py
@@ -32,6 +32,7 @@ from lib.core.common import listToStrValue
 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 htmlunescape
 from lib.core.data import conf
@@ -57,7 +58,6 @@ from lib.core.threads import runThreads
 from lib.core.unescaper import unescaper
 from lib.request.connect import Connect as Request
 from lib.utils.progress import ProgressBar
-from lib.utils.xrange import xrange
 from thirdparty import six
 
 def _oneShotErrorUse(expression, field=None, chunkTest=False):
diff --git a/lib/techniques/union/test.py b/lib/techniques/union/test.py
index 3d51b7dc6..137656f02 100644
--- a/lib/techniques/union/test.py
+++ b/lib/techniques/union/test.py
@@ -24,6 +24,7 @@ from lib.core.common import singleTimeLogMessage
 from lib.core.common import singleTimeWarnMessage
 from lib.core.common import stdev
 from lib.core.common import wasLastResponseDBMSError
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -42,7 +43,6 @@ from lib.core.settings import ORDER_BY_STEP
 from lib.core.unescaper import unescaper
 from lib.request.comparison import comparison
 from lib.request.connect import Connect as Request
-from lib.utils.xrange import xrange
 
 def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=PAYLOAD.WHERE.ORIGINAL):
     """
diff --git a/lib/techniques/union/use.py b/lib/techniques/union/use.py
index 3800b52ef..ffb3085f1 100644
--- a/lib/techniques/union/use.py
+++ b/lib/techniques/union/use.py
@@ -38,6 +38,7 @@ from lib.core.common import singleTimeDebugMessage
 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 htmlunescape
 from lib.core.data import conf
 from lib.core.data import kb
@@ -59,7 +60,6 @@ from lib.core.threads import runThreads
 from lib.core.unescaper import unescaper
 from lib.request.connect import Connect as Request
 from lib.utils.progress import ProgressBar
-from lib.utils.xrange import xrange
 from thirdparty import six
 from thirdparty.odict import OrderedDict
 
diff --git a/lib/utils/api.py b/lib/utils/api.py
index 384c84c88..e42e18fd4 100644
--- a/lib/utils/api.py
+++ b/lib/utils/api.py
@@ -23,6 +23,7 @@ from lib.core.common import dataToStdout
 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 dejsonize
@@ -47,7 +48,6 @@ from lib.core.settings import RESTAPI_DEFAULT_PORT
 from lib.core.shell import autoCompletion
 from lib.core.subprocessng import Popen
 from lib.parse.cmdline import cmdLineParser
-from lib.utils.xrange import xrange
 from thirdparty.bottle.bottle import error as return_error
 from thirdparty.bottle.bottle import get
 from thirdparty.bottle.bottle import hook
diff --git a/lib/utils/crawler.py b/lib/utils/crawler.py
index faecf5da7..7a86a947d 100644
--- a/lib/utils/crawler.py
+++ b/lib/utils/crawler.py
@@ -19,6 +19,7 @@ from lib.core.common import openFile
 from lib.core.common import readInput
 from lib.core.common import safeCSValue
 from lib.core.common import urldecode
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -31,7 +32,6 @@ from lib.core.threads import getCurrentThreadData
 from lib.core.threads import runThreads
 from lib.parse.sitemap import parseSitemap
 from lib.request.connect import Connect as Request
-from lib.utils.xrange import xrange
 from thirdparty.beautifulsoup.beautifulsoup import BeautifulSoup
 from thirdparty.six.moves import http_client as _http_client
 from thirdparty.six.moves import urllib as _urllib
diff --git a/lib/utils/hash.py b/lib/utils/hash.py
index 98d76b6df..5a2a9f084 100644
--- a/lib/utils/hash.py
+++ b/lib/utils/hash.py
@@ -61,6 +61,7 @@ from lib.core.common import paths
 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
@@ -86,7 +87,6 @@ from lib.core.settings import NULL
 from lib.core.settings import UNICODE_ENCODING
 from lib.core.settings import ROTATING_CHARS
 from lib.core.wordlist import Wordlist
-from lib.utils.xrange import xrange
 from thirdparty import six
 from thirdparty.colorama.initialise import init as coloramainit
 from thirdparty.pydes.pyDes import des
diff --git a/lib/utils/hashdb.py b/lib/utils/hashdb.py
index 808cf3b9d..d0189f725 100644
--- a/lib/utils/hashdb.py
+++ b/lib/utils/hashdb.py
@@ -16,6 +16,7 @@ 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.data import logger
 from lib.core.exception import SqlmapConnectionException
 from lib.core.settings import HASHDB_END_TRANSACTION_RETRIES
@@ -25,7 +26,6 @@ from lib.core.settings import HASHDB_RETRIEVE_RETRIES
 from lib.core.settings import UNICODE_ENCODING
 from lib.core.threads import getCurrentThreadData
 from lib.core.threads import getCurrentThreadName
-from lib.utils.xrange import xrange
 
 class HashDB(object):
     def __init__(self, filepath):
diff --git a/lib/utils/pivotdumptable.py b/lib/utils/pivotdumptable.py
index f1372ac4f..902e4d51c 100644
--- a/lib/utils/pivotdumptable.py
+++ b/lib/utils/pivotdumptable.py
@@ -18,6 +18,7 @@ from lib.core.common import isNumPosStrValue
 from lib.core.common import singleTimeWarnMessage
 from lib.core.common import unArrayizeValue
 from lib.core.common import unsafeSQLIdentificatorNaming
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -31,7 +32,6 @@ 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 lib.utils.xrange import xrange
 
 def pivotDumpTable(table, colList, count=None, blind=True, alias=None):
     lengths = {}
diff --git a/lib/utils/purge.py b/lib/utils/purge.py
index fc4ed95a0..ad84ad795 100644
--- a/lib/utils/purge.py
+++ b/lib/utils/purge.py
@@ -12,8 +12,8 @@ import stat
 import string
 
 from lib.core.common import getSafeExString
+from lib.core.compat import xrange
 from lib.core.data import logger
-from lib.utils.xrange import xrange
 
 def purge(directory):
     """
diff --git a/plugins/dbms/db2/fingerprint.py b/plugins/dbms/db2/fingerprint.py
index 43c81c2f0..1a9ae8f90 100644
--- a/plugins/dbms/db2/fingerprint.py
+++ b/plugins/dbms/db2/fingerprint.py
@@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
 
 from lib.core.common import Backend
 from lib.core.common import Format
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -15,7 +16,6 @@ from lib.core.enums import OS
 from lib.core.session import setDbms
 from lib.core.settings import DB2_ALIASES
 from lib.request import inject
-from lib.utils.xrange import xrange
 from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
 
 class Fingerprint(GenericFingerprint):
diff --git a/plugins/dbms/firebird/fingerprint.py b/plugins/dbms/firebird/fingerprint.py
index 210f35329..e491fe1cc 100644
--- a/plugins/dbms/firebird/fingerprint.py
+++ b/plugins/dbms/firebird/fingerprint.py
@@ -11,6 +11,7 @@ from lib.core.common import Backend
 from lib.core.common import Format
 from lib.core.common import getUnicode
 from lib.core.common import randomRange
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -19,7 +20,6 @@ from lib.core.session import setDbms
 from lib.core.settings import FIREBIRD_ALIASES
 from lib.core.settings import METADB_SUFFIX
 from lib.request import inject
-from lib.utils.xrange import xrange
 from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
 
 class Fingerprint(GenericFingerprint):
diff --git a/plugins/dbms/h2/syntax.py b/plugins/dbms/h2/syntax.py
index d991f625e..0d7cc45a7 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.utils.xrange import xrange
+from lib.core.compat import xrange
 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 d991f625e..0d7cc45a7 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.utils.xrange import xrange
+from lib.core.compat import xrange
 from plugins.generic.syntax import Syntax as GenericSyntax
 
 class Syntax(GenericSyntax):
diff --git a/plugins/dbms/maxdb/fingerprint.py b/plugins/dbms/maxdb/fingerprint.py
index 2388bf012..bb56f4bcb 100644
--- a/plugins/dbms/maxdb/fingerprint.py
+++ b/plugins/dbms/maxdb/fingerprint.py
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
 from lib.core.agent import agent
 from lib.core.common import Backend
 from lib.core.common import Format
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -16,7 +17,6 @@ from lib.core.session import setDbms
 from lib.core.settings import MAXDB_ALIASES
 from lib.request import inject
 from lib.request.connect import Connect as Request
-from lib.utils.xrange import xrange
 from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
 
 class Fingerprint(GenericFingerprint):
diff --git a/plugins/dbms/mssqlserver/enumeration.py b/plugins/dbms/mssqlserver/enumeration.py
index b3bee7134..83703a54e 100644
--- a/plugins/dbms/mssqlserver/enumeration.py
+++ b/plugins/dbms/mssqlserver/enumeration.py
@@ -17,6 +17,7 @@ from lib.core.common import safeStringFormat
 from lib.core.common import singleTimeLogMessage
 from lib.core.common import unArrayizeValue
 from lib.core.common import unsafeSQLIdentificatorNaming
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -28,7 +29,6 @@ from lib.core.enums import PAYLOAD
 from lib.core.exception import SqlmapNoneDataException
 from lib.core.settings import CURRENT_DB
 from lib.request import inject
-from lib.utils.xrange import xrange
 from plugins.generic.enumeration import Enumeration as GenericEnumeration
 from thirdparty import six
 
diff --git a/plugins/dbms/mssqlserver/filesystem.py b/plugins/dbms/mssqlserver/filesystem.py
index 0702a8932..7488fe3d1 100644
--- a/plugins/dbms/mssqlserver/filesystem.py
+++ b/plugins/dbms/mssqlserver/filesystem.py
@@ -14,6 +14,7 @@ from lib.core.common import isTechniqueAvailable
 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.data import conf
@@ -24,7 +25,6 @@ from lib.core.enums import PAYLOAD
 from lib.core.exception import SqlmapNoneDataException
 from lib.core.exception import SqlmapUnsupportedFeatureException
 from lib.request import inject
-from lib.utils.xrange import xrange
 
 from plugins.generic.filesystem import Filesystem as GenericFilesystem
 
diff --git a/plugins/dbms/mssqlserver/syntax.py b/plugins/dbms/mssqlserver/syntax.py
index 1cff5e029..a2169de3f 100644
--- a/plugins/dbms/mssqlserver/syntax.py
+++ b/plugins/dbms/mssqlserver/syntax.py
@@ -5,7 +5,7 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
-from lib.utils.xrange import xrange
+from lib.core.compat import xrange
 from plugins.generic.syntax import Syntax as GenericSyntax
 
 class Syntax(GenericSyntax):
diff --git a/plugins/dbms/mssqlserver/takeover.py b/plugins/dbms/mssqlserver/takeover.py
index cde20ca31..164821b02 100644
--- a/plugins/dbms/mssqlserver/takeover.py
+++ b/plugins/dbms/mssqlserver/takeover.py
@@ -8,10 +8,10 @@ See the file 'LICENSE' for copying permission
 import binascii
 
 from lib.core.common import Backend
+from lib.core.compat import xrange
 from lib.core.data import logger
 from lib.core.exception import SqlmapUnsupportedFeatureException
 from lib.request import inject
-from lib.utils.xrange import xrange
 from plugins.generic.takeover import Takeover as GenericTakeover
 
 class Takeover(GenericTakeover):
diff --git a/plugins/dbms/mysql/filesystem.py b/plugins/dbms/mysql/filesystem.py
index 81e80dbc8..9063a4708 100644
--- a/plugins/dbms/mysql/filesystem.py
+++ b/plugins/dbms/mysql/filesystem.py
@@ -13,6 +13,7 @@ from lib.core.common import popValue
 from lib.core.common import pushValue
 from lib.core.common import randomStr
 from lib.core.common import singleTimeWarnMessage
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -26,7 +27,6 @@ from lib.core.exception import SqlmapNoneDataException
 from lib.request import inject
 from lib.request.connect import Connect as Request
 from lib.techniques.union.use import unionUse
-from lib.utils.xrange import xrange
 from plugins.generic.filesystem import Filesystem as GenericFilesystem
 
 class Filesystem(GenericFilesystem):
diff --git a/plugins/dbms/mysql/fingerprint.py b/plugins/dbms/mysql/fingerprint.py
index cc91c50a3..aeb9ffb14 100644
--- a/plugins/dbms/mysql/fingerprint.py
+++ b/plugins/dbms/mysql/fingerprint.py
@@ -12,6 +12,7 @@ from lib.core.common import Format
 from lib.core.common import getUnicode
 from lib.core.common import hashDBRetrieve
 from lib.core.common import hashDBWrite
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -21,7 +22,6 @@ from lib.core.enums import OS
 from lib.core.session import setDbms
 from lib.core.settings import MYSQL_ALIASES
 from lib.request import inject
-from lib.utils.xrange import xrange
 from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
 
 class Fingerprint(GenericFingerprint):
diff --git a/plugins/dbms/oracle/enumeration.py b/plugins/dbms/oracle/enumeration.py
index 6825697fd..fe03da705 100644
--- a/plugins/dbms/oracle/enumeration.py
+++ b/plugins/dbms/oracle/enumeration.py
@@ -11,6 +11,7 @@ from lib.core.common import isInferenceAvailable
 from lib.core.common import isNoneValue
 from lib.core.common import isNumPosStrValue
 from lib.core.common import isTechniqueAvailable
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -21,7 +22,6 @@ from lib.core.enums import EXPECTED
 from lib.core.enums import PAYLOAD
 from lib.core.exception import SqlmapNoneDataException
 from lib.request import inject
-from lib.utils.xrange import xrange
 from plugins.generic.enumeration import Enumeration as GenericEnumeration
 
 class Enumeration(GenericEnumeration):
diff --git a/plugins/dbms/oracle/syntax.py b/plugins/dbms/oracle/syntax.py
index fd407fb59..3177b3542 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.utils.xrange import xrange
+from lib.core.compat import xrange
 from plugins.generic.syntax import Syntax as GenericSyntax
 
 class Syntax(GenericSyntax):
diff --git a/plugins/dbms/postgresql/filesystem.py b/plugins/dbms/postgresql/filesystem.py
index 0b0045e82..935afb410 100644
--- a/plugins/dbms/postgresql/filesystem.py
+++ b/plugins/dbms/postgresql/filesystem.py
@@ -8,11 +8,11 @@ See the file 'LICENSE' for copying permission
 import os
 
 from lib.core.common import randomInt
+from lib.core.compat import xrange
 from lib.core.data import logger
 from lib.core.exception import SqlmapUnsupportedFeatureException
 from lib.core.settings import LOBLKSIZE
 from lib.request import inject
-from lib.utils.xrange import xrange
 from plugins.generic.filesystem import Filesystem as GenericFilesystem
 
 class Filesystem(GenericFilesystem):
diff --git a/plugins/dbms/sybase/fingerprint.py b/plugins/dbms/sybase/fingerprint.py
index 1904f6c58..0c62f848f 100644
--- a/plugins/dbms/sybase/fingerprint.py
+++ b/plugins/dbms/sybase/fingerprint.py
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
 from lib.core.common import Backend
 from lib.core.common import Format
 from lib.core.common import unArrayizeValue
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -16,7 +17,6 @@ from lib.core.enums import OS
 from lib.core.session import setDbms
 from lib.core.settings import SYBASE_ALIASES
 from lib.request import inject
-from lib.utils.xrange import xrange
 from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
 
 class Fingerprint(GenericFingerprint):
diff --git a/plugins/dbms/sybase/syntax.py b/plugins/dbms/sybase/syntax.py
index 533d0ac2f..617afb010 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.utils.xrange import xrange
+from lib.core.compat import xrange
 from plugins.generic.syntax import Syntax as GenericSyntax
 
 class Syntax(GenericSyntax):
diff --git a/plugins/generic/filesystem.py b/plugins/generic/filesystem.py
index 497eb6964..abdb53e05 100644
--- a/plugins/generic/filesystem.py
+++ b/plugins/generic/filesystem.py
@@ -20,6 +20,7 @@ from lib.core.common import isListLike
 from lib.core.common import isStackingAvailable
 from lib.core.common import isTechniqueAvailable
 from lib.core.common import readInput
+from lib.core.compat import xrange
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -31,7 +32,6 @@ from lib.core.exception import SqlmapUndefinedMethod
 from lib.core.settings import TAKEOVER_TABLE_PREFIX
 from lib.core.settings import UNICODE_ENCODING
 from lib.request import inject
-from lib.utils.xrange import xrange
 
 class Filesystem:
     """
diff --git a/plugins/generic/users.py b/plugins/generic/users.py
index e0d7d7ff8..3708a088b 100644
--- a/plugins/generic/users.py
+++ b/plugins/generic/users.py
@@ -21,6 +21,7 @@ from lib.core.common import isTechniqueAvailable
 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.data import conf
 from lib.core.data import kb
@@ -42,7 +43,6 @@ from lib.request import inject
 from lib.utils.hash import attackCachedUsersPasswords
 from lib.utils.hash import storeHashesToFile
 from lib.utils.pivotdumptable import pivotDumpTable
-from lib.utils.xrange import xrange
 
 class Users:
     """
diff --git a/tamper/ifnull2casewhenisnull.py b/tamper/ifnull2casewhenisnull.py
index 4947da3d3..3a222cbda 100644
--- a/tamper/ifnull2casewhenisnull.py
+++ b/tamper/ifnull2casewhenisnull.py
@@ -5,8 +5,8 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
 See the file 'doc/COPYING' for copying permission
 """
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.HIGHEST
 
diff --git a/tamper/ifnull2ifisnull.py b/tamper/ifnull2ifisnull.py
index 770d6394f..eb8f61189 100644
--- a/tamper/ifnull2ifisnull.py
+++ b/tamper/ifnull2ifisnull.py
@@ -5,8 +5,8 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.HIGHEST
 
diff --git a/tamper/luanginx.py b/tamper/luanginx.py
index 308ed9a3b..fa1c6853f 100644
--- a/tamper/luanginx.py
+++ b/tamper/luanginx.py
@@ -8,10 +8,10 @@ See the file 'LICENSE' for copying permission
 import string
 import random
 
+from lib.core.compat import xrange
 from lib.core.enums import HINT
 from lib.core.enums import PRIORITY
 from lib.core.settings import DEFAULT_GET_POST_DELIMITER
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.NORMAL
 
diff --git a/tamper/plus2concat.py b/tamper/plus2concat.py
index 12dcc6ebb..776a7eec1 100644
--- a/tamper/plus2concat.py
+++ b/tamper/plus2concat.py
@@ -10,9 +10,9 @@ import re
 
 from lib.core.common import singleTimeWarnMessage
 from lib.core.common import zeroDepthSearch
+from lib.core.compat import xrange
 from lib.core.enums import DBMS
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.HIGHEST
 
diff --git a/tamper/plus2fnconcat.py b/tamper/plus2fnconcat.py
index 693443294..121549710 100644
--- a/tamper/plus2fnconcat.py
+++ b/tamper/plus2fnconcat.py
@@ -10,9 +10,9 @@ import re
 
 from lib.core.common import singleTimeWarnMessage
 from lib.core.common import zeroDepthSearch
+from lib.core.compat import xrange
 from lib.core.enums import DBMS
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.HIGHEST
 
diff --git a/tamper/randomcase.py b/tamper/randomcase.py
index c76452f7b..0819521ad 100644
--- a/tamper/randomcase.py
+++ b/tamper/randomcase.py
@@ -8,9 +8,9 @@ See the file 'LICENSE' for copying permission
 import re
 
 from lib.core.common import randomRange
+from lib.core.compat import xrange
 from lib.core.data import kb
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.NORMAL
 
diff --git a/tamper/randomcomments.py b/tamper/randomcomments.py
index 871716241..2a504d3a0 100644
--- a/tamper/randomcomments.py
+++ b/tamper/randomcomments.py
@@ -8,9 +8,9 @@ See the file 'LICENSE' for copying permission
 import re
 
 from lib.core.common import randomRange
+from lib.core.compat import xrange
 from lib.core.data import kb
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2comment.py b/tamper/space2comment.py
index 7b82b4178..e62bde276 100644
--- a/tamper/space2comment.py
+++ b/tamper/space2comment.py
@@ -5,8 +5,8 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2dash.py b/tamper/space2dash.py
index 90e941a5f..e5ab69af2 100644
--- a/tamper/space2dash.py
+++ b/tamper/space2dash.py
@@ -8,8 +8,8 @@ See the file 'LICENSE' for copying permission
 import random
 import string
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2hash.py b/tamper/space2hash.py
index 9b1aa50e6..79d8d01fd 100644
--- a/tamper/space2hash.py
+++ b/tamper/space2hash.py
@@ -10,9 +10,9 @@ import random
 import string
 
 from lib.core.common import singleTimeWarnMessage
+from lib.core.compat import xrange
 from lib.core.enums import DBMS
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2morecomment.py b/tamper/space2morecomment.py
index 848a9dae8..39048cb0e 100644
--- a/tamper/space2morecomment.py
+++ b/tamper/space2morecomment.py
@@ -5,8 +5,8 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2morehash.py b/tamper/space2morehash.py
index 93f8b43eb..81168258c 100644
--- a/tamper/space2morehash.py
+++ b/tamper/space2morehash.py
@@ -11,11 +11,11 @@ import random
 import string
 
 from lib.core.common import singleTimeWarnMessage
+from lib.core.compat import xrange
 from lib.core.data import kb
 from lib.core.enums import DBMS
 from lib.core.enums import PRIORITY
 from lib.core.settings import IGNORE_SPACE_AFFECTED_KEYWORDS
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2mssqlblank.py b/tamper/space2mssqlblank.py
index 754955f71..b78915186 100644
--- a/tamper/space2mssqlblank.py
+++ b/tamper/space2mssqlblank.py
@@ -9,9 +9,9 @@ import os
 import random
 
 from lib.core.common import singleTimeWarnMessage
+from lib.core.compat import xrange
 from lib.core.enums import DBMS
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2mssqlhash.py b/tamper/space2mssqlhash.py
index f9d6f75d0..12f793b55 100644
--- a/tamper/space2mssqlhash.py
+++ b/tamper/space2mssqlhash.py
@@ -5,8 +5,8 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2mysqlblank.py b/tamper/space2mysqlblank.py
index 83742a180..1c7cc6676 100644
--- a/tamper/space2mysqlblank.py
+++ b/tamper/space2mysqlblank.py
@@ -9,9 +9,9 @@ import os
 import random
 
 from lib.core.common import singleTimeWarnMessage
+from lib.core.compat import xrange
 from lib.core.enums import DBMS
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2mysqldash.py b/tamper/space2mysqldash.py
index 26284e051..550ea9a40 100644
--- a/tamper/space2mysqldash.py
+++ b/tamper/space2mysqldash.py
@@ -8,9 +8,9 @@ See the file 'LICENSE' for copying permission
 import os
 
 from lib.core.common import singleTimeWarnMessage
+from lib.core.compat import xrange
 from lib.core.enums import DBMS
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2plus.py b/tamper/space2plus.py
index df8ce1c87..063b6ff23 100644
--- a/tamper/space2plus.py
+++ b/tamper/space2plus.py
@@ -5,8 +5,8 @@ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/space2randomblank.py b/tamper/space2randomblank.py
index e6271cb1e..e668292b1 100644
--- a/tamper/space2randomblank.py
+++ b/tamper/space2randomblank.py
@@ -7,8 +7,8 @@ See the file 'LICENSE' for copying permission
 
 import random
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.LOW
 
diff --git a/tamper/unmagicquotes.py b/tamper/unmagicquotes.py
index cb86e7820..2f418ff6b 100644
--- a/tamper/unmagicquotes.py
+++ b/tamper/unmagicquotes.py
@@ -7,8 +7,8 @@ See the file 'LICENSE' for copying permission
 
 import re
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.NORMAL
 
diff --git a/tamper/xforwardedfor.py b/tamper/xforwardedfor.py
index 4bbbae5f4..7bcde6337 100644
--- a/tamper/xforwardedfor.py
+++ b/tamper/xforwardedfor.py
@@ -7,8 +7,8 @@ See the file 'LICENSE' for copying permission
 
 import random
 
+from lib.core.compat import xrange
 from lib.core.enums import PRIORITY
-from lib.utils.xrange import xrange
 
 __priority__ = PRIORITY.NORMAL