Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/lib/core/patch.py
3553 views
1
#!/usr/bin/env python
2
3
"""
4
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
5
See the file 'LICENSE' for copying permission
6
"""
7
8
import codecs
9
import collections
10
import inspect
11
import logging
12
import os
13
import random
14
import re
15
import sys
16
17
import lib.controller.checks
18
import lib.core.common
19
import lib.core.convert
20
import lib.core.option
21
import lib.core.threads
22
import lib.request.connect
23
import lib.utils.search
24
import lib.utils.sqlalchemy
25
import thirdparty.ansistrm.ansistrm
26
import thirdparty.chardet.universaldetector
27
28
from lib.core.common import filterNone
29
from lib.core.common import getSafeExString
30
from lib.core.common import isDigit
31
from lib.core.common import isListLike
32
from lib.core.common import readInput
33
from lib.core.common import shellExec
34
from lib.core.common import singleTimeWarnMessage
35
from lib.core.compat import xrange
36
from lib.core.convert import stdoutEncode
37
from lib.core.data import conf
38
from lib.core.enums import PLACE
39
from lib.core.option import _setHTTPHandlers
40
from lib.core.option import setVerbosity
41
from lib.core.settings import INVALID_UNICODE_PRIVATE_AREA
42
from lib.core.settings import INVALID_UNICODE_CHAR_FORMAT
43
from lib.core.settings import IS_WIN
44
from lib.request.templates import getPageTemplate
45
from thirdparty import six
46
from thirdparty.six import unichr as _unichr
47
from thirdparty.six.moves import http_client as _http_client
48
49
_rand = 0
50
51
def dirtyPatches():
52
"""
53
Place for "dirty" Python related patches
54
"""
55
56
# accept overly long result lines (e.g. SQLi results in HTTP header responses)
57
_http_client._MAXLINE = 1 * 1024 * 1024
58
59
# prevent double chunked encoding in case of sqlmap chunking (Note: Python3 does it automatically if 'Content-length' is missing)
60
if six.PY3:
61
if not hasattr(_http_client.HTTPConnection, "__send_output"):
62
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
63
64
def _send_output(self, *args, **kwargs):
65
if conf.get("chunked") and "encode_chunked" in kwargs:
66
kwargs["encode_chunked"] = False
67
self.__send_output(*args, **kwargs)
68
69
_http_client.HTTPConnection._send_output = _send_output
70
71
# add support for inet_pton() on Windows OS
72
if IS_WIN:
73
from thirdparty.wininetpton import win_inet_pton
74
75
# Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440
76
codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None)
77
78
# Reference: http://bugs.python.org/issue17849
79
if hasattr(_http_client, "LineAndFileWrapper"):
80
def _(self, *args):
81
return self._readline()
82
83
_http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
84
_http_client.LineAndFileWrapper.readline = _
85
86
# to prevent too much "guessing" in case of binary data retrieval
87
thirdparty.chardet.universaldetector.MINIMUM_THRESHOLD = 0.90
88
89
match = re.search(r" --method[= ](\w+)", " ".join(sys.argv))
90
if match and match.group(1).upper() != PLACE.POST:
91
PLACE.CUSTOM_POST = PLACE.CUSTOM_POST.replace("POST", "%s (body)" % match.group(1))
92
93
# Reference: https://github.com/sqlmapproject/sqlmap/issues/4314
94
try:
95
os.urandom(1)
96
except NotImplementedError:
97
if six.PY3:
98
os.urandom = lambda size: bytes(random.randint(0, 255) for _ in range(size))
99
else:
100
os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))
101
102
# Reference: https://github.com/sqlmapproject/sqlmap/issues/5929
103
try:
104
import collections
105
if not hasattr(collections, "MutableSet"):
106
import collections.abc
107
collections.MutableSet = collections.abc.MutableSet
108
except ImportError:
109
pass
110
111
# Reference: https://github.com/sqlmapproject/sqlmap/issues/5727
112
# Reference: https://stackoverflow.com/a/14076841
113
try:
114
import pymysql
115
pymysql.install_as_MySQLdb()
116
except (ImportError, AttributeError):
117
pass
118
119
# Reference: https://github.com/bottlepy/bottle/blob/df67999584a0e51ec5b691146c7fa4f3c87f5aac/bottle.py
120
# Reference: https://python.readthedocs.io/en/v2.7.2/library/inspect.html#inspect.getargspec
121
if not hasattr(inspect, "getargspec") and hasattr(inspect, "getfullargspec"):
122
ArgSpec = collections.namedtuple("ArgSpec", ("args", "varargs", "keywords", "defaults"))
123
124
def makelist(data):
125
if isinstance(data, (tuple, list, set, dict)):
126
return list(data)
127
elif data:
128
return [data]
129
else:
130
return []
131
132
def getargspec(func):
133
spec = inspect.getfullargspec(func)
134
kwargs = makelist(spec[0]) + makelist(spec.kwonlyargs)
135
return ArgSpec(kwargs, spec[1], spec[2], spec[3])
136
137
inspect.getargspec = getargspec
138
139
# Installing "reversible" unicode (decoding) error handler
140
def _reversible(ex):
141
if INVALID_UNICODE_PRIVATE_AREA:
142
return (u"".join(_unichr(int('000f00%02x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
143
else:
144
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
145
146
codecs.register_error("reversible", _reversible)
147
148
# Reference: https://github.com/sqlmapproject/sqlmap/issues/5731
149
if not hasattr(logging, "_acquireLock"):
150
def _acquireLock():
151
if logging._lock:
152
logging._lock.acquire()
153
154
logging._acquireLock = _acquireLock
155
156
if not hasattr(logging, "_releaseLock"):
157
def _releaseLock():
158
if logging._lock:
159
logging._lock.release()
160
161
logging._releaseLock = _releaseLock
162
163
from xml.etree import ElementTree as et
164
if not getattr(et, "_patched", False):
165
_real_parse = et.parse
166
167
def _safe_parse(source, parser=None):
168
if parser is None:
169
parser = et.XMLParser()
170
if hasattr(parser, "parser"):
171
def reject(*args): raise ValueError("XML entities are forbidden")
172
parser.parser.EntityDeclHandler = reject
173
parser.parser.UnparsedEntityDeclHandler = reject
174
175
return _real_parse(source, parser=parser)
176
177
et.parse = _safe_parse
178
et._patched = True
179
180
def resolveCrossReferences():
181
"""
182
Place for cross-reference resolution
183
"""
184
185
lib.core.threads.isDigit = isDigit
186
lib.core.threads.readInput = readInput
187
lib.core.common.getPageTemplate = getPageTemplate
188
lib.core.convert.filterNone = filterNone
189
lib.core.convert.isListLike = isListLike
190
lib.core.convert.shellExec = shellExec
191
lib.core.convert.singleTimeWarnMessage = singleTimeWarnMessage
192
lib.core.option._pympTempLeakPatch = pympTempLeakPatch
193
lib.request.connect.setHTTPHandlers = _setHTTPHandlers
194
lib.utils.search.setHTTPHandlers = _setHTTPHandlers
195
lib.controller.checks.setVerbosity = setVerbosity
196
lib.utils.sqlalchemy.getSafeExString = getSafeExString
197
thirdparty.ansistrm.ansistrm.stdoutEncode = stdoutEncode
198
199
def pympTempLeakPatch(tempDir):
200
"""
201
Patch for "pymp" leaking directories inside Python3
202
"""
203
204
try:
205
import multiprocessing.util
206
multiprocessing.util.get_temp_dir = lambda: tempDir
207
except:
208
pass
209
210
def unisonRandom():
211
"""
212
Unifying random generated data across different Python versions
213
"""
214
215
def _lcg():
216
global _rand
217
a = 1140671485
218
c = 128201163
219
m = 2 ** 24
220
_rand = (a * _rand + c) % m
221
return _rand
222
223
def _randint(a, b):
224
_ = a + (_lcg() % (b - a + 1))
225
return _
226
227
def _choice(seq):
228
return seq[_randint(0, len(seq) - 1)]
229
230
def _sample(population, k):
231
return [_choice(population) for _ in xrange(k)]
232
233
def _seed(seed):
234
global _rand
235
_rand = seed
236
237
random.choice = _choice
238
random.randint = _randint
239
random.sample = _sample
240
random.seed = _seed
241
242