This commit is contained in:
Miroslav Stampar 2017-07-03 16:55:24 +02:00
parent aef5d6667f
commit 1678b606a2
10 changed files with 230 additions and 345 deletions

View File

@ -117,7 +117,6 @@ def checkSqlInjection(place, parameter, value):
while tests:
test = tests.pop(0)
threadData.requestCollector.reset()
try:
if kb.endDetection:
@ -701,7 +700,6 @@ def checkSqlInjection(place, parameter, value):
injection.data[stype].matchRatio = kb.matchRatio
injection.data[stype].trueCode = trueCode
injection.data[stype].falseCode = falseCode
injection.data[stype].collectedRequests = threadData.requestCollector.obtain()
injection.conf.textOnly = conf.textOnly
injection.conf.titles = conf.titles

View File

@ -2601,13 +2601,11 @@ def logHTTPTraffic(requestLogMsg, responseLogMsg):
"""
Logs HTTP traffic to the output file
"""
threadData = getCurrentThreadData()
assert threadData.requestCollector is not None, "Request collector should be initialized by now"
threadData.requestCollector.collectRequest(requestLogMsg, responseLogMsg)
if conf.harFile:
conf.httpCollector.collectRequest(requestLogMsg, responseLogMsg)
if not conf.trafficFile:
return
with kb.locks.log:
dataToTrafficFile("%s%s" % (requestLogMsg, os.linesep))
dataToTrafficFile("%s%s" % (responseLogMsg, os.linesep))

View File

@ -149,7 +149,7 @@ from lib.request.pkihandler import HTTPSPKIAuthHandler
from lib.request.rangehandler import HTTPRangeHandler
from lib.request.redirecthandler import SmartRedirectHandler
from lib.request.templates import getPageTemplate
from lib.utils.collect import RequestCollectorFactory
from lib.utils.har import HTTPCollectorFactory
from lib.utils.crawler import crawl
from lib.utils.deps import checkDependencies
from lib.utils.search import search
@ -1830,6 +1830,7 @@ def _setConfAttributes():
conf.dumpPath = None
conf.hashDB = None
conf.hashDBFile = None
conf.httpCollector = None
conf.httpHeaders = []
conf.hostname = None
conf.ipv6 = False
@ -1845,7 +1846,7 @@ def _setConfAttributes():
conf.scheme = None
conf.tests = []
conf.trafficFP = None
conf.requestCollectorFactory = None
conf.HARCollectorFactory = None
conf.wFileType = None
def _setKnowledgeBaseAttributes(flushAll=True):
@ -2230,10 +2231,11 @@ def _setTrafficOutputFP():
conf.trafficFP = openFile(conf.trafficFile, "w+")
def _setupRequestCollector():
conf.requestCollectorFactory = RequestCollectorFactory(collect=conf.collectRequests)
threadData = getCurrentThreadData()
threadData.requestCollector = conf.requestCollectorFactory.create()
def _setupHTTPCollector():
if not conf.harFile:
return
conf.httpCollector = HTTPCollectorFactory(conf.harFile).create()
def _setDNSServer():
if not conf.dnsDomain:
@ -2611,7 +2613,7 @@ def init():
_setTamperingFunctions()
_setWafFunctions()
_setTrafficOutputFP()
_setupRequestCollector()
_setupHTTPCollector()
_resolveCrossReferences()
_checkWebSocket()

View File

@ -197,7 +197,6 @@ optDict = {
"binaryFields": "string",
"charset": "string",
"checkInternet": "boolean",
"collectRequests": "string",
"crawlDepth": "integer",
"crawlExclude": "string",
"csvDel": "string",
@ -206,6 +205,7 @@ optDict = {
"flushSession": "boolean",
"forms": "boolean",
"freshQueries": "boolean",
"harFile": "string",
"hexConvert": "boolean",
"outputDir": "string",
"parseErrors": "boolean",

View File

@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.1.7.2"
VERSION = "1.1.7.3"
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)

View File

@ -618,9 +618,6 @@ def cmdLineParser(argv=None):
general = OptionGroup(parser, "General", "These options can be used "
"to set some general working parameters")
#general.add_option("-x", dest="xmlFile",
# help="Dump the data into an XML file")
general.add_option("-s", dest="sessionFile",
help="Load session from a stored (.sqlite) file")
@ -632,10 +629,6 @@ def cmdLineParser(argv=None):
action="store_true",
help="Never ask for user input, use the default behaviour")
general.add_option("--collect-requests", dest="collectRequests",
action="store_true",
help="Collect requests in HAR format")
general.add_option("--binary-fields", dest="binaryFields",
help="Result fields having binary values (e.g. \"digest\")")
@ -661,8 +654,7 @@ def cmdLineParser(argv=None):
general.add_option("--eta", dest="eta",
action="store_true",
help="Display for each output the "
"estimated time of arrival")
help="Display for each output the estimated time of arrival")
general.add_option("--flush-session", dest="flushSession",
action="store_true",
@ -676,6 +668,9 @@ def cmdLineParser(argv=None):
action="store_true",
help="Ignore query results stored in session file")
general.add_option("--har", dest="harFile",
help="Log all HTTP traffic into a HAR file")
general.add_option("--hex", dest="hexConvert",
action="store_true",
help="Use DBMS hex function(s) for data retrieval")

View File

