From d660c1a2dd049bb5a26e21135c411be6646f12cd Mon Sep 17 00:00:00 2001 From: Paul Pfeister Date: Mon, 8 Apr 2024 18:07:14 -0400 Subject: [PATCH] Filter WAF Hits --- sherlock/notify.py | 11 ++++++++++- sherlock/result.py | 1 + sherlock/sherlock.py | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/sherlock/notify.py b/sherlock/notify.py index 87bfa0b..65502ab 100644 --- a/sherlock/notify.py +++ b/sherlock/notify.py @@ -224,7 +224,7 @@ class QueryNotifyPrint(QueryNotify): elif result.status == QueryStatus.UNKNOWN: if self.print_all: print(Style.BRIGHT + Fore.WHITE + "[" + - Fore.RED + "-" + + Fore.RED + "?" + Fore.WHITE + "]" + Fore.GREEN + f" {self.result.site_name}:" + Fore.RED + f" {self.result.context}" + @@ -238,6 +238,15 @@ class QueryNotifyPrint(QueryNotify): Fore.WHITE + "]" + Fore.GREEN + f" {self.result.site_name}:" + Fore.YELLOW + f" {msg}") + + elif result.status == QueryStatus.WAF: + if self.print_all: + print(Style.BRIGHT + Fore.WHITE + "[" + + Fore.RED + "?" + + Fore.WHITE + "]" + + Fore.GREEN + f" {self.result.site_name}:" + + Fore.RED + f" Blocked by WAF" + + Fore.YELLOW + " (proxy recommended)") else: # It should be impossible to ever get here... diff --git a/sherlock/result.py b/sherlock/result.py index 6e6ddc1..c4d68b1 100644 --- a/sherlock/result.py +++ b/sherlock/result.py @@ -14,6 +14,7 @@ class QueryStatus(Enum): AVAILABLE = "Available" # Username Not Detected UNKNOWN = "Unknown" # Error Occurred While Trying To Detect Username ILLEGAL = "Illegal" # Username Not Allowable For This Site + WAF = "WAF" # Request blocked by WAF (i.e. Cloudflare) def __str__(self): """Convert Object To String. diff --git a/sherlock/sherlock.py b/sherlock/sherlock.py index fb9f524..93fafff 100644 --- a/sherlock/sherlock.py +++ b/sherlock/sherlock.py @@ -378,9 +378,19 @@ def sherlock( query_status = QueryStatus.UNKNOWN error_context = None + # As WAFs advance and evolve, they will occasionally block Sherlock and lead to false positives + # and negatives. Fingerprints should be added here to filter results that fail to bypass WAFs. + # Fingerprints should be highly targetted. Comment at the end of each fingerprint to indicate target and date. + WAFHitMsgs = [ + '.loading-spinner{visibility:hidden}body.no-js .challenge-running{display:none}body.dark{background-color:#222;color:#d9d9d9}body.dark a{color:#fff}body.dark a:hover{color:#ee730a;text-decoration:underline}body.dark .lds-ring div{border-color:#999 transparent transparent}body.dark .font-red{color:#b20f03}body.dark .big-button,body.dark .pow-button{background-color:#4693ff;color:#1d1d1d}body.dark #challenge-success-text{background-image:url(data:image/svg+xml;base64,' # 2024-04-08 Cloudflare + ] + if error_text is not None: error_context = error_text + elif any(hitMsg in r.text for hitMsg in WAFHitMsgs): + query_status = QueryStatus.WAF + elif error_type == "message": # error_flag True denotes no error found in the HTML # error_flag False denotes error found in the HTML