sqlmap/lib/core/patch.py

199 lines
6.6 KiB
Python
Raw Normal View History

2019-05-08 13:47:52 +03:00
#!/usr/bin/env python
2018-06-13 00:02:38 +03:00
"""
2024-01-04 01:11:52 +03:00
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
2018-06-13 00:02:38 +03:00
See the file 'LICENSE' for copying permission
"""
import codecs
2023-04-05 11:56:36 +03:00
import collections
2023-04-05 11:31:17 +03:00
import inspect
2020-08-23 21:56:22 +03:00
import os
2020-02-07 00:15:31 +03:00
import random
2020-12-11 00:47:29 +03:00
import re
import sys
2018-06-13 00:02:38 +03:00
2019-05-06 01:54:21 +03:00
import lib.controller.checks
import lib.core.common
import lib.core.convert
import lib.core.option
2019-06-04 15:48:51 +03:00
import lib.core.threads
2019-05-06 01:54:21 +03:00
import lib.request.connect
import lib.utils.search
2019-05-19 08:52:38 +03:00
import lib.utils.sqlalchemy
2019-05-06 01:54:21 +03:00
import thirdparty.ansistrm.ansistrm
import thirdparty.chardet.universaldetector
2019-05-06 01:54:21 +03:00
from lib.core.common import filterNone
2019-05-19 08:52:38 +03:00
from lib.core.common import getSafeExString
2019-10-07 15:20:18 +03:00
from lib.core.common import isDigit
2019-05-06 01:54:21 +03:00
from lib.core.common import isListLike
from lib.core.common import readInput
2019-05-21 15:18:14 +03:00
from lib.core.common import shellExec
2019-06-04 15:44:06 +03:00
from lib.core.common import singleTimeWarnMessage
2020-02-07 00:15:31 +03:00
from lib.core.compat import xrange
2019-05-20 12:21:31 +03:00
from lib.core.convert import stdoutEncode
from lib.core.data import conf
2020-12-11 00:47:29 +03:00
from lib.core.enums import PLACE
2019-05-06 01:54:21 +03:00
from lib.core.option import _setHTTPHandlers
from lib.core.option import setVerbosity
2024-06-05 11:38:24 +03:00
from lib.core.settings import INVALID_UNICODE_PRIVATE_AREA
from lib.core.settings import INVALID_UNICODE_CHAR_FORMAT
2018-06-13 00:02:38 +03:00
from lib.core.settings import IS_WIN
2019-06-04 15:44:06 +03:00
from lib.request.templates import getPageTemplate
from thirdparty import six
2024-06-05 11:38:24 +03:00
from thirdparty.six import unichr as _unichr
from thirdparty.six.moves import http_client as _http_client
2018-06-13 00:02:38 +03:00
2020-02-07 00:52:45 +03:00
_rand = 0
2018-06-13 00:02:38 +03:00
def dirtyPatches():
"""
Place for "dirty" Python related patches
"""
# accept overly long result lines (e.g. SQLi results in HTTP header responses)
_http_client._MAXLINE = 1 * 1024 * 1024
2018-06-13 00:02:38 +03:00
# prevent double chunked encoding in case of sqlmap chunking (Note: Python3 does it automatically if 'Content-length' is missing)
if six.PY3:
if not hasattr(_http_client.HTTPConnection, "__send_output"):
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
2020-02-07 00:15:31 +03:00
def _send_output(self, *args, **kwargs):
2020-03-17 13:10:52 +03:00
if conf.get("chunked") and "encode_chunked" in kwargs:
kwargs["encode_chunked"] = False
self.__send_output(*args, **kwargs)
_http_client.HTTPConnection._send_output = _send_output
2018-06-13 00:02:38 +03:00
# add support for inet_pton() on Windows OS
if IS_WIN:
from thirdparty.wininetpton import win_inet_pton
# Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440
codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None)
2019-03-27 18:36:32 +03:00
# Reference: http://bugs.python.org/issue17849
if hasattr(_http_client, "LineAndFileWrapper"):
def _(self, *args):
return self._readline()
_http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
_http_client.LineAndFileWrapper.readline = _
2019-05-06 01:54:21 +03:00
# to prevent too much "guessing" in case of binary data retrieval
thirdparty.chardet.universaldetector.MINIMUM_THRESHOLD = 0.90
2020-12-11 00:47:29 +03:00
match = re.search(r" --method[= ](\w+)", " ".join(sys.argv))
if match and match.group(1).upper() != PLACE.POST:
PLACE.CUSTOM_POST = PLACE.CUSTOM_POST.replace("POST", "%s (body)" % match.group(1))
2024-06-05 11:06:06 +03:00
# Reference: https://github.com/sqlmapproject/sqlmap/issues/4314
2020-08-23 21:56:22 +03:00
try:
os.urandom(1)
2020-12-31 14:17:08 +03:00
except NotImplementedError:
2020-08-23 21:56:22 +03:00
if six.PY3:
os.urandom = lambda size: bytes(random.randint(0, 255) for _ in range(size))
else:
os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))
2024-06-05 11:06:06 +03:00
# Reference: https://github.com/sqlmapproject/sqlmap/issues/5727
# Reference: https://stackoverflow.com/a/14076841
try:
import pymysql
pymysql.install_as_MySQLdb()
except (ImportError, AttributeError):
pass
2023-04-05 11:31:17 +03:00
# Reference: https://github.com/bottlepy/bottle/blob/df67999584a0e51ec5b691146c7fa4f3c87f5aac/bottle.py
2023-04-05 11:56:36 +03:00
# Reference: https://python.readthedocs.io/en/v2.7.2/library/inspect.html#inspect.getargspec
2023-04-05 11:31:17 +03:00
if not hasattr(inspect, "getargspec") and hasattr(inspect, "getfullargspec"):
2023-04-05 11:56:36 +03:00
ArgSpec = collections.namedtuple("ArgSpec", ("args", "varargs", "keywords", "defaults"))
2023-04-05 11:31:17 +03:00
def makelist(data):
if isinstance(data, (tuple, list, set, dict)):
return list(data)
elif data:
return [data]
else:
return []
def getargspec(func):
2023-04-05 11:56:36 +03:00
spec = inspect.getfullargspec(func)
2023-04-05 11:31:17 +03:00
kwargs = makelist(spec[0]) + makelist(spec.kwonlyargs)
2023-04-05 11:56:36 +03:00
return ArgSpec(kwargs, spec[1], spec[2], spec[3])
2023-04-05 11:31:17 +03:00
inspect.getargspec = getargspec
2024-06-05 11:38:24 +03:00
# Installing "reversible" unicode (decoding) error handler
def _reversible(ex):
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)
else:
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
codecs.register_error("reversible", _reversible)
2019-05-06 01:54:21 +03:00
def resolveCrossReferences():
"""
Place for cross-reference resolution
"""
2019-10-07 15:20:18 +03:00
lib.core.threads.isDigit = isDigit
2019-05-06 01:54:21 +03:00
lib.core.threads.readInput = readInput
lib.core.common.getPageTemplate = getPageTemplate
lib.core.convert.filterNone = filterNone
lib.core.convert.isListLike = isListLike
2019-05-21 15:18:14 +03:00
lib.core.convert.shellExec = shellExec
2019-05-06 01:54:21 +03:00
lib.core.convert.singleTimeWarnMessage = singleTimeWarnMessage
lib.core.option._pympTempLeakPatch = pympTempLeakPatch
2019-05-06 01:54:21 +03:00
lib.request.connect.setHTTPHandlers = _setHTTPHandlers
lib.utils.search.setHTTPHandlers = _setHTTPHandlers
lib.controller.checks.setVerbosity = setVerbosity
2019-05-19 08:52:38 +03:00
lib.utils.sqlalchemy.getSafeExString = getSafeExString
2019-05-20 12:21:31 +03:00
thirdparty.ansistrm.ansistrm.stdoutEncode = stdoutEncode
def pympTempLeakPatch(tempDir):
"""
Patch for "pymp" leaking directories inside Python3
"""
try:
import multiprocessing.util
multiprocessing.util.get_temp_dir = lambda: tempDir
except:
2019-05-09 16:47:23 +03:00
pass
2020-02-07 00:15:31 +03:00
def unisonRandom():
"""
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