From 614f290217324f41474951c6e9b2130bab32788c Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Tue, 4 Jul 2017 12:14:17 +0200 Subject: [PATCH 01/12] Update for #2597 --- lib/core/common.py | 4 +-- lib/core/settings.py | 2 +- lib/request/connect.py | 44 +++++++++++++++++---------------- lib/request/redirecthandler.py | 10 +++++--- lib/utils/har.py | 45 ++++++++++++++++++++++++---------- txt/checksum.md5 | 10 ++++---- 6 files changed, 69 insertions(+), 46 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index 2446dcd63..c308d2bac 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -2597,13 +2597,13 @@ def runningAsAdmin(): return isAdmin -def logHTTPTraffic(requestLogMsg, responseLogMsg): +def logHTTPTraffic(requestLogMsg, responseLogMsg, startTime=None, endTime=None): """ Logs HTTP traffic to the output file """ if conf.harFile: - conf.httpCollector.collectRequest(requestLogMsg, responseLogMsg) + conf.httpCollector.collectRequest(requestLogMsg, responseLogMsg, startTime, endTime) if not conf.trafficFile: with kb.locks.log: diff --git a/lib/core/settings.py b/lib/core/settings.py index f1773e695..82f82950c 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.3" +VERSION = "1.1.7.4" 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/request/connect.py b/lib/request/connect.py index 23b6b44ab..81977ec51 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -223,6 +223,8 @@ class Connect(object): the target URL page content """ + start = time.time() + if isinstance(conf.delay, (int, float)) and conf.delay > 0: time.sleep(conf.delay) @@ -288,7 +290,7 @@ class Connect(object): status = None _ = urlparse.urlsplit(url) - requestMsg = u"HTTP request [#%d]:\n%s " % (threadData.lastRequestUID, method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET)) + requestMsg = u"HTTP request [#%d]:\r\n%s " % (threadData.lastRequestUID, method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET)) requestMsg += getUnicode(("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else "")) if not any((refreshing, crawling, checking)) else url) responseMsg = u"HTTP response " requestHeaders = u"" @@ -413,13 +415,13 @@ class Connect(object): responseHeaders = _(ws.getheaders()) responseHeaders.headers = ["%s: %s\r\n" % (_[0].capitalize(), _[1]) for _ in responseHeaders.items()] - requestHeaders += "\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) - requestMsg += "\n%s" % requestHeaders + requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) + requestMsg += "\r\n%s" % requestHeaders if post is not None: - requestMsg += "\n\n%s" % getUnicode(post) + requestMsg += "\r\n\r\n%s" % getUnicode(post) - requestMsg += "\n" + requestMsg += "\r\n" threadData.lastRequestMsg = requestMsg @@ -432,26 +434,26 @@ class Connect(object): else: req = urllib2.Request(url, post, headers) - requestHeaders += "\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in req.header_items()]) + requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in req.header_items()]) if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj: conf.cj._policy._now = conf.cj._now = int(time.time()) cookies = conf.cj._cookies_for_request(req) - requestHeaders += "\n%s" % ("Cookie: %s" % ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in cookies)) + requestHeaders += "\r\n%s" % ("Cookie: %s" % ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in cookies)) if post is not None: if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH): - requestHeaders += "\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post)) + requestHeaders += "\r\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post)) if not getRequestHeader(req, HTTP_HEADER.CONNECTION): - requestHeaders += "\n%s: %s" % (HTTP_HEADER.CONNECTION, "close" if not conf.keepAlive else "keep-alive") + requestHeaders += "\r\n%s: %s" % (HTTP_HEADER.CONNECTION, "close" if not conf.keepAlive else "keep-alive") - requestMsg += "\n%s" % requestHeaders + requestMsg += "\r\n%s" % requestHeaders if post is not None: - requestMsg += "\n\n%s" % getUnicode(post) + requestMsg += "\r\n\r\n%s" % getUnicode(post) - requestMsg += "\n" + requestMsg += "\r\n" if not multipart: threadData.lastRequestMsg = requestMsg @@ -576,19 +578,19 @@ class Connect(object): threadData.lastHTTPError = (threadData.lastRequestUID, code, status) kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1 - responseMsg += "[#%d] (%d %s):\n" % (threadData.lastRequestUID, code, status) + responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status) if responseHeaders: - logHeaders = "\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) + logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) - logHTTPTraffic(requestMsg, "%s%s\n\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE])) + logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time()) skipLogTraffic = True if conf.verbose <= 5: responseMsg += getUnicode(logHeaders) elif conf.verbose > 5: - responseMsg += "%s\n\n%s" % (logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]) + responseMsg += "%s\r\n\r\n%s" % (logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]) if not multipart: logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg) @@ -736,20 +738,20 @@ class Connect(object): requestMsg = re.sub("(?i)Content-length: \d+\n", "", requestMsg) requestMsg = re.sub("(?s)\n\n.+", "\n", requestMsg) - responseMsg += "[#%d] (%d %s):\n" % (threadData.lastRequestUID, conn.code, status) + responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, conn.code, status) else: - responseMsg += "[#%d] (%d %s):\n" % (threadData.lastRequestUID, code, status) + responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status) if responseHeaders: - logHeaders = "\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) + logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) if not skipLogTraffic: - logHTTPTraffic(requestMsg, "%s%s\n\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE])) + logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time()) if conf.verbose <= 5: responseMsg += getUnicode(logHeaders) elif conf.verbose > 5: - responseMsg += "%s\n\n%s" % (logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]) + responseMsg += "%s\r\n\r\n%s" % (logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]) if not multipart: logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg) diff --git a/lib/request/redirecthandler.py b/lib/request/redirecthandler.py index a6e560bcf..4dca0f113 100644 --- a/lib/request/redirecthandler.py +++ b/lib/request/redirecthandler.py @@ -6,6 +6,7 @@ See the file 'doc/COPYING' for copying permission """ import re +import time import types import urllib2 import urlparse @@ -69,6 +70,7 @@ class SmartRedirectHandler(urllib2.HTTPRedirectHandler): return urllib2.Request(newurl, data=req.data, headers=req.headers, origin_req_host=req.get_origin_req_host()) def http_error_302(self, req, fp, code, msg, headers): + start = time.time() content = None redurl = self._get_header_redirect(headers) if not conf.ignoreRedirects else None @@ -92,18 +94,18 @@ class SmartRedirectHandler(urllib2.HTTPRedirectHandler): threadData.lastRedirectMsg = (threadData.lastRequestUID, content) redirectMsg = "HTTP redirect " - redirectMsg += "[#%d] (%d %s):\n" % (threadData.lastRequestUID, code, getUnicode(msg)) + redirectMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, getUnicode(msg)) if headers: - logHeaders = "\n".join("%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in headers.items()) + logHeaders = "\r\n".join("%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in headers.items()) else: logHeaders = "" redirectMsg += logHeaders if content: - redirectMsg += "\n\n%s" % getUnicode(content[:MAX_CONNECTION_CHUNK_SIZE]) + redirectMsg += "\r\n\r\n%s" % getUnicode(content[:MAX_CONNECTION_CHUNK_SIZE]) - logHTTPTraffic(threadData.lastRequestMsg, redirectMsg) + logHTTPTraffic(threadData.lastRequestMsg, redirectMsg, start, time.time()) logger.log(CUSTOM_LOGGING.TRAFFIC_IN, redirectMsg) if redurl: diff --git a/lib/utils/har.py b/lib/utils/har.py index 5630ec4d2..53f6184ab 100644 --- a/lib/utils/har.py +++ b/lib/utils/har.py @@ -7,28 +7,31 @@ See the file 'doc/COPYING' for copying permission import base64 import BaseHTTPServer +import datetime import httplib import re import StringIO +import time from lib.core.data import logger from lib.core.settings import VERSION +# Reference: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html +# http://www.softwareishard.com/har/viewer/ + class HTTPCollectorFactory: def __init__(self, harFile=False): self.harFile = harFile def create(self): - collector = HTTPCollector() - - return collector + return HTTPCollector() class HTTPCollector: def __init__(self): self.messages = [] - def collectRequest(self, requestMessage, responseMessage): - self.messages.append(RawPair(requestMessage, responseMessage)) + def collectRequest(self, requestMessage, responseMessage, startTime=None, endTime=None): + self.messages.append(RawPair(requestMessage, responseMessage, startTime, endTime)) def obtain(self): return {"log": { @@ -38,23 +41,30 @@ class HTTPCollector: }} class RawPair: - def __init__(self, request, response): + def __init__(self, request, response, startTime=None, endTime=None): self.request = request self.response = response + self.startTime = startTime + self.endTime = endTime def toEntry(self): - return Entry(request=Request.parse(self.request), - response=Response.parse(self.response)) + return Entry(request=Request.parse(self.request), response=Response.parse(self.response), startTime=self.startTime, endTime=self.endTime) class Entry: - def __init__(self, request, response): + def __init__(self, request, response, startTime, endTime): self.request = request self.response = response + self.startTime = startTime or 0 + self.endTime = endTime or 0 def toDict(self): return { "request": self.request.toDict(), "response": self.response.toDict(), + "cache": {}, + "timings": [], + "time": int(1000 * (self.endTime - self.startTime)), + "startedDateTime": "%s%s" % (datetime.datetime.fromtimestamp(self.startTime).isoformat(), time.strftime("%z")) if self.startTime else None } class Request: @@ -64,7 +74,7 @@ class Request: self.httpVersion = httpVersion self.headers = headers or {} self.postBody = postBody - self.comment = comment + self.comment = comment.strip() if comment else comment self.raw = raw @classmethod @@ -89,6 +99,10 @@ class Request: "method": self.method, "url": self.url, "headers": [dict(name=key.capitalize(), value=value) for key, value in self.headers.items()], + "cookies": [], + "queryString": [], + "headersSize": -1, + "bodySize": -1, "comment": self.comment, } @@ -111,7 +125,7 @@ class Response: self.statusText = statusText self.headers = headers self.content = content - self.comment = comment + self.comment = comment.strip() if comment else comment @classmethod def parse(cls, raw): @@ -124,7 +138,7 @@ class Response: 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 + altered = status_line + "\r\n" + remain comment = first_line response = httplib.HTTPResponse(FakeSocket(altered)) @@ -133,7 +147,7 @@ class Response: try: content = response.read(-1) except httplib.IncompleteRead: - content = raw[raw.find("\n\n") + 2:].rstrip("\r\n") + content = raw[raw.find("\r\n\r\n") + 4:].rstrip("\r\n") return cls(httpVersion="HTTP/1.1" if response.version == 11 else "HTTP/1.0", status=response.status, @@ -147,6 +161,7 @@ class Response: content = { "mimeType": self.headers.get("Content-Type"), "text": self.content, + "size": len(self.content or "") } binary = set(['\0', '\1']) @@ -159,7 +174,11 @@ class Response: "status": self.status, "statusText": self.statusText, "headers": [dict(name=key.capitalize(), value=value) for key, value in self.headers.items() if key.lower() != "uri"], + "cookies": [], "content": content, + "headersSize": -1, + "bodySize": -1, + "redirectURL": "", "comment": self.comment, } diff --git a/txt/checksum.md5 b/txt/checksum.md5 index c3dacbf10..82105e3a3 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -27,7 +27,7 @@ a97df93b552ee4e4ba3692eae870de7c lib/controller/handler.py 310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py d58e85ffeac2471ef3af729076b3b5f7 lib/core/agent.py 6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py -d40de0812b667b7be9d1755f82e18f17 lib/core/common.py +ebf31aa9c5af54188e999719593e8ba4 lib/core/common.py 5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py 7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -191a4cb7eea0a46315c894abd9491bcf lib/core/settings.py +4538abe3e7f78f73fe3cd85dc4715e7f lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py baa3f47efa6701076d026e43a6874a51 lib/core/target.py @@ -68,7 +68,7 @@ ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py 403d873f1d2fd0c7f73d83f104e41850 lib/request/basicauthhandler.py 3ba1c71e68953d34fc526a9d79d5a457 lib/request/basic.py ef48de622b0a6b4a71df64b0d2785ef8 lib/request/comparison.py -4b056460279e65eef5f4f4fe293e657b lib/request/connect.py +bfd08465f7bc259cc9af008da0ffb4c3 lib/request/connect.py fb6b788d0016ab4ec5e5f661f0f702ad lib/request/direct.py cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py 5dcdb37823a0b5eff65cd1018bcf09e4 lib/request/httpshandler.py @@ -77,7 +77,7 @@ cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py dc1e0af84ee8eb421797d61c8cb8f172 lib/request/methodrequest.py bb9c165b050f7696b089b96b5947fac3 lib/request/pkihandler.py 602d4338a9fceaaee40c601410d8ac0b lib/request/rangehandler.py -111b3ee936f23167b5654a5f72e9731b lib/request/redirecthandler.py +3ba71e1571d105386d4d30746f5d6ab2 lib/request/redirecthandler.py b373770137dc885889e495de95169b93 lib/request/templates.py 992a02767d12254784f15501a7ab8dd8 lib/takeover/abstraction.py c6bc7961a186baabe0a9f5b7e0d8974b lib/takeover/icmpsh.py @@ -103,7 +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 +40e987b76120f0327f891d1cc7866f4e lib/utils/har.py ccfdad414ce2ec0c394c3deaa39a82bf lib/utils/hashdb.py 12e0e0ab70c6fe5786bc561c35dc067f lib/utils/hash.py e76a08237ee6a4cd6855af79610ea8a5 lib/utils/htmlentities.py From ba369b73d3aac831c64640ddf5e23469b85c2dee Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 11:31:42 +0200 Subject: [PATCH 02/12] Fixes #2601 --- lib/core/settings.py | 2 +- plugins/dbms/oracle/enumeration.py | 2 +- plugins/generic/users.py | 2 +- txt/checksum.md5 | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index 82f82950c..9f2badec3 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.4" +VERSION = "1.1.7.5" 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/plugins/dbms/oracle/enumeration.py b/plugins/dbms/oracle/enumeration.py index 0cc0059c7..8c619cecc 100644 --- a/plugins/dbms/oracle/enumeration.py +++ b/plugins/dbms/oracle/enumeration.py @@ -67,7 +67,7 @@ class Enumeration(GenericEnumeration): user = None roles = set() - for count in xrange(0, len(value)): + for count in xrange(0, len(value or [])): # The first column is always the username if count == 0: user = value[count] diff --git a/plugins/generic/users.py b/plugins/generic/users.py index b09169dff..a6c8be7c7 100644 --- a/plugins/generic/users.py +++ b/plugins/generic/users.py @@ -393,7 +393,7 @@ class Users: user = None privileges = set() - for count in xrange(0, len(value)): + for count in xrange(0, len(value or [])): # The first column is always the username if count == 0: user = value[count] diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 82105e3a3..709bca709 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -4538abe3e7f78f73fe3cd85dc4715e7f lib/core/settings.py +ab9636352fc61fcb89683d45b2f895e8 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py baa3f47efa6701076d026e43a6874a51 lib/core/target.py @@ -174,7 +174,7 @@ e43fda42decf2a70bad470b884674fbe plugins/dbms/mysql/fingerprint.py 96dfafcc4aecc1c574148ac05dbdb6da plugins/dbms/mysql/syntax.py 33b2dc28075ab560fd8a4dc898682a0d plugins/dbms/mysql/takeover.py ea4b9cd238075b79945bd2607810934a plugins/dbms/oracle/connector.py -73fc1502dff934f008e3e2590b2609e7 plugins/dbms/oracle/enumeration.py +0471e3bf8310064e28e7c36064056e8d plugins/dbms/oracle/enumeration.py dc5962a1d4d69d4206b6c03e00e7f33d plugins/dbms/oracle/filesystem.py 525381f48505095b14e567c1f59ca9c7 plugins/dbms/oracle/fingerprint.py 25a99a9dd7072b6b7346438599c78050 plugins/dbms/oracle/__init__.py @@ -213,7 +213,7 @@ deed74334b637767fc9de8f74b37647a plugins/dbms/sybase/fingerprint.py 070f58c52e2a04e7a9896b42b2d17dc2 plugins/generic/search.py 562cfa80a15d5f7f1d52e10c5736d7e2 plugins/generic/syntax.py fca9946e960942cc9b22ef26e12b8b3a plugins/generic/takeover.py -bc0b47ced3db9f6746966d8dfc423b56 plugins/generic/users.py +f97b84b8dcbe80b2d86bc26829aed23b plugins/generic/users.py 310efc965c862cfbd7b0da5150a5ad36 plugins/__init__.py b04db3e861edde1f9dd0a3850d5b96c8 shell/backdoor.asp_ 158bfa168128393dde8d6ed11fe9a1b8 shell/backdoor.aspx_ From a4ebd5418fb9c2936680e6c488e7fcf3b85331b5 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 12:15:14 +0200 Subject: [PATCH 03/12] Patch for an Issue reported privately via email --- lib/core/settings.py | 2 +- lib/request/inject.py | 6 +++++- txt/checksum.md5 | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index 9f2badec3..51bf04014 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.5" +VERSION = "1.1.7.6" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) diff --git a/lib/request/inject.py b/lib/request/inject.py index c51cdb735..baa946949 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -345,6 +345,10 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser kb.safeCharEncode = safeCharEncode kb.resumeValues = resumeValue + # Note: following keywords are expected to be in uppercase + for keyword in ("SELECT", "FROM", "WHERE"): + expression = re.sub("(?i)(\A|\(|\)|\s)%s(\Z|\(|\)|\s)" % keyword, r"\g<1>%s\g<2>" % keyword, expression) + if suppressOutput is not None: pushValue(getCurrentThreadData().disableStdOut) getCurrentThreadData().disableStdOut = suppressOutput @@ -356,7 +360,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser if expected == EXPECTED.BOOL: forgeCaseExpression = booleanExpression = expression - if expression.upper().startswith("SELECT "): + if expression.startswith("SELECT "): booleanExpression = "(%s)=%s" % (booleanExpression, "'1'" if "'1'" in booleanExpression else "1") else: forgeCaseExpression = agent.forgeCaseStatement(expression) diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 709bca709..5eef9f66b 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -ab9636352fc61fcb89683d45b2f895e8 lib/core/settings.py +7d6af4ab9aa4b6c10cefe0062409a228 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py baa3f47efa6701076d026e43a6874a51 lib/core/target.py @@ -73,7 +73,7 @@ fb6b788d0016ab4ec5e5f661f0f702ad lib/request/direct.py cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py 5dcdb37823a0b5eff65cd1018bcf09e4 lib/request/httpshandler.py 310efc965c862cfbd7b0da5150a5ad36 lib/request/__init__.py -70ec3f5bce37cdd7bf085ba2ddda30ac lib/request/inject.py +62b01fc81e0ee708d1b92add612f659e lib/request/inject.py dc1e0af84ee8eb421797d61c8cb8f172 lib/request/methodrequest.py bb9c165b050f7696b089b96b5947fac3 lib/request/pkihandler.py 602d4338a9fceaaee40c601410d8ac0b lib/request/rangehandler.py From 4a4fa07bdd718a0ea7a55f84b1301504a2968b6e Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 12:35:48 +0200 Subject: [PATCH 04/12] Minor update --- lib/core/settings.py | 5 ++++- lib/request/inject.py | 6 +++--- txt/checksum.md5 | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index 51bf04014..545fc29c9 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.6" +VERSION = "1.1.7.7" 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) @@ -453,6 +453,9 @@ LOW_TEXT_PERCENT = 20 # Reference: http://dev.mysql.com/doc/refman/5.1/en/function-resolution.html IGNORE_SPACE_AFFECTED_KEYWORDS = ("CAST", "COUNT", "EXTRACT", "GROUP_CONCAT", "MAX", "MID", "MIN", "SESSION_USER", "SUBSTR", "SUBSTRING", "SUM", "SYSTEM_USER", "TRIM") +# Keywords expected to be in UPPERCASE in getValue() +GET_VALUE_UPPERCASE_KEYWORDS = ("SELECT", "FROM", "WHERE", "DISTINCT", "COUNT") + LEGAL_DISCLAIMER = "Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program" # After this number of misses reflective removal mechanism is turned off (for speed up reasons) diff --git a/lib/request/inject.py b/lib/request/inject.py index baa946949..bf2f6cbe6 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -42,6 +42,7 @@ from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapDataException from lib.core.exception import SqlmapNotVulnerableException from lib.core.exception import SqlmapUserQuitException +from lib.core.settings import GET_VALUE_UPPERCASE_KEYWORDS from lib.core.settings import MAX_TECHNIQUES_PER_VALUE from lib.core.settings import SQL_SCALAR_REGEX from lib.core.threads import getCurrentThreadData @@ -345,8 +346,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser kb.safeCharEncode = safeCharEncode kb.resumeValues = resumeValue - # Note: following keywords are expected to be in uppercase - for keyword in ("SELECT", "FROM", "WHERE"): + for keyword in GET_VALUE_UPPERCASE_KEYWORDS: expression = re.sub("(?i)(\A|\(|\)|\s)%s(\Z|\(|\)|\s)" % keyword, r"\g<1>%s\g<2>" % keyword, expression) if suppressOutput is not None: @@ -418,7 +418,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE if found and conf.dnsDomain: - _ = "".join(filter(None, (key if isTechniqueAvailable(value) else None for key, value in {"E": PAYLOAD.TECHNIQUE.ERROR, "Q": PAYLOAD.TECHNIQUE.QUERY, "U": PAYLOAD.TECHNIQUE.UNION}.items()))) + _ = "".join(filter(None, (key if isTechniqueAvailable(value) else None for key, value in {'E': PAYLOAD.TECHNIQUE.ERROR, 'Q': PAYLOAD.TECHNIQUE.QUERY, 'U': PAYLOAD.TECHNIQUE.UNION}.items()))) warnMsg = "option '--dns-domain' will be ignored " warnMsg += "as faster techniques are usable " warnMsg += "(%s) " % _ diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 5eef9f66b..36df8dba7 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -7d6af4ab9aa4b6c10cefe0062409a228 lib/core/settings.py +938c43b15900804e53882140493ffb71 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py baa3f47efa6701076d026e43a6874a51 lib/core/target.py @@ -73,7 +73,7 @@ fb6b788d0016ab4ec5e5f661f0f702ad lib/request/direct.py cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py 5dcdb37823a0b5eff65cd1018bcf09e4 lib/request/httpshandler.py 310efc965c862cfbd7b0da5150a5ad36 lib/request/__init__.py -62b01fc81e0ee708d1b92add612f659e lib/request/inject.py +f7660e11e23e977b00922e241b1a3000 lib/request/inject.py dc1e0af84ee8eb421797d61c8cb8f172 lib/request/methodrequest.py bb9c165b050f7696b089b96b5947fac3 lib/request/pkihandler.py 602d4338a9fceaaee40c601410d8ac0b lib/request/rangehandler.py From c6577b80d97a285dd233343ed496d36ffb82b3a1 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 13:35:02 +0200 Subject: [PATCH 05/12] Minor update --- lib/core/settings.py | 2 +- lib/parse/cmdline.py | 1 - lib/utils/har.py | 1 - plugins/generic/connector.py | 1 - sqlmap.py | 2 +- txt/checksum.md5 | 10 +++++----- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index 545fc29c9..a4e695c0d 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.7" +VERSION = "1.1.7.8" 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/parse/cmdline.py b/lib/parse/cmdline.py index 218f80fd2..d72914124 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -31,7 +31,6 @@ from lib.core.settings import BASIC_HELP_ITEMS from lib.core.settings import DUMMY_URL from lib.core.settings import IS_WIN from lib.core.settings import MAX_HELP_OPTION_LENGTH -from lib.core.settings import UNICODE_ENCODING from lib.core.settings import VERSION_STRING from lib.core.shell import autoCompletion from lib.core.shell import clearHistory diff --git a/lib/utils/har.py b/lib/utils/har.py index 53f6184ab..d227ad672 100644 --- a/lib/utils/har.py +++ b/lib/utils/har.py @@ -13,7 +13,6 @@ import re import StringIO import time -from lib.core.data import logger from lib.core.settings import VERSION # Reference: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html diff --git a/plugins/generic/connector.py b/plugins/generic/connector.py index 5ebbd0b82..79f242f01 100644 --- a/plugins/generic/connector.py +++ b/plugins/generic/connector.py @@ -11,7 +11,6 @@ from lib.core.data import conf from lib.core.data import logger from lib.core.exception import SqlmapFilePathException from lib.core.exception import SqlmapUndefinedMethod -from lib.core.settings import UNICODE_ENCODING class Connector: """ diff --git a/sqlmap.py b/sqlmap.py index 5d859f611..0d57b5fa4 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -329,7 +329,7 @@ def main(): except KeyboardInterrupt: pass - if conf.harFile: + if conf.get("harFile"): with openFile(conf.harFile, "w+b") as f: f.write(json.dumps(conf.httpCollector.obtain(), indent=4, separators=(',', ': '))) diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 36df8dba7..b8fb20812 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -938c43b15900804e53882140493ffb71 lib/core/settings.py +e65c91771c87c114238f281e198f802c lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py baa3f47efa6701076d026e43a6874a51 lib/core/target.py @@ -57,7 +57,7 @@ ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py 4d13ed693401a498b6d073a2a494bd83 lib/core/wordlist.py 310efc965c862cfbd7b0da5150a5ad36 lib/__init__.py 8c4b04062db2245d9e190b413985202a lib/parse/banner.py -0557c5fee58f2578e0dd502b1839e3a3 lib/parse/cmdline.py +d548e2bff2edae0b0e40364a439bb6d4 lib/parse/cmdline.py 3a31657bc38f277d0016ff6d50bde61f lib/parse/configfile.py 14539f1be714d4f1ed042067d63bc50a lib/parse/handler.py 64e5bb3ecbdd75144500588b437ba8da lib/parse/headers.py @@ -103,7 +103,7 @@ a73c3ddd0de359507a8ad59b363aa963 lib/utils/api.py ed70f1ca9113664043ec9e6778e48078 lib/utils/crawler.py ba12c69a90061aa14d848b8396e79191 lib/utils/deps.py 3b9fd519164e0bf275d5fd361c3f11ff lib/utils/getch.py -40e987b76120f0327f891d1cc7866f4e lib/utils/har.py +1cd7599b5e6addb29cbab85d292ccf6c lib/utils/har.py ccfdad414ce2ec0c394c3deaa39a82bf lib/utils/hashdb.py 12e0e0ab70c6fe5786bc561c35dc067f lib/utils/hash.py e76a08237ee6a4cd6855af79610ea8a5 lib/utils/htmlentities.py @@ -201,7 +201,7 @@ deed74334b637767fc9de8f74b37647a plugins/dbms/sybase/fingerprint.py 45436a42c2bb8075e1482a950d993d55 plugins/dbms/sybase/__init__.py 89412a921c8c598c19d36762d5820f05 plugins/dbms/sybase/syntax.py 654cd5e69cf5e5c644bfa5d284e61206 plugins/dbms/sybase/takeover.py -3371edd2292e3daec8df238034684232 plugins/generic/connector.py +f700954549ad8ebf77f5187262fb9af0 plugins/generic/connector.py 5390591ca955036d492de11355b52e8f plugins/generic/custom.py 4ad4bccc03256b8f3d21ba4f8f759404 plugins/generic/databases.py 106f19c1d895963e2efa8ee193a537ec plugins/generic/entries.py @@ -224,7 +224,7 @@ c3cc8b7727161e64ab59f312c33b541a shell/stager.aspx_ 1f7f125f30e0e800beb21e2ebbab18e1 shell/stager.jsp_ 01e3505e796edf19aad6a996101c81c9 shell/stager.php_ 0751a45ac4c130131f2cdb74d866b664 sqlmapapi.py -290b98e6923960e17bdef3db0a05b44c sqlmap.py +f53c10492a13c9f53024d8a963bd86a3 sqlmap.py 08c711a470d7e0bf705320ba3c48b886 tamper/apostrophemask.py e8509df10d3f1c28014d7825562d32dd tamper/apostrophenullencode.py bb27f7dc980ea07fcfedbd7da5e5e029 tamper/appendnullbyte.py From d038d027f96193acbaa7058fdda646c33189820a Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 13:51:48 +0200 Subject: [PATCH 06/12] Minor updates --- lib/core/settings.py | 2 +- lib/core/target.py | 3 ++- lib/utils/api.py | 2 +- lib/utils/crawler.py | 4 ++-- tamper/space2mysqlblank.py | 2 +- txt/checksum.md5 | 10 +++++----- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index a4e695c0d..bd84e7852 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.8" +VERSION = "1.1.7.9" 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 43cbabbf9..1a2d0421b 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -20,6 +20,7 @@ from lib.core.common import getSafeExString from lib.core.common import getUnicode from lib.core.common import hashDBRetrieve from lib.core.common import intersect +from lib.core.common import isNumPosStrValue from lib.core.common import normalizeUnicode from lib.core.common import openFile from lib.core.common import paramToDict @@ -436,7 +437,7 @@ def _resumeHashDBValues(): kb.xpCmdshellAvailable = hashDBRetrieve(HASHDB_KEYS.KB_XP_CMDSHELL_AVAILABLE) or kb.xpCmdshellAvailable kb.errorChunkLength = hashDBRetrieve(HASHDB_KEYS.KB_ERROR_CHUNK_LENGTH) - if kb.errorChunkLength and kb.errorChunkLength.isdigit(): + if isNumPosStrValue(kb.errorChunkLength): kb.errorChunkLength = int(kb.errorChunkLength) else: kb.errorChunkLength = None diff --git a/lib/utils/api.py b/lib/utils/api.py index 9c41412c8..829c2fff3 100644 --- a/lib/utils/api.py +++ b/lib/utils/api.py @@ -736,7 +736,7 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT): if not res["success"]: logger.error("Failed to execute command %s" % command) dataToStdout("%s\n" % raw) - + elif command.startswith("option"): if not taskid: logger.error("No task ID in use") diff --git a/lib/utils/crawler.py b/lib/utils/crawler.py index 27fc8fbdb..747aaf1e6 100644 --- a/lib/utils/crawler.py +++ b/lib/utils/crawler.py @@ -112,10 +112,10 @@ def crawl(target): threadData.shared.deeper.add(url) if re.search(r"(.*?)\?(.+)", url): threadData.shared.value.add(url) - except ValueError: # for non-valid links - pass except UnicodeEncodeError: # for non-HTML files pass + except ValueError: # for non-valid links + pass finally: if conf.forms: findPageForms(content, current, False, True) diff --git a/tamper/space2mysqlblank.py b/tamper/space2mysqlblank.py index caddab148..e7f96b0fb 100644 --- a/tamper/space2mysqlblank.py +++ b/tamper/space2mysqlblank.py @@ -33,7 +33,7 @@ def tamper(payload, **kwargs): >>> random.seed(0) >>> tamper('SELECT id FROM users') - 'SELECT%0Bid%0DFROM%0Cusers' + 'SELECT%A0id%0BFROM%0Cusers' """ # ASCII table: diff --git a/txt/checksum.md5 b/txt/checksum.md5 index b8fb20812..66d2fda94 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -46,10 +46,10 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -e65c91771c87c114238f281e198f802c lib/core/settings.py +3f23a17e519b6334d343e57e0018efd1 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py -baa3f47efa6701076d026e43a6874a51 lib/core/target.py +4416fdcab26b286a5a3a88e75aa60044 lib/core/target.py 8970b88627902239d695280b1160e16c lib/core/testing.py b8306192d980abdc8d669c024511e9a1 lib/core/threads.py ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py @@ -98,9 +98,9 @@ d3da4c7ceaf57c4687a052d58722f6bb lib/techniques/dns/use.py 310efc965c862cfbd7b0da5150a5ad36 lib/techniques/union/__init__.py d71e48e6fd08f75cc612bf8b260994ce lib/techniques/union/test.py db3090ff9a740ba096ba676fcf44ebfc lib/techniques/union/use.py -a73c3ddd0de359507a8ad59b363aa963 lib/utils/api.py +9e903297f6d6bb11660af5c7b109ccab lib/utils/api.py 7d10ba0851da8ee9cd3c140dcd18798e lib/utils/brute.py -ed70f1ca9113664043ec9e6778e48078 lib/utils/crawler.py +c08d2487a53a1db8170178ebcf87c864 lib/utils/crawler.py ba12c69a90061aa14d848b8396e79191 lib/utils/deps.py 3b9fd519164e0bf275d5fd361c3f11ff lib/utils/getch.py 1cd7599b5e6addb29cbab85d292ccf6c lib/utils/har.py @@ -265,7 +265,7 @@ b2331640743170f82be9a8c27f65b206 tamper/space2morecomment.py 507a174c64345df8df003ddba93c8cd1 tamper/space2morehash.py 0ce89b0d602abbd64344ab038be8acbc tamper/space2mssqlblank.py fa66af20648b5538289748abe7a08fe6 tamper/space2mssqlhash.py -9dde72d94ce42bf71e3615108fe0214f tamper/space2mysqlblank.py +b5abc11a45e9646cd0e296548c42e787 tamper/space2mysqlblank.py 038b8ea90f9a3a45b9bc67fcdff38511 tamper/space2mysqldash.py 5665c217ef8998bfd18f9ef1d8c617bd tamper/space2plus.py a30fa43203d960c7a9d8709bf24ca401 tamper/space2randomblank.py From c9b3b47d6f14490cd9e447c120ad9c3b0566bd34 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 14:07:21 +0200 Subject: [PATCH 07/12] Minor update --- lib/core/common.py | 17 +++++++++++++++++ lib/core/settings.py | 2 +- lib/utils/har.py | 3 ++- sqlmap.py | 2 +- txt/checksum.md5 | 8 ++++---- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index c308d2bac..3c2a3636e 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -1118,6 +1118,13 @@ def sanitizeStr(value): return getUnicode(value).replace("\n", " ").replace("\r", "") def getHeader(headers, key): + """ + Returns header value ignoring the letter case + + >>> getHeader({"Foo": "bar"}, "foo") + 'bar' + """ + retVal = None for _ in (headers or {}): if _.upper() == key.upper(): @@ -1619,6 +1626,13 @@ def getRemoteIP(): return retVal def getFileType(filePath): + """ + Returns "magic" file type for given file path + + >>> getFileType(__file__) + 'text' + """ + try: _ = magic.from_file(filePath) except: @@ -4387,6 +4401,9 @@ def getSafeExString(ex, encoding=None): """ Safe way how to get the proper exception represtation as a string (Note: errors to be avoided: 1) "%s" % Exception(u'\u0161') and 2) "%s" % str(Exception(u'\u0161')) + + >>> getSafeExString(Exception('foobar')) + u'foobar' """ retVal = ex diff --git a/lib/core/settings.py b/lib/core/settings.py index bd84e7852..4f35e318c 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.9" +VERSION = "1.1.7.10" 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/utils/har.py b/lib/utils/har.py index d227ad672..3d3579053 100644 --- a/lib/utils/har.py +++ b/lib/utils/har.py @@ -13,6 +13,7 @@ import re import StringIO import time +from lib.core.bigarray import BigArray from lib.core.settings import VERSION # Reference: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HAR/Overview.html @@ -27,7 +28,7 @@ class HTTPCollectorFactory: class HTTPCollector: def __init__(self): - self.messages = [] + self.messages = BigArray() def collectRequest(self, requestMessage, responseMessage, startTime=None, endTime=None): self.messages.append(RawPair(requestMessage, responseMessage, startTime, endTime)) diff --git a/sqlmap.py b/sqlmap.py index 0d57b5fa4..2358a897d 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -331,7 +331,7 @@ def main(): if conf.get("harFile"): with openFile(conf.harFile, "w+b") as f: - f.write(json.dumps(conf.httpCollector.obtain(), indent=4, separators=(',', ': '))) + json.dump(conf.httpCollector.obtain(), fp=f, indent=4, separators=(',', ': ')) if cmdLineOptions.get("sqlmapShell"): cmdLineOptions.clear() diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 66d2fda94..55254a677 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -27,7 +27,7 @@ a97df93b552ee4e4ba3692eae870de7c lib/controller/handler.py 310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py d58e85ffeac2471ef3af729076b3b5f7 lib/core/agent.py 6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py -ebf31aa9c5af54188e999719593e8ba4 lib/core/common.py +68dd8d8d430d6b569ec3210e87f4dce9 lib/core/common.py 5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py 7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -3f23a17e519b6334d343e57e0018efd1 lib/core/settings.py +fa6387225fb4dd399abfcb77e5ef8b94 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py 4416fdcab26b286a5a3a88e75aa60044 lib/core/target.py @@ -103,7 +103,7 @@ db3090ff9a740ba096ba676fcf44ebfc lib/techniques/union/use.py c08d2487a53a1db8170178ebcf87c864 lib/utils/crawler.py ba12c69a90061aa14d848b8396e79191 lib/utils/deps.py 3b9fd519164e0bf275d5fd361c3f11ff lib/utils/getch.py -1cd7599b5e6addb29cbab85d292ccf6c lib/utils/har.py +7143c26b3e18973bc5169c202b775245 lib/utils/har.py ccfdad414ce2ec0c394c3deaa39a82bf lib/utils/hashdb.py 12e0e0ab70c6fe5786bc561c35dc067f lib/utils/hash.py e76a08237ee6a4cd6855af79610ea8a5 lib/utils/htmlentities.py @@ -224,7 +224,7 @@ c3cc8b7727161e64ab59f312c33b541a shell/stager.aspx_ 1f7f125f30e0e800beb21e2ebbab18e1 shell/stager.jsp_ 01e3505e796edf19aad6a996101c81c9 shell/stager.php_ 0751a45ac4c130131f2cdb74d866b664 sqlmapapi.py -f53c10492a13c9f53024d8a963bd86a3 sqlmap.py +b83d4f9b170014ff158f3caa7b735415 sqlmap.py 08c711a470d7e0bf705320ba3c48b886 tamper/apostrophemask.py e8509df10d3f1c28014d7825562d32dd tamper/apostrophenullencode.py bb27f7dc980ea07fcfedbd7da5e5e029 tamper/appendnullbyte.py From 30378c8ae3ba85024d53ab13ae2b9c67a2ac396c Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 15:27:29 +0200 Subject: [PATCH 08/12] Minor patch --- lib/core/common.py | 2 +- lib/core/settings.py | 2 +- txt/checksum.md5 | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index 3c2a3636e..805a44c9f 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -3549,7 +3549,7 @@ def safeSQLIdentificatorNaming(name, isTable=False): if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ("." if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal) if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS): retVal = "`%s`" % retVal.strip("`") - elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2): + elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE): retVal = "\"%s\"" % retVal.strip("\"") elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,): retVal = "\"%s\"" % retVal.strip("\"").upper() diff --git a/lib/core/settings.py b/lib/core/settings.py index 4f35e318c..102194a5d 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.10" +VERSION = "1.1.7.11" 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/txt/checksum.md5 b/txt/checksum.md5 index 55254a677..47f3d4213 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -27,7 +27,7 @@ a97df93b552ee4e4ba3692eae870de7c lib/controller/handler.py 310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py d58e85ffeac2471ef3af729076b3b5f7 lib/core/agent.py 6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py -68dd8d8d430d6b569ec3210e87f4dce9 lib/core/common.py +5bb1ec4e4583cc8be9cb8f694f89b118 lib/core/common.py 5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py 7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -fa6387225fb4dd399abfcb77e5ef8b94 lib/core/settings.py +6122afed0d4d29f58fdbcb1d86c60624 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py 4416fdcab26b286a5a3a88e75aa60044 lib/core/target.py From 75fd8782429a614639c9309c4936e5bf43d93c8a Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 15:41:53 +0200 Subject: [PATCH 09/12] Minor patch --- lib/core/common.py | 4 ++-- lib/core/settings.py | 2 +- txt/checksum.md5 | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index 805a44c9f..f695172a4 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -3549,11 +3549,11 @@ def safeSQLIdentificatorNaming(name, isTable=False): if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ("." if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal) if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS): retVal = "`%s`" % retVal.strip("`") - elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE): + elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE, DBMS.INFORMIX, DBMS.HSQLDB): retVal = "\"%s\"" % retVal.strip("\"") elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,): retVal = "\"%s\"" % retVal.strip("\"").upper() - elif Backend.getIdentifiedDbms() in (DBMS.MSSQL,) and ((retVal or " ")[0].isdigit() or not re.match(r"\A\w+\Z", retVal, re.U)): + elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and ((retVal or " ")[0].isdigit() or not re.match(r"\A\w+\Z", retVal, re.U)): retVal = "[%s]" % retVal.strip("[]") if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal): diff --git a/lib/core/settings.py b/lib/core/settings.py index 102194a5d..cdb870f55 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.11" +VERSION = "1.1.7.12" 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/txt/checksum.md5 b/txt/checksum.md5 index 47f3d4213..0a6f865f2 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -27,7 +27,7 @@ a97df93b552ee4e4ba3692eae870de7c lib/controller/handler.py 310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py d58e85ffeac2471ef3af729076b3b5f7 lib/core/agent.py 6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py -5bb1ec4e4583cc8be9cb8f694f89b118 lib/core/common.py +852ed8b5f19401b7fe21b8032104e3dd lib/core/common.py 5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py 7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -6122afed0d4d29f58fdbcb1d86c60624 lib/core/settings.py +2bb10701c510923bc3e3e3744488cf01 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py 4416fdcab26b286a5a3a88e75aa60044 lib/core/target.py From d248317b89a97d561e163258ddee664acd6492fc Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 5 Jul 2017 16:42:54 +0200 Subject: [PATCH 10/12] Update for people that just download 'sqlmap.py' <- they exist --- lib/core/settings.py | 2 +- sqlmap.py | 5 ++++- txt/checksum.md5 | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index cdb870f55..fd52b5351 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.12" +VERSION = "1.1.7.13" 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/sqlmap.py b/sqlmap.py index 2358a897d..c5944a4ae 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -9,7 +9,10 @@ import sys sys.dont_write_bytecode = True -__import__("lib.utils.versioncheck") # this has to be the first non-standard import +try: + __import__("lib.utils.versioncheck") # this has to be the first non-standard import +except ImportError: + exit("[!] wrong installation detected (missing modules). Visit 'https://github.com/sqlmapproject/sqlmap/#installation' for further details") import bdb import distutils diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 0a6f865f2..4a038359b 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -2bb10701c510923bc3e3e3744488cf01 lib/core/settings.py +638ce6f9130caedbc067d2cf1dc8afc6 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py 4416fdcab26b286a5a3a88e75aa60044 lib/core/target.py @@ -224,7 +224,7 @@ c3cc8b7727161e64ab59f312c33b541a shell/stager.aspx_ 1f7f125f30e0e800beb21e2ebbab18e1 shell/stager.jsp_ 01e3505e796edf19aad6a996101c81c9 shell/stager.php_ 0751a45ac4c130131f2cdb74d866b664 sqlmapapi.py -b83d4f9b170014ff158f3caa7b735415 sqlmap.py +9d91bcb91acf7f623f701d528357bba1 sqlmap.py 08c711a470d7e0bf705320ba3c48b886 tamper/apostrophemask.py e8509df10d3f1c28014d7825562d32dd tamper/apostrophenullencode.py bb27f7dc980ea07fcfedbd7da5e5e029 tamper/appendnullbyte.py From 3f40bf11014166207530759fb24381948ec22233 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Thu, 6 Jul 2017 11:44:18 +0200 Subject: [PATCH 11/12] Fixes #2387 --- lib/core/agent.py | 6 ++++++ lib/core/settings.py | 2 +- txt/checksum.md5 | 6 +++--- xml/queries.xml | 26 +++++++++++++------------- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib/core/agent.py b/lib/core/agent.py index e678627d4..0ac2434b3 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -347,6 +347,12 @@ class Agent(object): if payload: payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec)) + for _ in set(re.findall(r"\[RANDNUM(?:\d+)?\]", payload, re.I)): + payload = payload.replace(_, str(randomInt())) + + for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)): + payload = payload.replace(_, randomStr()) + return payload def getComment(self, request): diff --git a/lib/core/settings.py b/lib/core/settings.py index fd52b5351..565295aae 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.13" +VERSION = "1.1.7.14" 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/txt/checksum.md5 b/txt/checksum.md5 index 4a038359b..80db24757 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -25,7 +25,7 @@ f77daa397016460433d5e06704efd538 lib/controller/checks.py 130d1c16708668b8d89605b6b5b38bf5 lib/controller/controller.py a97df93b552ee4e4ba3692eae870de7c lib/controller/handler.py 310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py -d58e85ffeac2471ef3af729076b3b5f7 lib/core/agent.py +bc51363cbbe4b4d6bafef04508046c31 lib/core/agent.py 6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py 852ed8b5f19401b7fe21b8032104e3dd lib/core/common.py 5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -638ce6f9130caedbc067d2cf1dc8afc6 lib/core/settings.py +c77392c0cc5535864f13a2f8eda71aae lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py 4416fdcab26b286a5a3a88e75aa60044 lib/core/target.py @@ -460,4 +460,4 @@ a279656ea3fcb85c727249b02f828383 xml/livetests.xml 3194e2688a7576e1f877d5b137f7c260 xml/payloads/stacked_queries.xml c2d8dd03db5a663e79eabb4495dd0723 xml/payloads/time_blind.xml ac649aff0e7db413e4937e446e398736 xml/payloads/union_query.xml -7fa7db2c2296baa5e9ea381d4880492f xml/queries.xml +8f984712da3f23f105fc0b3391114e4b xml/queries.xml diff --git a/xml/queries.xml b/xml/queries.xml index bc36a8ad8..f4a177485 100644 --- a/xml/queries.xml +++ b/xml/queries.xml @@ -283,7 +283,7 @@ - + @@ -506,7 +506,7 @@ - + @@ -563,7 +563,7 @@ - + @@ -586,7 +586,7 @@ - + @@ -601,7 +601,7 @@ - + @@ -611,23 +611,23 @@ - + - + - + - + @@ -635,19 +635,19 @@ - + - + - + - + From 591a60bbde434aacc0d90548cd442d6a756ff104 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Tue, 11 Jul 2017 14:48:22 +0200 Subject: [PATCH 12/12] Fixes #2606 --- lib/core/settings.py | 2 +- sqlmap.py | 3 +++ txt/checksum.md5 | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index 565295aae..3ea2fb9ed 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.7.14" +VERSION = "1.1.7.15" 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/sqlmap.py b/sqlmap.py index c5944a4ae..4664ef813 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -287,6 +287,9 @@ def main(): elif "valueStack.pop" in excMsg and kb.get("dumpKeyboardInterrupt"): raise SystemExit + elif any(_ in excMsg for _ in ("Broken pipe",)): + raise SystemExit + for match in re.finditer(r'File "(.+?)", line', excMsg): file_ = match.group(1) file_ = os.path.relpath(file_, os.path.dirname(__file__)) diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 80db24757..9512c1645 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -46,7 +46,7 @@ b9ff4e622c416116bee6024c0f050349 lib/core/enums.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -c77392c0cc5535864f13a2f8eda71aae lib/core/settings.py +68eee8e5cded862a7b123de3d7a94584 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py 4416fdcab26b286a5a3a88e75aa60044 lib/core/target.py @@ -224,7 +224,7 @@ c3cc8b7727161e64ab59f312c33b541a shell/stager.aspx_ 1f7f125f30e0e800beb21e2ebbab18e1 shell/stager.jsp_ 01e3505e796edf19aad6a996101c81c9 shell/stager.php_ 0751a45ac4c130131f2cdb74d866b664 sqlmapapi.py -9d91bcb91acf7f623f701d528357bba1 sqlmap.py +a41c8ad1a5a8f9535d094a637c2990fd sqlmap.py 08c711a470d7e0bf705320ba3c48b886 tamper/apostrophemask.py e8509df10d3f1c28014d7825562d32dd tamper/apostrophenullencode.py bb27f7dc980ea07fcfedbd7da5e5e029 tamper/appendnullbyte.py