From 4ce08dcfa367e27abda250be0085ab6960f06585 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 17 May 2017 00:22:18 +0200 Subject: [PATCH] Patch for an Issue #2536 --- lib/controller/checks.py | 9 +++------ lib/core/settings.py | 2 +- lib/request/basic.py | 8 ++++---- lib/request/connect.py | 10 +++++----- lib/techniques/error/use.py | 29 +++++++++++++---------------- txt/checksum.md5 | 10 +++++----- 6 files changed, 31 insertions(+), 37 deletions(-) diff --git a/lib/controller/checks.py b/lib/controller/checks.py index c96524472f5..61c77f5581f 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -554,12 +554,9 @@ def genCmpPayload(): try: page, headers = Request.queryPage(reqPayload, place, content=True, raise404=False) output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) \ - or extractRegexResult(check, listToStrValue( \ - [headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()] \ - if headers else None), re.DOTALL | re.IGNORECASE) \ - or extractRegexResult(check, threadData.lastRedirectMsg[1] \ - if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == \ - threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE) + or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE) \ + or extractRegexResult(check, listToStrValue([headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()] if headers else None), re.DOTALL | re.IGNORECASE) \ + or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE) if output: result = output == "1" diff --git a/lib/core/settings.py b/lib/core/settings.py index 271511f7690..b9ac29d5d68 100755 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.1.5.8" +VERSION = "1.1.5.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/request/basic.py b/lib/request/basic.py index b6012941303..252d6c6cb9a 100644 --- a/lib/request/basic.py +++ b/lib/request/basic.py @@ -123,7 +123,7 @@ def title(self): return headers -def parseResponse(page, headers): +def parseResponse(page, headers, status=None): """ @param page: the page to parse to feed the knowledge base htmlFp (back-end DBMS fingerprint based upon DBMS error messages return @@ -135,7 +135,7 @@ def parseResponse(page, headers): headersParser(headers) if page: - htmlParser(page) + htmlParser(page if not status else "%s\n\n%s" % (status, page)) @cachedmethod def checkCharEncoding(encoding, warn=True): @@ -340,12 +340,12 @@ def _(match): return page -def processResponse(page, responseHeaders): +def processResponse(page, responseHeaders, status=None): kb.processResponseCounter += 1 page = page or "" - parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None) + parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None, status) if not kb.tableFrom and Backend.getIdentifiedDbms() in (DBMS.ACCESS,): kb.tableFrom = extractRegexResult(SELECT_FROM_TABLE_REGEX, page) diff --git a/lib/request/connect.py b/lib/request/connect.py index f5045bbaa01..3e80bef6359 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -280,8 +280,9 @@ def getPage(**kwargs): url = url.replace(" ", "%20") conn = None - code = None page = None + code = None + 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)) @@ -566,12 +567,12 @@ class _(dict): page = page if isinstance(page, unicode) else getUnicode(page) code = ex.code + status = getUnicode(ex.msg) kb.originalCode = kb.originalCode or code - threadData.lastHTTPError = (threadData.lastRequestUID, code) + threadData.lastHTTPError = (threadData.lastRequestUID, code, status) kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1 - status = getUnicode(ex.msg) responseMsg += "[#%d] (%d %s):\n" % (threadData.lastRequestUID, code, status) if responseHeaders: @@ -600,7 +601,6 @@ class _(dict): else: debugMsg = "page not found (%d)" % code singleTimeLogMessage(debugMsg, logging.DEBUG) - processResponse(page, responseHeaders) elif ex.code == httplib.GATEWAY_TIMEOUT: if ignoreTimeout: return None if not conf.ignoreTimeouts else "", None, None @@ -716,7 +716,7 @@ class _(dict): page = getUnicode(page) socket.setdefaulttimeout(conf.timeout) - processResponse(page, responseHeaders) + processResponse(page, responseHeaders, status) if conn and getattr(conn, "redurl", None): _ = urlparse.urlsplit(conn.redurl) diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py index 895962c30d2..3b41a8bff48 100644 --- a/lib/techniques/error/use.py +++ b/lib/techniques/error/use.py @@ -28,6 +28,7 @@ from lib.core.common import listToStrValue from lib.core.common import readInput from lib.core.common import unArrayizeValue +from lib.core.common import wasLastResponseHTTPError from lib.core.convert import hexdecode from lib.core.convert import htmlunescape from lib.core.data import conf @@ -97,8 +98,8 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False): if retVal is None or partialValue: try: while True: - check = r"%s(?P.*?)%s" % (kb.chars.start, kb.chars.stop) - trimcheck = r"%s(?P[^<\n]*)" % (kb.chars.start) + check = r"(?si)%s(?P.*?)%s" % (kb.chars.start, kb.chars.stop) + trimcheck = r"(?si)%s(?P[^<\n]*)" % kb.chars.start if field: nulledCastedField = agent.nullAndCastField(field) @@ -130,23 +131,19 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False): # Parse the returned page to get the exact error-based # SQL injection output output = reduce(lambda x, y: x if x is not None else y, (\ - extractRegexResult(check, page, re.DOTALL | re.IGNORECASE), \ - extractRegexResult(check, listToStrValue([headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()] \ - if headers else None), re.DOTALL | re.IGNORECASE), \ - extractRegexResult(check, threadData.lastRedirectMsg[1] \ - if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == \ - threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)), \ + extractRegexResult(check, page), \ + extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None), \ + extractRegexResult(check, listToStrValue([headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()] if headers else None)), \ + extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)), \ None) if output is not None: output = getUnicode(output) else: - trimmed = extractRegexResult(trimcheck, page, re.DOTALL | re.IGNORECASE) \ - or extractRegexResult(trimcheck, listToStrValue([headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()] \ - if headers else None), re.DOTALL | re.IGNORECASE) \ - or extractRegexResult(trimcheck, threadData.lastRedirectMsg[1] \ - if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == \ - threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE) + trimmed = extractRegexResult(trimcheck, page) \ + or extractRegexResult(trimcheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None) \ + or extractRegexResult(trimcheck, listToStrValue([headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()] if headers else None)) \ + or extractRegexResult(trimcheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None) if trimmed: if not chunkTest: @@ -205,8 +202,8 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False): hashDBWrite(expression, retVal) else: - _ = "%s(?P.*?)%s" % (kb.chars.start, kb.chars.stop) - retVal = extractRegexResult(_, retVal, re.DOTALL | re.IGNORECASE) or retVal + _ = "(?si)%s(?P.*?)%s" % (kb.chars.start, kb.chars.stop) + retVal = extractRegexResult(_, retVal) or retVal return safecharencode(retVal) if kb.safeCharEncode else retVal diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 7d50f79dd4d..55f7cefbd2f 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -21,7 +21,7 @@ c55b400b72acc43e0e59c87dd8bb8d75 extra/shellcodeexec/windows/shellcodeexec.x32. 310efc965c862cfbd7b0da5150a5ad36 extra/sqlharvest/__init__.py 7713aa366c983cdf1f3dbaa7383ea9e1 extra/sqlharvest/sqlharvest.py 7afe836fd97271ccba67b4c0da2482ff lib/controller/action.py -4ea6e0c35aedbdce88bbdff7c8786ae5 lib/controller/checks.py +2e871354300eb72ae60da0d58aa78dcd lib/controller/checks.py 130d1c16708668b8d89605b6b5b38bf5 lib/controller/controller.py 52a3969f57170e935e3fc0156335bf2c lib/controller/handler.py 310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py @@ -46,7 +46,7 @@ edcfce0850771e6454acef244d5c5760 lib/core/optiondict.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -de11a5dd8eba001298b2f6774af54d25 lib/core/settings.py +e1f0497c4a8a98ce2804e08afed99330 lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py 8136241fdbdb99a5dc0e51ba72918f6e lib/core/target.py @@ -66,9 +66,9 @@ ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py 0b010b7cdb2e42b5aa0caa59607279ad lib/parse/payloads.py 997d0452e6fc22411f81a334511bcb3d lib/parse/sitemap.py 403d873f1d2fd0c7f73d83f104e41850 lib/request/basicauthhandler.py -7b3f95016175b9700bb2cc09c9e0fa91 lib/request/basic.py +a79f7c4259418fbc66229a1cb2e945bd lib/request/basic.py ef48de622b0a6b4a71df64b0d2785ef8 lib/request/comparison.py -108ca3607d42bd4923277019a8d6db7d lib/request/connect.py +09ab01822da8f45dec4c995a7fb0e130 lib/request/connect.py fb6b788d0016ab4ec5e5f661f0f702ad lib/request/direct.py cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py 5dcdb37823a0b5eff65cd1018bcf09e4 lib/request/httpshandler.py @@ -93,7 +93,7 @@ e7f3012f4f9e822d39eabd934d050b0e lib/takeover/web.py ab1601a7f429b47637c4fb8af703d0f1 lib/techniques/dns/test.py d3da4c7ceaf57c4687a052d58722f6bb lib/techniques/dns/use.py 310efc965c862cfbd7b0da5150a5ad36 lib/techniques/error/__init__.py -8e918c27b796dada3f87ed2fafeb9d8c lib/techniques/error/use.py +628f1fe86603512ae122f868cdabbfb9 lib/techniques/error/use.py 310efc965c862cfbd7b0da5150a5ad36 lib/techniques/__init__.py 310efc965c862cfbd7b0da5150a5ad36 lib/techniques/union/__init__.py 211e6dc49af6ad6bd3590d16d41e86db lib/techniques/union/test.py