PhishCatch: Detecting password reuse from the inside out
A browser extension to enforce password hygiene
In an effort to bolster Palantir’s password hygiene, our Information Security team, with deep collaboration from our friends at SpecterOps, sought to create a solution for detecting password reuse even when endpoints aren’t in-scope for detection via network telemetry. This became doubly urgent with COVID-19 and the shift to remote work for the vast majority of our employees. For example, many Palantirians simply don’t have the necessary network or bandwidth to use a full-tunnel VPN. As a result, our full spectrum of network security controls and detections, including our password reuse detection, may only apply to a small portion of their network traffic.
Upon considering several means of approaching the issue, we found that a browser extension most effectively served the purpose of reducing password reuse and phishing risk across our fleet. At its core, PhishCatch (GitHub) is a browser extension which compares passwords used for corporate resources to passwords used elsewhere, but in a more robust and versatile manner than similarly-described tools that have come before. This blog post explains our motivations for building PhishCatch and describes how it works under the hood.
PhishCatch is available now in the Chrome Web Store. Moreover, as part of our commitment to open-source security, we are releasing PhishCatch source code, policy templates, and related documentation on our public GitHub page. We are extending our responsible disclosure program to include PhishCatch within the scope, and are committing to undergoing, and releasing the results of, periodic application security assessments to validate the security of the extension. It is our deepest hope that other network defenders will be able to use PhishCatch to help protect their environments against phishing and poor credential hygiene.
Password reuse in the enterprise
Good password hygiene (or lack thereof) is a practice with exceedingly consequential impact on the security posture of any organization. Improvements to authentication workflows, such as mandatory multifactor authentication, password audits and banned lists, account lockout thresholds, and passwordless authentication have made account compromise both more difficult and less damaging. However, most systems still fundamentally rely on passwords for authentication.
Browsers are increasingly the primary location for both business and personal tasks, often simultaneously. Desktop applications and command-line interfaces serve more specialized functions, but most users spend their days interacting with enterprise and productivity applications solely through their browser. Single sign-on (SSO) has helped enterprises manage the authentication complexity inherent to the web ecosystem, but this also concentrates risk into a single point of “phishable” failure.
A December 2019 study from Google indicated that only 35% of respondents used a unique password for every account they used — perhaps even more alarming was the 13% of people who reused the same password on every account.
In a traditional (meaning, pre-COVID) office environment, security teams could implement security tools at the network perimeter for controlling and monitoring employee behavior. These tools, in more sophisticated setups, perform decryption of network traffic to identify password reuse or theft. Now that working remotely is the new norm, traditional password reuse detection strategies are subverted or outright irrelevant.
To better understand the scope of the problem, let’s first take a look at the current risk landscape:
Three ways passwords get leaked
Password leaks rarely occur in a vacuum — human behavior is the primary element, whether triggered intentionally or through simple human error.
Intentional account compromise: A bad actor wants your password, and devises a method to trick you into giving it away. Most commonly, this is in the form of a phishing email that prompts the user to visit a fake login page, where the victim enters their real credentials.
Password reuse: Computer systems expect people to choose passwords according to rules that are explicitly difficult for humans to memorize. A common practice in the real world is to create a handful of passwords that meet most complexity requirements and rotate between them as necessary. Unfortunately, this also means that a breach of one location results in the potential breach of every other location — a particularly troublesome business risk if one of those reuse locations is the corporate environment.
Muscle memory: Who among us hasn’t absent-mindedly entered a real password in the wrong place? The login fails, you chuckle at the error, and go about your day — no harm done, right? Despite the failed authentication, there is no way of having total assurance that a leak didn’t occur. The site may log all authentication attempts in plaintext, it may be running a keylogger, or any number of other potential issues. Nobody enjoys rotating their password, but even from this silly mistake one must assume breach.
Three ways leaks can be stopped
Fortunately, human behavior can be somewhat anticipated and lovingly redirected toward a desired outcome — or at least monitored for when something does go wrong.
Prevent the phish: Proper security tooling can protect the user from being a victim of threat actors. Spam filters can stop the phish before it ever reaches an inbox, and web filters can restrict access to suspicious domains before the user makes a poor decision. However, these tools are largely reactive and may not be able to anticipate a novel approach taken by a bad actor.
Train the user: Most organizations require some amount of security awareness training, often coupled with sanctioned phishing campaigns to test and train their employees. The most robust solution to combat password reuse is a digital password manager such as 1Password or LastPass, which generate and store strong, unique passwords for as many platforms as needed. Unfortunately, password managers are not widely used, particularly by careless or less savvy users (the ideal targets for attackers).
Detect the leak: Services like Have I Been Pwned? will monitor data breaches for user information, but this is inherently a last-ditch effort to detect compromises. Many breaches never become public knowledge, and it can be difficult trace back the origins of a specific leak. A more advanced and real-time option is to monitor network traffic at the corporate network perimeter. Network traffic can be inspected, decrypted, and password submissions compared against hashed domain passwords. This strategy is complex, requires substantial hardware, necessitates the organization manage public-key infrastructure, and introduces severe privacy concerns.
Three ways controls fail
Unfortunately, even the best security measures can be inaccurate, trivially bypassed, or are simply not robust enough to correctly handle unanticipated edge cases.
Email compromise: A legitimate email address is taken over by a bad actor and used to send phishing emails. These emails may slip by security tooling, and any previously established relationship lends legitimacy to the request.
Domain reuse: A known and previously-trustworthy external domain is taken over by a bad actor, possibly because the owner neglected to renew the domain, or because the bad actor was able to surreptitiously upload their own content without being detected. Alternatively, malicious content can be hosted on generic shared web hosting domains such as azurewebsites.net. These domains are unlikely to be detected and blocked by web content filters rapidly enough to prevent abuse.
Monitoring circumvented: Security tooling and monitoring at the network perimeter is quite brittle. Organizations may opt to not monitor network traffic to sensitive website categories, such as banking or healthcare, for privacy concerns — something a motivated bad actor can leverage by getting a benign site categorized in advance and swapping to malicious content later. It is also trivially easy for password submissions to go unnoticed, either because the submission wasn’t denoted in an expected way, or because passwords may not be submitted by the website in plaintext. Finally, and most obviously, no amount of network-based security tooling will protect the user if they’re not on the network — in the current world of all-remote, all-the-time, everyone is a dropped VPN away from being unprotected.
Goals for a new security tool
Keeping in mind both the current risk landscape and the end-users’ most likely behaviors, we developed a framework that we believe the PhishCatch browser extension and alerting server is well-suited to address.
Our technical goals were:
- Detect password reuse events regardless of network status:
Protections remain in place even while not connected to the corporate network, such as while off VPN or away from the office, without necessarily mandating any corporate internet-facing infrastructure that may create an additional attack surface. - All reuse detection is performed locally:
Credentials are never sent over the wire in any form — period. There should be effectively no additional risk if a malicious actor is able to snoop on any network traffic from the endpoint. - Support multiple credential pairs:
Most existing password reuse tooling assumes that employees only have one corporate password, but this doesn’t support the best practice of segregated accounts for privileged or sensitive workflows. - Minimize false positives:
This is most important for incident response teams that may respond to alerts, but it’s also critical end users don’t experience unnecessary friction. - Stretch goal: Prevent leaks from happening in the first place:
Reduce the number of security incidents caused by password leaks or reuse. This is an ideal outcome for incident responders and users alike.
We also had some ideological goals around trustworthiness and usability:
- Maintain privacy of personal accounts:
Employees are rightfully concerned about their privacy, so we wanted fundamental assurance that the users’ personal credentials remain private — without compromising corporate security. - Low-lift deployment and configuration management:
Make testing and updating the tool as simple as possible for the security team deploying — no new dashboards, bespoke query languages, or coding necessary. - Frictionless user experience:
No user interaction is required for the tool to function — after all, an invisible security tool is a tool that a frustrated user doesn’t feel compelled to bypass.
Debuting PhishCatch
PhishCatch is an open-source Chrome browser extension and backend alerting API server, for identifying and preventing enterprise password leaks.
Detecting password reuse in the browser
The primary configuration in PhishCatch is a list of enterprise domains where the user is expected to enter their corporate credentials. This list will likely include the organization’s primary identity provider, such as Azure AD, Active Directory Federation Services, Salesforce, Okta, etc., but may also include standalone domains where single-sign on is not enabled.
When credentials are entered on a site on the enterprise domains list, PhishCatch captures the password entry, hashes it, and stores the hash locally (i.e., in browser storage) with a per-secret salt. PhishCatch also saves the entered username associated with that domain. This data is saved in the browser storage for a default of 30 days before expiring, although this rolling window can optionally be configured for any duration.
When credentials are entered on a site not on the enterprise domains list, PhishCatch again captures the password entry, but this time hashes using the salt from the stored enterprise hash, then compares the resulting hash to the stored enterprise hash. If there is a match, this indicates that the corporate password has been entered on a non-corporate domain, and a reuse alert (more on this below) is triggered. If multiple enterprise hashes are stored, PhishCatch uses the salt from each hash in turn in order to compare against each uniquely-salted hash.
PhishCatch hashes and compares passwords entered into non-enterprise domains with each keystroke, rather than waiting for the entry to be complete, so that external passwords that merely contain the enterprise password can also be identified. This is function is multithreaded and entirely separated from the page rendered in the browser, so user experience is not impacted and the attack surface for timing attacks is minimized.
PhishCatch also hashes usernames entered on non-enterprise domains and compares it to the cached hashes. This detects and prevents users from accidentally entering their password into username fields. As username fields are generally not hashed or otherwise protected in event logs, this helps prevent further plaintext leakage of credentials.
Hashes from non-enterprise domains are never stored locally or transmitted remotely. Only enterprise domain password hashes are cached locally, and all comparisons are performed locally, therefore maintaining end user privacy across all domains as well as minimizing the need for external computational resources.
Alerting on password reuse
PhishCatch has two configurable alert mechanisms.
Endpoint alerts immediately notify the impacted user with a popup notification, so they can take action accordingly.
Remote alerts are more useful for security teams and monitoring at scale. The PhishCatch extension is designed to send alert metadata such as username, external domain name, and timestamp to a backend server via an API call. The server can be natively configured to then relay incoming alerts into webhooks for Slack or Microsoft Teams. The server logs can be directly monitored by the security team or ingested into a SIEM, such as Splunk or Elastic.
The browser extension and the API server will need to be configured with the same pre-shared key (PSK), in order to provide a baseline measure of abuse prevention. We are currently investigating stronger authentication mechanisms to help prevent opportunistic abuse.
Only metadata about the reuse event (username, external domain, referrer, timestamp, etc.) is sent to the server for logging and alerting. Hashes are only stored locally and are never sent to the PhishCatch server or any other external location.
If the PhishCatch server cannot be reached, the extension will cache the alert and attempt to retransmit them periodically. This is useful if the PhishCatch server can only be reached while on a corporate VPN, or if the route or network connection is temporarily down.
How passwords are protected
PhishCatch uses PBKDF2, a well-known bruteforce resistant key derivation function, before saving to browser storage. By default, it performs 100,000 iterations of salted PBKDF2-HMAC-SHA512 hashing, although this can be configured with a custom value. This hashing configuration is similar to the hashing performed on a master password in 1Password. PhishCatch also optionally truncates stored hashes to further increase the difficulty of reversing stored hashes.
PhishCatch uses Chrome storage to save enterprise hashes to disk. This storage is not accessible to websites or other extensions. The PhishCatch dev team does not believe that PhishCatch’s code contains any browser-originated vulnerabilities (such as cross-site scripting) that would allow attackers access to stored hashes. Furthermore, were an attacker able to gain access to your computer’s disk directly, we believe it would be technically infeasible to reverse the hashes at this time.
Personal passwords, or more generally passwords entered on sites not listed as an enterprise domain, are only hashed in memory and never persisted to disk.
Proactively preventing password leaks
Part of our goal for the PhishCatch extension was to help users recognize a malicious website before they enter their password.
PhishCatch achieves this by taking a representative hash of a visited enterprise domain’s HTML code, known as a fuzzy DOM hash, and storing it locally. The extension then performs the same hashing against external domains and compare. This can identify cloned or visually similar domains, potentially identifying a phishing campaign before the user does.
As with password reuse alerts, only hashes for enterprise domains are stored locally, and if an alert is triggered by a matching hash, only metadata about the event is sent to the API server.
Deploying PhishCatch at scale
The extension uses Chrome management schema to obtain deployment configuration settings. These settings should be deployed using the appropriate enterprise management mechanism for the endpoint: Group Policy for domain-joined Windows systems, Jamf Pro configuration profile for managed macOS systems, or other configuration deployment systems.
This has several distinct advantages:
- No configuration data is hard-coded in the extension:
PhishCatch can be installed directly from the Chrome Web Store, and there is no need to edit and build your own copy of the extension from source. If you would prefer to build and deploy your own copy of the extension, the source code is available in our public GitHub repo. - No custom administrative dashboards:
All configuration is performed directly in the enterprise management platform you’re already using. - No accounts:
The extension doesn’t need to be onboarded to your single-sign on provider and stores no access tokens — only a plaintext PSK deployed via configuration management if using the (optional) API server. - No action required from the end user:
The PhishCatch extension is a passive, invisible addition to the user’s web browsing experience (until an alert is triggered!).
Very few other Chrome extensions leverage enterprise management to this extent, but we think this provides the best experience for both the organization and the end user.
Here at Palantir, we use the webhook integration to keep tabs on phishing reports as they occur. We additionally ingest the PhishCatch logs into our SIEM and use security automation to directly ping users and, if a phish or credential reuse event is confirmed, help them walk through the credential rotation process.
Where to find PhishCatch
We have deployed PhishCatch with great success internally at Palantir, but development remains ongoing and we’re always interested in hearing feedback, issues, or unaddressed edge cases.
Extension source code, API server Docker image, and deployment policy templates are available in our public GitHub repo:
https://github.com/palantir/phishcatch
Documentation, including feature details, installation and configuration settings, and enterprise rollout recommendations are available in the GitHub wiki: https://github.com/palantir/phishcatch/wiki
The extension is available for install from the Chrome Web Store: https://chrome.google.com/webstore/detail/phishcatch/jgegnlkclgfifjphjmijnkmicfgckmah
Contributors
Authors: Tyler B, Eason G, Dane S
Additional contributors and acknowledgements: https://github.com/palantir/phishcatch/wiki/Acknowledgements