diff --git a/lib/core/agent.py b/lib/core/agent.py index 0ac2434b3..e4a349e14 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -101,7 +101,7 @@ class Agent(object): if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue: paramString = origValue if place == PLACE.URI: - origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0] + origValue = origValue.split(conf.customInjectionChar)[0] else: origValue = filter(None, (re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z")))[0].group(0) origValue = origValue[origValue.rfind('/') + 1:] @@ -110,7 +110,7 @@ class Agent(object): origValue = origValue[origValue.rfind(char) + 1:] elif place == PLACE.CUSTOM_POST: paramString = origValue - origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0] + origValue = origValue.split(conf.customInjectionChar)[0] if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML): origValue = origValue.split('>')[-1] elif kb.postHint in (POST_HINT.JSON, POST_HINT.JSON_LIKE): @@ -120,7 +120,7 @@ class Agent(object): origValue = _.split('=', 1)[1] if '=' in _ else "" elif place == PLACE.CUSTOM_HEADER: paramString = origValue - origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0] + origValue = origValue.split(conf.customInjectionChar)[0] origValue = origValue[origValue.find(',') + 1:] match = re.search(r"([^;]+)=(?P[^;]+);?\Z", origValue) if match: @@ -159,14 +159,14 @@ class Agent(object): newValue = self.cleanupPayload(newValue, origValue) if place in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER): - _ = "%s%s" % (origValue, CUSTOM_INJECTION_MARK_CHAR) + _ = "%s%s" % (origValue, conf.customInjectionChar) if kb.postHint == POST_HINT.JSON and not isNumber(newValue) and not '"%s"' % _ in paramString: newValue = '"%s"' % newValue elif kb.postHint == POST_HINT.JSON_LIKE and not isNumber(newValue) and not "'%s'" % _ in paramString: newValue = "'%s'" % newValue - newValue = newValue.replace(CUSTOM_INJECTION_MARK_CHAR, REPLACEMENT_MARKER) + newValue = newValue.replace(conf.customInjectionChar, REPLACEMENT_MARKER) retVal = paramString.replace(_, self.addPayloadDelimiters(newValue)) - retVal = retVal.replace(CUSTOM_INJECTION_MARK_CHAR, "").replace(REPLACEMENT_MARKER, CUSTOM_INJECTION_MARK_CHAR) + retVal = retVal.replace(conf.customInjectionChar, "").replace(REPLACEMENT_MARKER, conf.customInjectionChar) elif BOUNDED_INJECTION_MARKER in paramDict[parameter]: _ = "%s%s" % (origValue, BOUNDED_INJECTION_MARKER) retVal = "%s=%s" % (re.sub(r" (\#\d\*|\(.+\))\Z", "", parameter), paramString.replace(_, self.addPayloadDelimiters(newValue))) diff --git a/lib/core/common.py b/lib/core/common.py index f695172a4..60c8d14b9 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -654,7 +654,8 @@ def paramToDict(place, parameters=None): except Exception: pass - _ = re.sub(regex, "\g<1>%s\g<%d>" % (CUSTOM_INJECTION_MARK_CHAR, len(match.groups())), testableParameters[parameter]) + print "Testing injection char %c"%conf.customInjectionChar + _ = re.sub(regex, "\g<1>%s\g<%d>" % (conf.customInjectionChar, len(match.groups())), testableParameters[parameter]) message = "it appears that provided value for %s parameter '%s' " % (place, parameter) message += "has boundaries. Do you want to inject inside? ('%s') [y/N] " % getUnicode(_) @@ -1394,7 +1395,7 @@ def parseTargetUrl(): else: conf.url = "http://" + conf.url - if CUSTOM_INJECTION_MARK_CHAR in conf.url: + if conf.customInjectionChar in conf.url: conf.url = conf.url.replace('?', URI_QUESTION_MARKER) try: @@ -1412,7 +1413,7 @@ def parseTargetUrl(): conf.hostname = hostnamePort[0].strip() conf.ipv6 = conf.hostname != conf.hostname.strip("[]") - conf.hostname = conf.hostname.strip("[]").replace(CUSTOM_INJECTION_MARK_CHAR, "") + conf.hostname = conf.hostname.strip("[]").replace(conf.customInjectionChar, "") try: _ = conf.hostname.encode("idna") @@ -1453,7 +1454,7 @@ def parseTargetUrl(): debugMsg = "setting the HTTP Referer header to the target URL" logger.debug(debugMsg) conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.REFERER] - conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.url.replace(CUSTOM_INJECTION_MARK_CHAR, ""))) + conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.url.replace(conf.customInjectionChar, ""))) if not conf.host and (intersect(HOST_ALIASES, conf.testParameter, True) or conf.level >= 5): debugMsg = "setting the HTTP Host header to the target URL" @@ -2498,7 +2499,8 @@ def findMultipartPostBoundary(post): return retVal -def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CHAR, convall=False, plusspace=True): +# def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CHAR, convall=False, plusspace=True): +def urldecode(value, encoding=None, unsafe="UNSAFE_IDENTIFIER", convall=False, plusspace=True): """ URL decodes given value @@ -2506,6 +2508,8 @@ def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CH u'AND 1>(2+3)#' """ + if unsafe == "UNSAFE_IDENTIFIER": + unsafe = "%%&=;+%s"%conf.customInjectionChar result = value if value: diff --git a/lib/core/option.py b/lib/core/option.py index ebf958470..12181828b 100755 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -280,7 +280,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls): method = match.group(1) url = match.group(2) - if any(_ in line for _ in ('?', '=', CUSTOM_INJECTION_MARK_CHAR)): + if any(_ in line for _ in ('?', '=', conf.customInjectionChar)): params = True getPostReq = True @@ -320,7 +320,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls): elif key not in (HTTP_HEADER.PROXY_CONNECTION, HTTP_HEADER.CONNECTION): headers.append((getUnicode(key), getUnicode(value))) - if CUSTOM_INJECTION_MARK_CHAR in re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value or ""): + if conf.customInjectionChar in re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value or ""): params = True data = data.rstrip("\r\n") if data else data @@ -539,9 +539,10 @@ def _doSearch(): for link in links: link = urldecode(link) + _URI_INJECTABLE_REGEX = _URI_INJECTABLE_REGEX.replace('*',conf.customInjectionChar) if re.search(r"(.*?)\?(.+)", link): kb.targets.add((link, conf.method, conf.data, conf.cookie, None)) - elif re.search(URI_INJECTABLE_REGEX, link, re.I): + elif re.search(_URI_INJECTABLE_REGEX, link, re.I): if kb.data.onlyGETs is None and conf.data is None and not conf.googleDork: message = "do you want to scan only results containing GET parameters? [Y/n] " kb.data.onlyGETs = readInput(message, default='Y', boolean=True) @@ -593,7 +594,7 @@ def _setBulkMultipleTargets(): found = False for line in getFileItems(conf.bulkFile): - if re.match(r"[^ ]+\?(.+)", line, re.I) or CUSTOM_INJECTION_MARK_CHAR in line: + if re.match(r"[^ ]+\?(.+)", line, re.I) or conf.customInjectionChar in line: found = True kb.targets.add((line.strip(), conf.method, conf.data, conf.cookie, None)) @@ -1686,10 +1687,10 @@ def _cleanupOptions(): setOptimize() if conf.data: - conf.data = re.sub("(?i)%s" % INJECT_HERE_MARK.replace(" ", r"[^A-Za-z]*"), CUSTOM_INJECTION_MARK_CHAR, conf.data) + conf.data = re.sub("(?i)%s" % INJECT_HERE_MARK.replace(" ", r"[^A-Za-z]*"), conf.customInjectionChar, conf.data) if conf.url: - conf.url = re.sub("(?i)%s" % INJECT_HERE_MARK.replace(" ", r"[^A-Za-z]*"), CUSTOM_INJECTION_MARK_CHAR, conf.url) + conf.url = re.sub("(?i)%s" % INJECT_HERE_MARK.replace(" ", r"[^A-Za-z]*"), conf.customInjectionChar, conf.url) if conf.os: conf.os = conf.os.capitalize() diff --git a/lib/core/target.py b/lib/core/target.py index 1a2d0421b..8e57f4a9f 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -52,7 +52,7 @@ from lib.core.option import _setKnowledgeBaseAttributes from lib.core.option import _setAuthCred from lib.core.settings import ASTERISK_MARKER from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES -from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR +# from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import HOST_ALIASES from lib.core.settings import ARRAY_LIKE_RECOGNITION_REGEX @@ -114,12 +114,12 @@ def _setRequestParams(): retVal = retVal.replace(_.group(0), match.group(int(_.group(1)) if _.group(1).isdigit() else _.group(1))) else: break - if CUSTOM_INJECTION_MARK_CHAR in retVal: - hintNames.append((retVal.split(CUSTOM_INJECTION_MARK_CHAR)[0], match.group("name"))) + if conf.customInjectionChar in retVal: + hintNames.append((retVal.split(conf.customInjectionChar)[0], match.group("name"))) return retVal - if kb.processUserMarks is None and CUSTOM_INJECTION_MARK_CHAR in conf.data: - message = "custom injection marking character ('%s') found in option " % CUSTOM_INJECTION_MARK_CHAR + if kb.processUserMarks is None and conf.customInjectionChar in conf.data: + message = "custom injection marking character ('%s') found in option " % conf.customInjectionChar message += "'--data'. Do you want to process it? [Y/n/q] " choice = readInput(message, default='Y') @@ -139,16 +139,16 @@ def _setRequestParams(): if choice == 'Q': raise SqlmapUserQuitException elif choice == 'Y': - if not (kb.processUserMarks and CUSTOM_INJECTION_MARK_CHAR in conf.data): + if not (kb.processUserMarks and conf.customInjectionChar in conf.data): conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) - conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR, ASTERISK_MARKER) - conf.data = re.sub(r'("(?P[^"]+)"\s*:\s*"[^"]+)"', functools.partial(process, repl=r'\g<1>%s"' % CUSTOM_INJECTION_MARK_CHAR), conf.data) - conf.data = re.sub(r'("(?P[^"]+)"\s*:\s*)(-?\d[\d\.]*\b)', functools.partial(process, repl=r'\g<0>%s' % CUSTOM_INJECTION_MARK_CHAR), conf.data) + conf.data = conf.data.replace(conf.customInjectionChar, ASTERISK_MARKER) + conf.data = re.sub(r'("(?P[^"]+)"\s*:\s*"[^"]+)"', functools.partial(process, repl=r'\g<1>%s"' % conf.customInjectionChar), conf.data) + conf.data = re.sub(r'("(?P[^"]+)"\s*:\s*)(-?\d[\d\.]*\b)', functools.partial(process, repl=r'\g<0>%s' % conf.customInjectionChar), conf.data) match = re.search(r'(?P[^"]+)"\s*:\s*\[([^\]]+)\]', conf.data) if match and not (conf.testParameter and match.group("name") not in conf.testParameter): _ = match.group(2) - _ = re.sub(r'("[^"]+)"', '\g<1>%s"' % CUSTOM_INJECTION_MARK_CHAR, _) - _ = re.sub(r'(\A|,|\s+)(-?\d[\d\.]*\b)', '\g<0>%s' % CUSTOM_INJECTION_MARK_CHAR, _) + _ = re.sub(r'("[^"]+)"', '\g<1>%s"' % conf.customInjectionChar, _) + _ = re.sub(r'(\A|,|\s+)(-?\d[\d\.]*\b)', '\g<0>%s' % conf.customInjectionChar, _) conf.data = conf.data.replace(match.group(0), match.group(0).replace(match.group(2), _)) kb.postHint = POST_HINT.JSON @@ -161,11 +161,11 @@ def _setRequestParams(): if choice == 'Q': raise SqlmapUserQuitException elif choice == 'Y': - if not (kb.processUserMarks and CUSTOM_INJECTION_MARK_CHAR in conf.data): + if not (kb.processUserMarks and conf.customInjectionChar in conf.data): conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) - conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR, ASTERISK_MARKER) - conf.data = re.sub(r"('(?P[^']+)'\s*:\s*'[^']+)'", functools.partial(process, repl=r"\g<1>%s'" % CUSTOM_INJECTION_MARK_CHAR), conf.data) - conf.data = re.sub(r"('(?P[^']+)'\s*:\s*)(-?\d[\d\.]*\b)", functools.partial(process, repl=r"\g<0>%s" % CUSTOM_INJECTION_MARK_CHAR), conf.data) + conf.data = conf.data.replace(conf.customInjectionChar, ASTERISK_MARKER) + conf.data = re.sub(r"('(?P[^']+)'\s*:\s*'[^']+)'", functools.partial(process, repl=r"\g<1>%s'" % conf.customInjectionChar), conf.data) + conf.data = re.sub(r"('(?P[^']+)'\s*:\s*)(-?\d[\d\.]*\b)", functools.partial(process, repl=r"\g<0>%s" % conf.customInjectionChar), conf.data) kb.postHint = POST_HINT.JSON_LIKE @@ -177,9 +177,9 @@ def _setRequestParams(): if choice == 'Q': raise SqlmapUserQuitException elif choice == 'Y': - if not (kb.processUserMarks and CUSTOM_INJECTION_MARK_CHAR in conf.data): - conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR, ASTERISK_MARKER) - conf.data = re.sub(r"(=[^%s]+)" % DEFAULT_GET_POST_DELIMITER, r"\g<1>%s" % CUSTOM_INJECTION_MARK_CHAR, conf.data) + if not (kb.processUserMarks and conf.customInjectionChar in conf.data): + conf.data = conf.data.replace(conf.customInjectionChar, ASTERISK_MARKER) + conf.data = re.sub(r"(=[^%s]+)" % DEFAULT_GET_POST_DELIMITER, r"\g<1>%s" % conf.customInjectionChar, conf.data) kb.postHint = POST_HINT.ARRAY_LIKE @@ -191,10 +191,10 @@ def _setRequestParams(): if choice == 'Q': raise SqlmapUserQuitException elif choice == 'Y': - if not (kb.processUserMarks and CUSTOM_INJECTION_MARK_CHAR in conf.data): + if not (kb.processUserMarks and conf.customInjectionChar in conf.data): conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) - conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR, ASTERISK_MARKER) - conf.data = re.sub(r"(<(?P[^>]+)( [^<]*)?>)([^<]+)(\g<4>%s\g<5>" % CUSTOM_INJECTION_MARK_CHAR), conf.data) + conf.data = conf.data.replace(conf.customInjectionChar, ASTERISK_MARKER) + conf.data = re.sub(r"(<(?P[^>]+)( [^<]*)?>)([^<]+)(\g<4>%s\g<5>" % conf.customInjectionChar), conf.data) kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower() else POST_HINT.XML @@ -206,15 +206,15 @@ def _setRequestParams(): if choice == 'Q': raise SqlmapUserQuitException elif choice == 'Y': - if not (kb.processUserMarks and CUSTOM_INJECTION_MARK_CHAR in conf.data): + if not (kb.processUserMarks and conf.customInjectionChar in conf.data): conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) - conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR, ASTERISK_MARKER) - conf.data = re.sub(r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"'](?P[^\n]+?)[\"']).+?)(((\r)?\n)+--)", functools.partial(process, repl=r"\g<1>%s\g<4>" % CUSTOM_INJECTION_MARK_CHAR), conf.data) + conf.data = conf.data.replace(conf.customInjectionChar, ASTERISK_MARKER) + conf.data = re.sub(r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"'](?P[^\n]+?)[\"']).+?)(((\r)?\n)+--)", functools.partial(process, repl=r"\g<1>%s\g<4>" % conf.customInjectionChar), conf.data) kb.postHint = POST_HINT.MULTIPART if not kb.postHint: - if CUSTOM_INJECTION_MARK_CHAR in conf.data: # later processed + if conf.customInjectionChar in conf.data: # later processed pass else: place = PLACE.POST @@ -226,12 +226,13 @@ def _setRequestParams(): conf.paramDict[place] = paramDict testableParameters = True else: - if CUSTOM_INJECTION_MARK_CHAR not in conf.data: # in case that no usable parameter values has been found + if conf.customInjectionChar not in conf.data: # in case that no usable parameter values has been found conf.parameters[PLACE.POST] = conf.data - kb.processUserMarks = True if (kb.postHint and CUSTOM_INJECTION_MARK_CHAR in conf.data) else kb.processUserMarks + kb.processUserMarks = True if (kb.postHint and conf.customInjectionChar in conf.data) else kb.processUserMarks - if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (PLACE.GET, PLACE.POST)) and not kb.postHint and not CUSTOM_INJECTION_MARK_CHAR in (conf.data or "") and conf.url.startswith("http"): + _URI_INJECTABLE_REGEX = URI_INJECTABLE_REGEX.replace('*',conf.customInjectionChar) + if re.search(_URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (PLACE.GET, PLACE.POST)) and not kb.postHint and not conf.customInjectionChar in (conf.data or "") and conf.url.startswith("http"): warnMsg = "you've provided target URL without any GET " warnMsg += "parameters (e.g. 'http://www.site.com/article.php?id=1') " warnMsg += "and without providing any POST parameters " @@ -245,15 +246,15 @@ def _setRequestParams(): if choice == 'Q': raise SqlmapUserQuitException elif choice == 'Y': - conf.url = "%s%s" % (conf.url, CUSTOM_INJECTION_MARK_CHAR) + conf.url = "%s%s" % (conf.url, conf.customInjectionChar) kb.processUserMarks = True for place, value in ((PLACE.URI, conf.url), (PLACE.CUSTOM_POST, conf.data), (PLACE.CUSTOM_HEADER, str(conf.httpHeaders))): _ = re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value or "") if place == PLACE.CUSTOM_HEADER else value or "" - if CUSTOM_INJECTION_MARK_CHAR in _: + if conf.customInjectionChar in _: if kb.processUserMarks is None: lut = {PLACE.URI: '-u', PLACE.CUSTOM_POST: '--data', PLACE.CUSTOM_HEADER: '--headers/--user-agent/--referer/--cookie'} - message = "custom injection marking character ('%s') found in option " % CUSTOM_INJECTION_MARK_CHAR + message = "custom injection marking character ('%s') found in option " % conf.customInjectionChar message += "'%s'. Do you want to process it? [Y/n/q] " % lut[place] choice = readInput(message, default='Y').upper() @@ -265,7 +266,7 @@ def _setRequestParams(): if kb.processUserMarks: kb.testOnlyCustom = True - if "=%s" % CUSTOM_INJECTION_MARK_CHAR in _: + if "=%s" % conf.customInjectionChar in _: warnMsg = "it seems that you've provided empty parameter value(s) " warnMsg += "for testing. Please, always use only valid parameter values " warnMsg += "so sqlmap could be able to run properly" @@ -297,13 +298,13 @@ def _setRequestParams(): if place == PLACE.CUSTOM_HEADER: for index in xrange(len(conf.httpHeaders)): header, value = conf.httpHeaders[index] - if CUSTOM_INJECTION_MARK_CHAR in re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value): - parts = value.split(CUSTOM_INJECTION_MARK_CHAR) + if conf.customInjectionChar in re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value): + parts = value.split(conf.customInjectionChar) for i in xrange(len(parts) - 1): - conf.paramDict[place]["%s #%d%s" % (header, i + 1, CUSTOM_INJECTION_MARK_CHAR)] = "%s,%s" % (header, "".join("%s%s" % (parts[j], CUSTOM_INJECTION_MARK_CHAR if i == j else "") for j in xrange(len(parts)))) - conf.httpHeaders[index] = (header, value.replace(CUSTOM_INJECTION_MARK_CHAR, "")) + conf.paramDict[place]["%s #%d%s" % (header, i + 1, conf.customInjectionChar)] = "%s,%s" % (header, "".join("%s%s" % (parts[j], conf.customInjectionChar if i == j else "") for j in xrange(len(parts)))) + conf.httpHeaders[index] = (header, value.replace(conf.customInjectionChar, "")) else: - parts = value.split(CUSTOM_INJECTION_MARK_CHAR) + parts = value.split(conf.customInjectionChar) for i in xrange(len(parts) - 1): name = None @@ -313,8 +314,8 @@ def _setRequestParams(): name = "%s %s" % (kb.postHint, _) break if name is None: - name = "%s#%s%s" % (("%s " % kb.postHint) if kb.postHint else "", i + 1, CUSTOM_INJECTION_MARK_CHAR) - conf.paramDict[place][name] = "".join("%s%s" % (parts[j], CUSTOM_INJECTION_MARK_CHAR if i == j else "") for j in xrange(len(parts))) + name = "%s#%s%s" % (("%s " % kb.postHint) if kb.postHint else "", i + 1, conf.customInjectionChar) + conf.paramDict[place][name] = "".join("%s%s" % (parts[j], conf.customInjectionChar if i == j else "") for j in xrange(len(parts))) if place == PLACE.URI and PLACE.GET in conf.paramDict: del conf.paramDict[PLACE.GET] @@ -326,7 +327,7 @@ def _setRequestParams(): if kb.processUserMarks: for item in ("url", "data", "agent", "referer", "cookie"): if conf.get(item): - conf[item] = conf[item].replace(CUSTOM_INJECTION_MARK_CHAR, "") + conf[item] = conf[item].replace(conf.customInjectionChar, "") # Perform checks on Cookie parameters if conf.cookie: @@ -375,8 +376,8 @@ def _setRequestParams(): if condition: conf.parameters[PLACE.CUSTOM_HEADER] = str(conf.httpHeaders) - conf.paramDict[PLACE.CUSTOM_HEADER] = {httpHeader: "%s,%s%s" % (httpHeader, headerValue, CUSTOM_INJECTION_MARK_CHAR)} - conf.httpHeaders = [(header, value.replace(CUSTOM_INJECTION_MARK_CHAR, "")) for header, value in conf.httpHeaders] + conf.paramDict[PLACE.CUSTOM_HEADER] = {httpHeader: "%s,%s%s" % (httpHeader, headerValue, conf.customInjectionChar)} + conf.httpHeaders = [(header, value.replace(conf.customInjectionChar, "")) for header, value in conf.httpHeaders] testableParameters = True if not conf.parameters: diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index d72914124..c6942e4ab 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -232,6 +232,10 @@ def cmdLineParser(argv=None): request.add_option("--eval", dest="evalCode", help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")") + # Attempt to replace CUSTOM_INJECTION_MARK_CHAR with something dynamic + request.add_option("--custom-injection-char", dest="customInjectionChar", default='*', + help="Assign a different character to be used as injection identifier") + # Optimization options optimization = OptionGroup(parser, "Optimization", "These " "options can be used to optimize the " diff --git a/lib/request/connect.py b/lib/request/connect.py index 81977ec51..d2b638fdb 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -901,7 +901,7 @@ class Connect(object): post = value if PLACE.CUSTOM_POST in conf.parameters: - post = conf.parameters[PLACE.CUSTOM_POST].replace(CUSTOM_INJECTION_MARK_CHAR, "") if place != PLACE.CUSTOM_POST or not value else value + post = conf.parameters[PLACE.CUSTOM_POST].replace(conf.customInjectionChar, "") if place != PLACE.CUSTOM_POST or not value else value post = post.replace(ASTERISK_MARKER, '*') if post else post if PLACE.COOKIE in conf.parameters: