From 94a337b2e3ddbaacdcbca124f993aa86feee25d8 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Tue, 10 Oct 2017 16:08:13 +0200 Subject: [PATCH] Implementation for an Issue #1306 --- lib/core/common.py | 7 +++++++ lib/core/settings.py | 3 ++- lib/request/connect.py | 37 +++++++++++++++++++++++++++++-------- txt/checksum.md5 | 6 +++--- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index 3ce658418..495883c82 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -143,6 +143,7 @@ from lib.core.settings import REFLECTED_REPLACEMENT_REGEX from lib.core.settings import REFLECTED_REPLACEMENT_TIMEOUT from lib.core.settings import REFLECTED_VALUE_MARKER from lib.core.settings import REFLECTIVE_MISS_THRESHOLD +from lib.core.settings import SAFE_VARIABLE_MARKER from lib.core.settings import SENSITIVE_DATA_REGEX from lib.core.settings import SENSITIVE_OPTIONS from lib.core.settings import SUPPORTED_DBMS @@ -4429,3 +4430,9 @@ def getSafeExString(ex, encoding=None): retVal = ex.msg return getUnicode(retVal or "", encoding=encoding).strip() + +def safeVariableNaming(value): + return re.sub(r"[^\w]", lambda match: "%s%02x" % (SAFE_VARIABLE_MARKER, ord(match.group(0))), value) + +def unsafeVariableNaming(value): + return re.sub(r"%s([0-9a-f]{2})" % SAFE_VARIABLE_MARKER, lambda match: match.group(1).decode("hex"), value) diff --git a/lib/core/settings.py b/lib/core/settings.py index fa4a68181..41b7a17c9 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.10.7" +VERSION = "1.1.10.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) @@ -63,6 +63,7 @@ URI_QUESTION_MARKER = "__QUESTION_MARK__" ASTERISK_MARKER = "__ASTERISK_MARK__" REPLACEMENT_MARKER = "__REPLACEMENT_MARK__" BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__" +SAFE_VARIABLE_MARKER = "__SAFE__" RANDOM_INTEGER_MARKER = "[RANDINT]" RANDOM_STRING_MARKER = "[RANDSTR]" diff --git a/lib/request/connect.py b/lib/request/connect.py index 3ef84ca08..7de42ffb8 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -51,11 +51,13 @@ from lib.core.common import randomInt from lib.core.common import randomStr from lib.core.common import readInput from lib.core.common import removeReflectiveValues +from lib.core.common import safeVariableNaming from lib.core.common import singleTimeLogMessage from lib.core.common import singleTimeWarnMessage from lib.core.common import stdev from lib.core.common import wasLastResponseDelayed from lib.core.common import unicodeencode +from lib.core.common import unsafeVariableNaming from lib.core.common import urldecode from lib.core.common import urlencode from lib.core.data import conf @@ -1028,8 +1030,11 @@ class Connect(object): for part in item.split(delimiter): if '=' in part: name, value = part.split('=', 1) - name = re.sub(r"[^\w]", "", name.strip()) - if name in keywords: + name = name.strip() + if safeVariableNaming(name) != name: + conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode) + name = safeVariableNaming(name) + elif name in keywords: name = "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX) value = urldecode(value, convall=True, plusspace=(item==post and kb.postSpaceToPlus)) variables[name] = value @@ -1038,8 +1043,11 @@ class Connect(object): for part in cookie.split(conf.cookieDel or DEFAULT_COOKIE_DELIMITER): if '=' in part: name, value = part.split('=', 1) - name = re.sub(r"[^\w]", "", name.strip()) - if name in keywords: + name = name.strip() + if safeVariableNaming(name) != name: + conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode) + name = safeVariableNaming(name) + elif name in keywords: name = "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX) value = urldecode(value, convall=True) variables[name] = value @@ -1050,10 +1058,18 @@ class Connect(object): except SyntaxError, ex: if ex.text: original = replacement = ex.text.strip() - for _ in re.findall(r"[A-Za-z_]+", original)[::-1]: - if _ in keywords: - replacement = replacement.replace(_, "%s%s" % (_, EVALCODE_KEYWORD_SUFFIX)) - break + if '=' in original: + name, value = original.split('=', 1) + name = name.strip() + if safeVariableNaming(name) != name: + replacement = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), replacement) + elif name in keywords: + replacement = re.sub(r"\b%s\b" % re.escape(name), "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX), replacement) + else: + for _ in re.findall(r"[A-Za-z_]+", original)[::-1]: + if _ in keywords: + replacement = replacement.replace(_, "%s%s" % (_, EVALCODE_KEYWORD_SUFFIX)) + break if original == replacement: conf.evalCode = conf.evalCode.replace(EVALCODE_KEYWORD_SUFFIX, "") break @@ -1073,6 +1089,11 @@ class Connect(object): del variables[variable] variables[variable.replace(EVALCODE_KEYWORD_SUFFIX, "")] = value + if unsafeVariableNaming(variable) != variable: + value = variables[variable] + del variables[variable] + variables[unsafeVariableNaming(variable)] = value + uri = variables["uri"] for name, value in variables.items(): diff --git a/txt/checksum.md5 b/txt/checksum.md5 index d0a3a9fc0..54b644800 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -27,7 +27,7 @@ a66093c734c7f94ecdf94d882c2d8b89 lib/controller/controller.py 310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py 90b4f40ccde13c44e26f53db474afc19 lib/core/agent.py 6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py -ff068a628d68a4dcf597ae60e6e8abe2 lib/core/common.py +5ac200c86905d827e22c744a466da8f3 lib/core/common.py 9edefb92b0b9cad862543fcd587aaa66 lib/core/convert.py a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py 7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py @@ -46,7 +46,7 @@ e8e9fd4f224ead0caa1569312b5b2582 lib/core/optiondict.py d8e9250f3775119df07e9070eddccd16 lib/core/replication.py 785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py 40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py -a2dc48679d88e33f075ab1e0e557fa9e lib/core/settings.py +587bd6c44f842c95680d1e471470733d lib/core/settings.py d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py 2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py effc153067a00bd43461bfc1cdec1122 lib/core/target.py @@ -68,7 +68,7 @@ ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py 403d873f1d2fd0c7f73d83f104e41850 lib/request/basicauthhandler.py 0c476bde96ad035b3f0dde3b845e5e6e lib/request/basic.py ef48de622b0a6b4a71df64b0d2785ef8 lib/request/comparison.py -1ec370ec9d037135607b48ad6afd4f40 lib/request/connect.py +fbff2cbabb815c989ec005115a1813a0 lib/request/connect.py fb6b788d0016ab4ec5e5f661f0f702ad lib/request/direct.py cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py 5dcdb37823a0b5eff65cd1018bcf09e4 lib/request/httpshandler.py