@ -1,309 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from BaseHTTPServer import BaseHTTPRequestHandler
from httplib import HTTPResponse
from StringIO import StringIO
import base64
import re
from lib.core.data import logger
from lib.core.settings import VERSION
class RequestCollectorFactory:
def __init__(self, collect=False):
self.collect = collect
def create(self):
collector = RequestCollector()
if not self.collect:
collector.collectRequest = self._noop
else:
logger.info("Request collection is enabled.")
return collector
@staticmethod
def _noop(*args, **kwargs):
pass
class RequestCollector:
def __init__(self):
self.reset()
def collectRequest(self, requestMessage, responseMessage):
self.messages.append(RawPair(requestMessage, responseMessage))
def reset(self):
self.messages = []
def obtain(self):
if self.messages:
return {"log": {
"version": "1.2",
"creator": {"name": "SQLMap", "version": VERSION},
"entries": [pair.toEntry().toDict() for pair in self.messages],
}}
class RawPair:
def __init__(self, request, response):
self.request = request
self.response = response
def toEntry(self):
return Entry(request=Request.parse(self.request),
response=Response.parse(self.response))
class Entry:
def __init__(self, request, response):
self.request = request
self.response = response
def toDict(self):
return {
"request": self.request.toDict(),
"response": self.response.toDict(),
}
class Request:
def __init__(self, method, path, httpVersion, headers, postBody=None, raw=None, comment=None):
self.method = method
self.path = path
self.httpVersion = httpVersion
self.headers = headers or {}
self.postBody = postBody
self.comment = comment
self.raw = raw
@classmethod
def parse(cls, raw):
request = HTTPRequest(raw)
return cls(method=request.command,
path=request.path,
httpVersion=request.request_version,
headers=request.headers,
postBody=request.rfile.read(),
comment=request.comment,
raw=raw)
@property
def url(self):
host = self.headers.get('Host', 'unknown')
return "http://%s%s" % (host, self.path)
def toDict(self):
out = {
"httpVersion": self.httpVersion,
"method": self.method,
"url": self.url,
"headers": [dict(name=key, value=value) for key, value in self.headers.items()],
"comment": self.comment,
}
if self.postBody:
contentType = self.headers.get('Content-Type')
out["postData"] = {
"mimeType": contentType,
"text": self.postBody,
}
return out
class Response:
extract_status = re.compile(r'\((\d{3}) (.*)\)')
def __init__(self, httpVersion, status, statusText, headers, content, raw=None, comment=None):
self.raw = raw
self.httpVersion = httpVersion
self.status = status
self.statusText = statusText
self.headers = headers
self.content = content
self.comment = comment
@classmethod
def parse(cls, raw):
altered = raw
comment = None
if altered.startswith("HTTP response ["):
io = StringIO(raw)
first_line = io.readline()
parts = cls.extract_status.search(first_line)
status_line = "HTTP/1.0 %s %s" % (parts.group(1), parts.group(2))
remain = io.read()
altered = status_line + "\n" + remain
comment = first_line
response = HTTPResponse(FakeSocket(altered))
response.begin()
return cls(httpVersion="HTTP/1.1" if response.version == 11 else "HTTP/1.0",
status=response.status,
statusText=response.reason,
headers=response.msg,
content=response.read(-1),
comment=comment,
raw=raw)
def toDict(self):
content = {
"mimeType": self.headers.get('Content-Type'),
"text": self.content,
}
binary = set(['\0', '\1'])
if any(c in binary for c in self.content):
content["encoding"] = "base64"
content["text"] = base64.b64encode(self.content)
return {
"httpVersion": self.httpVersion,
"status": self.status,
"statusText": self.statusText,
"headers": [dict(name=key, value=value) for key, value in self.headers.items()],
"content": content,
"comment": self.comment,
}
class FakeSocket:
# Original source:
# https://stackoverflow.com/questions/24728088/python-parse-http-response-string
def __init__(self, response_text):
self._file = StringIO(response_text)
def makefile(self, *args, **kwargs):
return self._file
class HTTPRequest(BaseHTTPRequestHandler):
# Original source:
# https://stackoverflow.com/questions/4685217/parse-raw-http-headers
def __init__(self, request_text):
self.comment = None
self.rfile = StringIO(request_text)
self.raw_requestline = self.rfile.readline()
if self.raw_requestline.startswith("HTTP request ["):
self.comment = self.raw_requestline
self.raw_requestline = self.rfile.readline()
self.error_code = self.error_message = None
self.parse_request()
def send_error(self, code, message):
self.error_code = code
self.error_message = message
if __name__ == '__main__':
import unittest
class RequestParseTest(unittest.TestCase):
def test_basic_request(self):
req = Request.parse("GET /test HTTP/1.0\r\n"
"Host: test\r\n"
"Connection: close")
self.assertEqual("GET", req.method)
self.assertEqual("/test", req.path)
self.assertEqual("close", req.headers['Connection'])
self.assertEqual("test", req.headers['Host'])
self.assertEqual("HTTP/1.0", req.httpVersion)
def test_with_request_as_logged_by_sqlmap(self):
raw = "HTTP request [#75]:\nPOST /create.php HTTP/1.1\nHost: 127.0.0.1\nAccept-encoding: gzip,deflate\nCache-control: no-cache\nContent-type: application/x-www-form-urlencoded; charset=utf-8\nAccept: */*\nUser-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10\nCookie: PHPSESSID=65c4a9cfbbe91f2d975d50ce5e8d1026\nContent-length: 138\nConnection: close\n\nname=test%27%29%3BSELECT%20LIKE%28%27ABCDEFG%27%2CUPPER%28HEX%28RANDOMBLOB%280.0.10000%2F2%29%29%29%29--&csrfmiddlewaretoken=594d26cfa3fad\n" # noqa
req = Request.parse(raw)
self.assertEqual("POST", req.method)
self.assertEqual("138", req.headers["Content-Length"])
self.assertIn("csrfmiddlewaretoken", req.postBody)
self.assertEqual("HTTP request [#75]:\n", req.comment)
class RequestRenderTest(unittest.TestCase):
def test_render_get_request(self):
req = Request(method="GET",
path="/test.php",
headers={"Host": "example.com", "Content-Length": "0"},
httpVersion="HTTP/1.1",
comment="Hello World")
out = req.toDict()
self.assertEqual("GET", out["method"])
self.assertEqual("http://example.com/test.php", out["url"])
self.assertIn({"name": "Host", "value": "example.com"}, out["headers"])
self.assertEqual("Hello World", out["comment"])
self.assertEqual("HTTP/1.1", out["httpVersion"])
def test_render_with_post_body(self):
req = Request(method="POST",
path="/test.php",
headers={"Host": "example.com",
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"},
httpVersion="HTTP/1.1",
postBody="name=test&csrfmiddlewaretoken=594d26cfa3fad\n")
out = req.toDict()
self.assertEqual(out["postData"], {
"mimeType": "application/x-www-form-urlencoded; charset=utf-8",
"text": "name=test&csrfmiddlewaretoken=594d26cfa3fad\n",
})
class ResponseParseTest(unittest.TestCase):
def test_parse_standard_http_response(self):
raw = "HTTP/1.1 404 Not Found\nContent-length: 518\nX-powered-by: PHP/5.6.30\nContent-encoding: gzip\nExpires: Thu, 19 Nov 1981 08:52:00 GMT\nVary: Accept-Encoding\nUri: http://127.0.0.1/\nServer: Apache/2.4.10 (Debian)\nConnection: close\nPragma: no-cache\nCache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\nDate: Fri, 23 Jun 2017 16:18:17 GMT\nContent-type: text/html; charset=UTF-8\n\n<!doctype html>\n<html>Test</html>\n" # noqa
resp = Response.parse(raw)
self.assertEqual(resp.status, 404)
self.assertEqual(resp.statusText, "Not Found")
def test_parse_response_as_logged_by_sqlmap(self):
raw = "HTTP response [#74] (200 OK):\nContent-length: 518\nX-powered-by: PHP/5.6.30\nContent-encoding: gzip\nExpires: Thu, 19 Nov 1981 08:52:00 GMT\nVary: Accept-Encoding\nUri: http://127.0.0.1/\nServer: Apache/2.4.10 (Debian)\nConnection: close\nPragma: no-cache\nCache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\nDate: Fri, 23 Jun 2017 16:18:17 GMT\nContent-type: text/html; charset=UTF-8\n\n<!doctype html>\n<html>Test</html>\n" # noqa
resp = Response.parse(raw)
self.assertEqual(resp.status, 200)
self.assertEqual(resp.statusText, "OK")
self.assertEqual(resp.headers["Content-Length"], "518")
self.assertIn("Test", resp.content)
self.assertEqual("HTTP response [#74] (200 OK):\n", resp.comment)
class ResponseRenderTest(unittest.TestCase):
def test_simple_page_encoding(self):
resp = Response(status=200, statusText="OK",
httpVersion="HTTP/1.1",
headers={"Content-Type": "text/html"},
content="<html>\n<body>Hello</body>\n</html>")
out = resp.toDict()
self.assertEqual(200, out["status"])
self.assertEqual("OK", out["statusText"])
self.assertIn({"name": "Content-Type", "value": "text/html"}, out["headers"])
self.assertEqual(out["content"], {
"mimeType": "text/html",
"text": "<html>\n<body>Hello</body>\n</html>",
})
def test_simple_body_contains_binary_data(self):
resp = Response(status=200, statusText="OK",
httpVersion="HTTP/1.1",
headers={"Content-Type": "application/octet-stream"},
content="test\0abc")
out = resp.toDict()
self.assertEqual(out["content"], {
"encoding": "base64",
"mimeType": "application/octet-stream",
"text": "dGVzdABhYmM=",
})
unittest.main(buffer=False)

194
lib/utils/har.py Normal file
View File

@ -0,0 +1,194 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
import base64
import BaseHTTPServer
import httplib
import re
import StringIO
from lib.core.data import logger
from lib.core.settings import VERSION
class HTTPCollectorFactory:
def __init__(self, harFile=False):
self.harFile = harFile
def create(self):
collector = HTTPCollector()
return collector
class HTTPCollector:
def __init__(self):
self.messages = []
def collectRequest(self, requestMessage, responseMessage):
self.messages.append(RawPair(requestMessage, responseMessage))
def obtain(self):
return {"log": {
"version": "1.2",
"creator": {"name": "sqlmap", "version": VERSION},
"entries": [pair.toEntry().toDict() for pair in self.messages],
}}
class RawPair:
def __init__(self, request, response):
self.request = request
self.response = response
def toEntry(self):
return Entry(request=Request.parse(self.request),
response=Response.parse(self.response))
class Entry:
def __init__(self, request, response):
self.request = request
self.response = response
def toDict(self):
return {
"request": self.request.toDict(),
"response": self.response.toDict(),
}
class Request:
def __init__(self, method, path, httpVersion, headers, postBody=None, raw=None, comment=None):
self.method = method
self.path = path
self.httpVersion = httpVersion
self.headers = headers or {}
self.postBody = postBody
self.comment = comment
self.raw = raw
@classmethod
def parse(cls, raw):
request = HTTPRequest(raw)
return cls(method=request.command,
path=request.path,
httpVersion=request.request_version,
headers=request.headers,
postBody=request.rfile.read(),
comment=request.comment,
raw=raw)
@property
def url(self):
host = self.headers.get("Host", "unknown")
return "http://%s%s" % (host, self.path)
def toDict(self):
out = {
"httpVersion": self.httpVersion,
"method": self.method,
"url": self.url,
"headers": [dict(name=key.capitalize(), value=value) for key, value in self.headers.items()],
"comment": self.comment,
}
if self.postBody:
contentType = self.headers.get("Content-Type")
out["postData"] = {
"mimeType": contentType,
"text": self.postBody.rstrip("\r\n"),
}
return out
class Response:
extract_status = re.compile(r'\((\d{3}) (.*)\)')
def __init__(self, httpVersion, status, statusText, headers, content, raw=None, comment=None):
self.raw = raw
self.httpVersion = httpVersion
self.status = status
self.statusText = statusText
self.headers = headers
self.content = content
self.comment = comment
@classmethod
def parse(cls, raw):
altered = raw
comment = None
if altered.startswith("HTTP response ["):
io = StringIO.StringIO(raw)
first_line = io.readline()
parts = cls.extract_status.search(first_line)
status_line = "HTTP/1.0 %s %s" % (parts.group(1), parts.group(2))
remain = io.read()
altered = status_line + "\n" + remain
comment = first_line
response = httplib.HTTPResponse(FakeSocket(altered))
response.begin()
try:
content = response.read(-1)
except httplib.IncompleteRead:
content = raw[raw.find("\n\n") + 2:].rstrip("\r\n")
return cls(httpVersion="HTTP/1.1" if response.version == 11 else "HTTP/1.0",
status=response.status,
statusText=response.reason,
headers=response.msg,
content=content,
comment=comment,
raw=raw)
def toDict(self):
content = {
"mimeType": self.headers.get("Content-Type"),
"text": self.content,
}
binary = set(['\0', '\1'])
if any(c in binary for c in self.content):
content["encoding"] = "base64"
content["text"] = base64.b64encode(self.content)
return {
"httpVersion": self.httpVersion,
"status": self.status,
"statusText": self.statusText,
"headers": [dict(name=key.capitalize(), value=value) for key, value in self.headers.items() if key.lower() != "uri"],
"content": content,
"comment": self.comment,
}
class FakeSocket:
# Original source:
# https://stackoverflow.com/questions/24728088/python-parse-http-response-string
def __init__(self, response_text):
self._file = StringIO.StringIO(response_text)
def makefile(self, *args, **kwargs):
return self._file
class HTTPRequest(BaseHTTPServer.BaseHTTPRequestHandler):
# Original source:
# https://stackoverflow.com/questions/4685217/parse-raw-http-headers
def __init__(self, request_text):
self.comment = None
self.rfile = StringIO.StringIO(request_text)
self.raw_requestline = self.rfile.readline()
if self.raw_requestline.startswith("HTTP request ["):
self.comment = self.raw_requestline
self.raw_requestline = self.rfile.readline()
self.error_code = self.error_message = None
self.parse_request()
def send_error(self, code, message):
self.error_code = code
self.error_message = message

View File

@ -15,6 +15,7 @@ import bdb
import distutils
import glob
import inspect
import json
import logging
import os
import re
@ -40,6 +41,7 @@ try:
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import maskSensitiveData
from lib.core.common import openFile
from lib.core.common import setPaths
from lib.core.common import weAreFrozen
from lib.core.data import cmdLineOptions
@ -327,6 +329,10 @@ def main():
except KeyboardInterrupt:
pass
if conf.harFile:
with openFile(conf.harFile, "w+b") as f:
f.write(json.dumps(conf.httpCollector.obtain(), indent=4, separators=(',', ': ')))
if cmdLineOptions.get("sqlmapShell"):
cmdLineOptions.clear()
conf.clear()

View File

@ -27,7 +27,7 @@ a97df93b552ee4e4ba3692eae870de7c lib/controller/handler.py
310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py
d58e85ffeac2471ef3af729076b3b5f7 lib/core/agent.py
6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py
d9a450dec19787649e0265b68956f020 lib/core/common.py
d40de0812b667b7be9d1755f82e18f17 lib/core/common.py
5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py
a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py
7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py
@ -39,25 +39,25 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py
9381a0c7e8bc19986299e84f4edda1a0 lib/core/exception.py
310efc965c862cfbd7b0da5150a5ad36 lib/core/__init__.py
9ba39bf66e9ecd469446bdbbeda906c3 lib/core/log.py
f1531be15ed98555a9010e2db3c9da75 lib/core/optiondict.py
0ff0d360c02b4b92293aa7e5ee705d49 lib/core/option.py
5a34a1be62eab520cacc197b5eacda39 lib/core/optiondict.py
837f3859f007b9104b32f18e217e326a lib/core/option.py
5f2f56e6c5f274408df61943f1e080c0 lib/core/profiling.py
40be71cd774662a7b420caeb7051e7d5 lib/core/readlineng.py
d8e9250f3775119df07e9070eddccd16 lib/core/replication.py
785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py
40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py
77c9531dcb52345e86c07e1973859e79 lib/core/settings.py
191a4cb7eea0a46315c894abd9491bcf lib/core/settings.py
d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py
2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py
baa3f47efa6701076d026e43a6874a51 lib/core/target.py
8970b88627902239d695280b1160e16c lib/core/testing.py
40881e63d516d8304fc19971049cded0 lib/core/threads.py
b8306192d980abdc8d669c024511e9a1 lib/core/threads.py
ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py
1f1fa616b5b19308d78c610ec8046399 lib/core/update.py
4d13ed693401a498b6d073a2a494bd83 lib/core/wordlist.py
310efc965c862cfbd7b0da5150a5ad36 lib/__init__.py
8c4b04062db2245d9e190b413985202a lib/parse/banner.py
89c837c3b2cb2853839e127978bed8a6 lib/parse/cmdline.py
0557c5fee58f2578e0dd502b1839e3a3 lib/parse/cmdline.py
3a31657bc38f277d0016ff6d50bde61f lib/parse/configfile.py
14539f1be714d4f1ed042067d63bc50a lib/parse/handler.py
64e5bb3ecbdd75144500588b437ba8da lib/parse/headers.py
@ -103,6 +103,7 @@ a73c3ddd0de359507a8ad59b363aa963 lib/utils/api.py
ed70f1ca9113664043ec9e6778e48078 lib/utils/crawler.py
ba12c69a90061aa14d848b8396e79191 lib/utils/deps.py
3b9fd519164e0bf275d5fd361c3f11ff lib/utils/getch.py
3b93150eea78ea84fa0461a55e3e48ec lib/utils/har.py
ccfdad414ce2ec0c394c3deaa39a82bf lib/utils/hashdb.py
12e0e0ab70c6fe5786bc561c35dc067f lib/utils/hash.py
e76a08237ee6a4cd6855af79610ea8a5 lib/utils/htmlentities.py
@ -223,7 +224,7 @@ c3cc8b7727161e64ab59f312c33b541a shell/stager.aspx_
1f7f125f30e0e800beb21e2ebbab18e1 shell/stager.jsp_
01e3505e796edf19aad6a996101c81c9 shell/stager.php_
0751a45ac4c130131f2cdb74d866b664 sqlmapapi.py
c056277de4394bed29f35b74ffc4d209 sqlmap.py
290b98e6923960e17bdef3db0a05b44c sqlmap.py
08c711a470d7e0bf705320ba3c48b886 tamper/apostrophemask.py
e8509df10d3f1c28014d7825562d32dd tamper/apostrophenullencode.py
bb27f7dc980ea07fcfedbd7da5e5e029 tamper/appendnullbyte.py