In this article, we cover the details of a heavily distributed credential-stuffing attack that targeted a major US financial service company (spoiler: there were some pretty clear signs of device spoofing, as you'll see below). By the end of the bot attack, which lasted 6 days, Castle blocked more than 11.8M malicious login attempts.
Credential stuffing attack metrics
- Date: from December 7th around ~3 am UTC lasted until December 13th 0:30am UTC
- Attack duration: 6 days
- Endpoint targeted: login
- Type of attack: credential stuffing
- Volume of requests: 11,804,332 malicious login events
- Maximum velocity: 208k login events per hour
- Number of IPs involved: 2,217,488 IP addresses
Credential stuffing attack overview
As a reminder, credential stuffing is the act of trying large amounts of stolen credentials with the purpose of gaining unauthorized access to accounts (account takeover). The attacker made 11,804,332 login attempts over more than 6 days, and the attack reached a spike of a whopping 208k login attempts per hour on December 10th. For reference, the regular login volume is about 10k per hour.
The attacker mostly used IP addresses located in the US. Since the financial platform targeted is a US-based company, this is a common technique used by attackers: they often rely on proxies located in the same country as the website they target to stay under the radar and avoid triggering traditional detection techniques such as geo-blocking.
More specifically, the attacker leveraged mostly US American IPs / US residential proxies that belong to well-known ISPs such as Comcast and AT&T. These IP addresses have a better reputation than cheaper data center proxies that may be blocked more quickly.
The graph below shows the evolution of the number of unique IP addresses per hour used by the attacker. We see that during the bot attack, the attacker was often using more than 100K distinct US-based residential IPs per hour to spread their attack.
Proxies are a key component of credential-stuffing attacks. It enables bots to spread their attack across thousands of IPs addresses, which avoids being detecting by simple IP-based rate-limiting techniques.
Attack Indicators of Compromise (IoCs)
The attacker used different techniques to minimize their chances of being detected, such as forging its bot device fingerprints and using US residential proxies to distribute the attack.
- The attacker used the latest Chrome on Windows user agent
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
- Bots sent a non-standard
Accept-Language
HTTP header that looks as followsen-300698689559436,en;q=0.9
. The number followingen-
is randomized, certainly to escape static WAF signatures. - The attacker had HTTP headers consistent with the latest Chrome. For example, they were properly sending the
Priority:u=0, i
HTTP header - Bots executed JavaScript and had relatively clean device fingerprints (absence of
navigator.webdriver = true
and CDP detection) - Bots operated in low and slow mode. They made a low volume of requests per IP, ~15 per day spread across the day
How did Castle block the attack?
Castle’s detection uses a multi-layered approach to ensure that even if attackers properly forge their device fingerprints or use clean residential proxies, it still detects malicious bot traffic.
In the case of this attack, the attacker was detected by a combination of signals and approaches:
- Abnormal behavior: Even though the volume of requests per IP was relatively low, it didn’t match the usual website patterns. Moreover, IPs involved in the attack had a high percentage of failed login attempts.
- Device fingerprinting inconsistencies: The attacker forged its device fingerprint to escape detection. However, it was not done consistently.
- There was a mismatch between the user agent collected on the client side using JavaScript and the user agent collected on the server side using the HTTP headers.
- The
navigator.productSub
property was overridden with bogus data related to the WebGL renderer.
- Contextual inconsistencies and weak signals: Castle’s detection ML models were able to leverage the mismatch between the user timezone and the IP location. While this is not enough to block traffic, this contributes negatively to the user confidence score.
- Forged HTTP header: the attacker forged the
Accept-Language
header as follows,en-300698689559436,en;q=0.9
by adding a randomized number in it, probably to avoid triggering classical WAF signatures. This randomization was detected - IP reputation and proxy detection: even though the attacker leveraged thousands of American residential proxies to distribute their attack, most of the IP addresses used were flagged as proxies.
Conclusion
Credential stuffing attacks can significantly strain server resources and pose a serious risk of account takeovers. These incidents can harm the brand reputation and degrade the customer experience. While such attacks can originate from a small number of IP addresses, attackers increasingly rely on residential proxies to highly distribute their attacks and to evade defenses.
Traditional bot detection techniques such as geo-blocking and IP-based rate limiting are not enough against today’s attackers. This is why Castle uses a multi-layered approach that leverages advanced machine learning (ML) with all signals available: from device fingerprint to advanced residential proxy detection and user behavioral analysis.