TechEarl

The Equifax Breach: An Unpatched Bug and a Blind Sensor

In 2017, attackers exploited an unpatched Apache Struts remote code execution flaw to breach Equifax and steal the data of 147 million people. A patch had been available for months, and an expired certificate had blinded the network monitoring for 19 months. A post-mortem of the RCE attack chain and the failures around it.

Ishan Karunaratne⏱️ 9 min readUpdated
Share thisCopied
How the 2017 Equifax breach exploited an unpatched Apache Struts RCE (CVE-2017-5638) to steal 147M records, and how an expired cert blinded detection.

In 2017, attackers breached Equifax, one of the three major US credit bureaus, and stole the personal data of about 147 million people, including names, Social Security numbers, dates of birth, and addresses. The way in was a remote code execution vulnerability in Apache Struts, CVE-2017-5638, for which a patch had been available for over two months and which Equifax had been specifically warned to apply. Once inside, the attackers operated for months largely undetected, because a digital certificate on Equifax's traffic-monitoring system had been expired for nineteen months, leaving the sensor that should have caught the data theft effectively blind.

This is the case I use to teach two lessons at once: that an unpatched, publicly-known RCE is one of the most dangerous things you can run, and that detection which is silently broken is worse than no detection at all, because everyone assumes it is working.

The vulnerability: CVE-2017-5638

The root bug is a clean example of remote code execution through injection. Apache Struts is a Java web framework, and CVE-2017-5638 was a flaw in how its Jakarta Multipart parser handled the Content-Type HTTP header. By sending a crafted Content-Type value containing an OGNL (Object-Graph Navigation Language) expression, an attacker could get the server to evaluate that expression, which is to say, run code of the attacker's choosing on the server. It is the same family of "untrusted input parsed as code" failure as server-side template injection, with OGNL as the interpreter.

Crucially, this was not a zero-day at the time of the breach. The Apache Struts project disclosed the vulnerability and released a fixed version in early March 2017, with a public advisory (S2-045). The US Department of Homeland Security separately notified organisations, including Equifax, to patch it. Exploitation in the wild began within days of disclosure. By the time the attackers used it against Equifax, the patch had existed for weeks.

The attack chain

Editorial illustration of the Equifax breach: an unlocked door in a wall, a figure slipping through, a watchtower whose eye is closed, and document files streaming out unseen behind it.
An unpatched door, an intruder, and a blinded watchtower: the monitoring that should have caught the theft had been dead for nineteen months.
  1. The unpatched portal. Equifax ran an online dispute portal (a public-facing web application) on a version of Apache Struts that was still vulnerable to CVE-2017-5638. Despite the advisory and the DHS notification, the patch was not applied to this system.
  2. Remote code execution. In mid-May 2017, attackers exploited the Struts flaw to run code on the dispute-portal server, giving them a foothold inside Equifax's environment.
  3. Credentials and lateral movement. On that server and nearby, the attackers found credentials stored in plaintext. They used them to move laterally across a network that was not well segmented, reaching far beyond the single compromised application into around fifty databases.
  4. Months of quiet exfiltration. Over roughly ten weeks, the attackers ran thousands of queries and exfiltrated the data in small, encrypted chunks to blend in with normal traffic. They were able to do this for months because the monitoring that should have flagged it was not working.

The detail that defines the case: a blind sensor

The single most instructive failure is not the unpatched server, common as that is. It is why the breach went undetected for so long.

Equifax inspected the encrypted traffic leaving its network using a device that needed a valid digital certificate to decrypt and examine that traffic. That certificate had expired about nineteen months earlier and had not been renewed. For nineteen months, the system that was supposed to be watching outbound traffic for exactly this kind of data theft was passing it through without looking, because it could not decrypt what it was meant to inspect.

The breach was discovered on 29 July 2017, and the way it was discovered is the lesson in one sentence: Equifax renewed the expired certificate, the monitoring system started inspecting traffic again, and it immediately surfaced the suspicious activity that had been flowing out unseen. The attack was not stealthy in some sophisticated sense. The alarm had simply been unplugged, and the moment it was plugged back in, it went off.

