Neutralizes reflective values in a given content based on a payload (e.g. ..search.php?q=1 AND 1=2 --> "...searching for 1%20AND%201%3D2 ..." --> "...searching for __REFLECTED_VALUE__ ...")
(content, payload, suppressWarning=False)
| 4134 | return retVal |
| 4135 | |
| 4136 | def removeReflectiveValues(content, payload, suppressWarning=False): |
| 4137 | """ |
| 4138 | Neutralizes reflective values in a given content based on a payload |
| 4139 | (e.g. ..search.php?q=1 AND 1=2 --> "...searching for <b>1%20AND%201%3D2</b>..." --> "...searching for <b>__REFLECTED_VALUE__</b>...") |
| 4140 | """ |
| 4141 | |
| 4142 | retVal = content |
| 4143 | |
| 4144 | try: |
| 4145 | if all((content, payload)) and isinstance(content, six.text_type) and kb.reflectiveMechanism and not kb.heuristicMode: |
| 4146 | def _(value): |
| 4147 | while 2 * REFLECTED_REPLACEMENT_REGEX in value: |
| 4148 | value = value.replace(2 * REFLECTED_REPLACEMENT_REGEX, REFLECTED_REPLACEMENT_REGEX) |
| 4149 | return value |
| 4150 | |
| 4151 | payload = getUnicode(urldecode(payload.replace(PAYLOAD_DELIMITER, ""), convall=True)) |
| 4152 | regex = _(filterStringValue(payload, r"[A-Za-z0-9]", encodeStringEscape(REFLECTED_REPLACEMENT_REGEX))) |
| 4153 | |
| 4154 | # NOTE: special case when part of the result shares the same output as the payload (e.g. ?id=1... and "sqlmap/1.0-dev (http://sqlmap.org)") |
| 4155 | preserve = extractRegexResult(r"%s(?P<result>.+?)%s" % (kb.chars.start, kb.chars.stop), content) |
| 4156 | if preserve: |
| 4157 | content = content.replace(preserve, REPLACEMENT_MARKER) |
| 4158 | |
| 4159 | if regex != payload: |
| 4160 | if all(part.lower() in content.lower() for part in filterNone(regex.split(REFLECTED_REPLACEMENT_REGEX))[1:]): # fast optimization check |
| 4161 | parts = regex.split(REFLECTED_REPLACEMENT_REGEX) |
| 4162 | |
| 4163 | # Note: naive approach |
| 4164 | retVal = content.replace(payload, REFLECTED_VALUE_MARKER) |
| 4165 | retVal = retVal.replace(re.sub(r"\A\w+", "", payload), REFLECTED_VALUE_MARKER) |
| 4166 | |
| 4167 | if len(parts) > REFLECTED_MAX_REGEX_PARTS: # preventing CPU hogs |
| 4168 | regex = _("%s%s%s" % (REFLECTED_REPLACEMENT_REGEX.join(parts[:REFLECTED_MAX_REGEX_PARTS // 2]), REFLECTED_REPLACEMENT_REGEX, REFLECTED_REPLACEMENT_REGEX.join(parts[-REFLECTED_MAX_REGEX_PARTS // 2:]))) |
| 4169 | |
| 4170 | parts = filterNone(regex.split(REFLECTED_REPLACEMENT_REGEX)) |
| 4171 | |
| 4172 | if regex.startswith(REFLECTED_REPLACEMENT_REGEX): |
| 4173 | regex = r"%s%s" % (REFLECTED_BORDER_REGEX, regex[len(REFLECTED_REPLACEMENT_REGEX):]) |
| 4174 | else: |
| 4175 | regex = r"\b%s" % regex |
| 4176 | |
| 4177 | if regex.endswith(REFLECTED_REPLACEMENT_REGEX): |
| 4178 | regex = r"%s%s" % (regex[:-len(REFLECTED_REPLACEMENT_REGEX)], REFLECTED_BORDER_REGEX) |
| 4179 | else: |
| 4180 | regex = r"%s\b" % regex |
| 4181 | |
| 4182 | _retVal = [retVal] |
| 4183 | |
| 4184 | def _thread(regex): |
| 4185 | try: |
| 4186 | _retVal[0] = re.sub(r"(?i)%s" % regex, REFLECTED_VALUE_MARKER, _retVal[0]) |
| 4187 | |
| 4188 | if len(parts) > 2: |
| 4189 | regex = REFLECTED_REPLACEMENT_REGEX.join(parts[1:]) |
| 4190 | _retVal[0] = re.sub(r"(?i)\b%s\b" % regex, REFLECTED_VALUE_MARKER, _retVal[0]) |
| 4191 | except KeyboardInterrupt: |
| 4192 | raise |
| 4193 | except: |
searching dependent graphs…