(payload, protection_regex=GENERIC_PROTECTION_REGEX % '|'.join(GENERIC_PROTECTION_KEYWORDS))
| 195 | seen.add(message) |
| 196 | |
| 197 | def check_payload(payload, protection_regex=GENERIC_PROTECTION_REGEX % '|'.join(GENERIC_PROTECTION_KEYWORDS)): |
| 198 | global chained |
| 199 | global heuristic |
| 200 | global intrusive |
| 201 | global locked_code |
| 202 | global locked_regex |
| 203 | |
| 204 | time.sleep(options.delay or 0) |
| 205 | if options.post: |
| 206 | _ = "%s=%s" % ("".join(random.sample(string.ascii_letters, 3)), quote(payload)) |
| 207 | intrusive = retrieve(options.url, _) |
| 208 | else: |
| 209 | _ = "%s%s%s=%s" % (options.url, '?' if '?' not in options.url else '&', "".join(random.sample(string.ascii_letters, 3)), quote(payload)) |
| 210 | intrusive = retrieve(_) |
| 211 | |
| 212 | if options.lock and not payload.isdigit(): |
| 213 | if payload == HEURISTIC_PAYLOAD: |
| 214 | match = re.search(re.sub(r"Server:|Protected by", "".join(random.sample(string.ascii_letters, 6)), WAF_RECOGNITION_REGEX, flags=re.I), intrusive[RAW] or "") |
| 215 | if match: |
| 216 | result = True |
| 217 | |
| 218 | for _ in match.groupdict(): |
| 219 | if match.group(_): |
| 220 | waf = re.sub(r"\Awaf_", "", _) |
| 221 | locked_regex = DATA_JSON["wafs"][waf]["regex"] |
| 222 | locked_code = intrusive[HTTPCODE] |
| 223 | break |
| 224 | else: |
| 225 | result = False |
| 226 | |
| 227 | if not result: |
| 228 | exit(colorize("[x] can't lock results to a non-blind match")) |
| 229 | else: |
| 230 | result = re.search(locked_regex, intrusive[RAW]) is not None and locked_code == intrusive[HTTPCODE] |
| 231 | elif options.string: |
| 232 | result = options.string in (intrusive[RAW] or "") |
| 233 | elif options.code: |
| 234 | result = options.code == intrusive[HTTPCODE] |
| 235 | else: |
| 236 | result = intrusive[HTTPCODE] != original[HTTPCODE] or (intrusive[HTTPCODE] != 200 and intrusive[TITLE] != original[TITLE]) or (re.search(protection_regex, intrusive[HTML]) is not None and re.search(protection_regex, original[HTML]) is None) or (difflib.SequenceMatcher(a=original[HTML] or "", b=intrusive[HTML] or "").quick_ratio() < QUICK_RATIO_THRESHOLD) |
| 237 | |
| 238 | if not payload.isdigit(): |
| 239 | if result: |
| 240 | if options.debug: |
| 241 | print("\r---%s" % (40 * ' ')) |
| 242 | print(payload) |
| 243 | print(intrusive[HTTPCODE], intrusive[RAW]) |
| 244 | print("---") |
| 245 | |
| 246 | if intrusive[SERVER]: |
| 247 | servers.add(re.sub(r"\s*\(.+\)\Z", "", intrusive[SERVER])) |
| 248 | if len(servers) > 1: |
| 249 | chained = True |
| 250 | single_print(colorize("[!] multiple (reactive) rejection HTTP 'Server' headers detected (%s)" % ', '.join("'%s'" % _ for _ in sorted(servers)))) |
| 251 | |
| 252 | if intrusive[HTTPCODE]: |
| 253 | codes.add(intrusive[HTTPCODE]) |
| 254 | if len(codes) > 1: |
no test coverage detected
searching dependent graphs…