This is why I treat "is our monitoring actually working?" as a question you have to verify, not assume. A detection control that has silently failed gives you the confidence of coverage with none of the protection, which is the worst of both.

The scale and the aftermath

FigureWhat it was
~147 millionPeople whose personal data was exposed.
Names, SSNs, DOB, addressesThe core data taken, the full kit for identity theft.
~209,000Credit card numbers also exposed.
At least $575M, up to $700MThe 2019 settlement with the FTC, CFPB, and US states.

The data taken was uniquely damaging because of what Equifax is: a credit bureau holds exactly the identifiers (Social Security numbers, dates of birth) that are used to verify identity, and unlike a password, you cannot change your SSN after it leaks. The regulatory and political response was severe: a settlement of up to around $700 million, the departure of the CEO, CIO, and chief security officer, and a Congressional investigation whose report read as a catalogue of preventable failures. In 2020, the US Department of Justice indicted four members of the Chinese military over the intrusion.

The lessons I take from it

Patch known RCEs immediately, and verify the patch reached every system. The vulnerability had a patch and a public warning. The failure was operational: Equifax did not get the fix onto the vulnerable dispute portal. A publicly-known remote code execution flaw on an internet-facing system is an emergency, and "we issued the patch instruction" is not the same as "every affected system is patched." You need an inventory accurate enough to know what you run and confirmation that the fix actually landed.

Verify that detection is alive. The expired certificate is the detail to carry into your own environment. Monitoring, logging, and inspection controls fail silently, and a dead sensor looks exactly like a quiet network. Test your detection: confirm certificates are current, confirm logs are flowing, confirm the alerts fire. A control you have not verified recently is a control you are only assuming you have.

Segment the network and never store plaintext credentials. The RCE compromised one application. What turned that into 147 million records was a flat network and plaintext credentials that let the attackers roam. Segmentation and proper secrets management would have contained the foothold. This is the same lesson as the Heartland breach: the entry bug is rarely the whole story, and the blast radius is decided by what the attacker can reach next.

RCE is the worst case, so treat its inputs accordingly. Remote code execution collapses the gap between "a bug in one app" and "the attacker runs the company's servers." Any framework or library that parses untrusted input is a candidate, and keeping that dependency patched is not optional maintenance, it is front-line security.

Where to go next

For the mechanics of the bug class, the remote code execution deep dive covers how untrusted input becomes code execution and how to defend against it, with server-side template injection as the closest cousin of the OGNL flaw here. The other RCE case study in this cluster is Log4Shell, where a vulnerability in a logging library produced mass exploitation. For the full set of web attack classes, see the web application security vulnerabilities taxonomy.

Sources

Authoritative references this article was fact-checked against.

TagsSecurityRCERemote Code ExecutionEquifaxApache StrutsCase Study

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Software Systems Architect · Senior Software Engineer · Engineering Leadership

Software systems architect and senior software engineer with more than two decades designing, building, and running production software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Now a CTO, though what I write here is drawn from the full arc of that work, across architecture, engineering, and operations, not any single job.

Keep reading

Related posts

How the 2022 Uber breach used MFA fatigue plus a WhatsApp pretext, then a hardcoded admin credential in a PowerShell script to reach the PAM vault. The lessons.

The 2022 Uber Breach: MFA Fatigue and a Hardcoded Password

In September 2022, an attacker spammed an Uber contractor with MFA prompts, then messaged them on WhatsApp pretending to be IT to get one approved. Inside, they found a hardcoded admin password in a script that unlocked Uber's secrets vault. A post-mortem of the MFA-fatigue attack chain.

How the 2019 Capital One breach used SSRF to reach the AWS EC2 metadata service, steal IAM credentials, and exfiltrate 100M+ records. Why IMDSv2 exists.

The Capital One Breach: SSRF and the Cloud Metadata Service

In 2019, a misconfigured firewall let an attacker use SSRF to reach the AWS metadata service, steal the server's IAM credentials, and exfiltrate the data of over 100 million Capital One applicants. It is the canonical cloud-SSRF breach and a prominent example of the attack class IMDSv2 was designed to mitigate. A post-mortem of the attack chain.