diff --git a/lib/core/common.py b/lib/core/common.py index db48c0b28..920d65630 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -4702,3 +4702,13 @@ def safeVariableNaming(value): def unsafeVariableNaming(value): return re.sub(r"%s([0-9a-f]{2})" % SAFE_VARIABLE_MARKER, lambda match: match.group(1).decode("hex"), value) + +def firstNotNone(*args): + retVal = None + + for _ in args: + if _ is not None: + retVal = _ + break + + return retVal diff --git a/lib/core/settings.py b/lib/core/settings.py index e62570a4f..c5a6196ec 100644 --- 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.2.7.22" +VERSION = "1.2.7.23" 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/techniques/error/use.py b/lib/techniques/error/use.py index 6aac89350..0674f38d6 100644 --- a/lib/techniques/error/use.py +++ b/lib/techniques/error/use.py @@ -16,6 +16,7 @@ from lib.core.common import calculateDeltaSeconds from lib.core.common import dataToStdout from lib.core.common import decodeHexValue from lib.core.common import extractRegexResult +from lib.core.common import firstNotNone from lib.core.common import getConsoleWidth from lib.core.common import getPartRun from lib.core.common import getUnicode @@ -102,7 +103,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False): try: while True: check = r"(?si)%s(?P.*?)%s" % (kb.chars.start, kb.chars.stop) - trimcheck = r"(?si)%s(?P[^<\n]*)" % kb.chars.start + trimCheck = r"(?si)%s(?P[^<\n]*)" % kb.chars.start if field: nulledCastedField = agent.nullAndCastField(field) @@ -133,22 +134,21 @@ 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, ( + output = firstNotNone( 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 + extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None) ) if output is not None: output = getUnicode(output) else: - 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) + trimmed = firstNotNone( + extractRegexResult(trimCheck, page), + extractRegexResult(trimCheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None), + extractRegexResult(trimCheck, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)), + extractRegexResult(trimCheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None) ) if trimmed: @@ -163,7 +163,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False): output = extractRegexResult(check, trimmed, re.IGNORECASE) if not output: - check = "(?P[^\s<>'\"]+)" + check = r"(?P[^\s<>'\"]+)" output = extractRegexResult(check, trimmed, re.IGNORECASE) else: output = output.rstrip() diff --git a/lib/techniques/union/use.py b/lib/techniques/union/use.py index 30c986d4b..1e65f67dc 100644 --- a/lib/techniques/union/use.py +++ b/lib/techniques/union/use.py @@ -19,6 +19,7 @@ from lib.core.common import calculateDeltaSeconds from lib.core.common import clearConsoleLine from lib.core.common import dataToStdout from lib.core.common import extractRegexResult +from lib.core.common import firstNotNone from lib.core.common import flattenValue from lib.core.common import getConsoleWidth from lib.core.common import getPartRun @@ -90,7 +91,10 @@ def _oneShotUnionUse(expression, unpack=True, limited=False): # Parse the returned page to get the exact UNION-based # SQL injection output def _(regex): - return reduce(lambda x, y: x if x is not None else y, (extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE), extractRegexResult(regex, removeReflectiveValues(listToStrValue((_ for _ in headers.headers if not _.startswith(HTTP_HEADER.URI)) if headers else None), payload, True), re.DOTALL | re.IGNORECASE)), None) + return firstNotNone( + extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE), + extractRegexResult(regex, removeReflectiveValues(listToStrValue((_ for _ in headers.headers if not _.startswith(HTTP_HEADER.URI)) if headers else None), payload, True), re.DOTALL | re.IGNORECASE) + ) # Automatically patching last char trimming cases if kb.chars.stop not in (page or "") and kb.chars.stop[:-1] in (page or ""): diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 04509aaa5..3fc726e5d 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -28,7 +28,7 @@ c7443613a0a2505b1faec931cee2a6ef lib/controller/handler.py 1e5532ede194ac9c083891c2f02bca93 lib/controller/__init__.py 0adf547455a76dc71e6a599e52da1ed9 lib/core/agent.py fd8f239e259afaf5f24bcf34a0ad187f lib/core/bigarray.py -de53dd81bda04541d0992852aee0f2b3 lib/core/common.py +14689a69e8c4447cc117703bb89489ad lib/core/common.py 0d082da16c388b3445e656e0760fb582 lib/core/convert.py 9f87391b6a3395f7f50830b391264f27 lib/core/data.py 72016ea5c994a711a262fd64572a0fcd lib/core/datatype.py @@ -48,7 +48,7 @@ c8c386d644d57c659d74542f5f57f632 lib/core/patch.py 0c3eef46bdbf87e29a3f95f90240d192 lib/core/replication.py a7db43859b61569b601b97f187dd31c5 lib/core/revision.py fcb74fcc9577523524659ec49e2e964b lib/core/session.py -9c991557b5b0a38f14c5667d627ead76 lib/core/settings.py +23138239bf2e6e9a5c2e383862a6fe59 lib/core/settings.py dd68a9d02fccb4fa1428b20e15b0db5d lib/core/shell.py a7edc9250d13af36ac0108f259859c19 lib/core/subprocessng.py 12bed9603b6fba3e5ffda11d584bc449 lib/core/target.py @@ -95,11 +95,11 @@ debc36a3ff80ba915aeeee69b21a8ddc lib/takeover/xp_cmdshell.py 799faf9008527d2e9da9d923e50f685a lib/techniques/dns/test.py 48a24f48da791e67309003fd5e8428cb lib/techniques/dns/use.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/error/__init__.py -b9f6148c8df6b9d3316ce082dc1a63dd lib/techniques/error/use.py +350d39006cf94151738a95c8d92caa28 lib/techniques/error/use.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/union/__init__.py 94d7a22bb6725a91e84ba2cd9973e96d lib/techniques/union/test.py -8b770864bdb106ef50c70173c824395c lib/techniques/union/use.py +bfa5bcc4058eeb05c07f6e50f91952b6 lib/techniques/union/use.py 77ff35587af9e3dfde63b8327e230f9a lib/utils/api.py 37dfb641358669f62c2acedff241348b lib/utils/brute.py 31b1e7eb489eac837db6a2bc1dcb7da7 lib/utils/crawler.py