Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce false positives (those caused by WAFs and bot detection) #2069

Merged
merged 3 commits into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions sherlock/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ def update(self, result):
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 + " Blocked by bot detection" +
Fore.YELLOW + " (proxy may help)")

else:
# It should be impossible to ever get here...
Expand Down
1 change: 1 addition & 0 deletions sherlock/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions sherlock/sherlock.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,20 @@ 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
'{return l.onPageView}}),Object.defineProperty(r,"perimeterxIdentifiers",{enumerable:' # 2024-04-09 PerimeterX / Human Security
]

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
Expand Down
Loading