A Technical Analysis of the Capital One Hack

CloudSploit
CloudSploit
Published in
6 min readAug 2, 2019

The recent disclosure of yet another cloud security misconfiguration leading to the loss of sensitive personal information made the headlines this past week. This particular incident came with a bit more information from the indictment of the accused party, allowing us to piece together the revealed data and take an educated guess as to what may have transpired leading up to the loss of over 100 million credit card applications and 100 thousand social security numbers.

This Keeps Happening

At the root of the hack lies a common refrain: the misconfiguration of cloud infrastructure resources allowed an unauthorized user to elevate her privileges and compromise sensitive documents. Similar incidents have made the news over the past 2–3 years, including the high-profile leak of nearly 200 million voter records, terabytes of classified documents from the pentagon, and half-a-billion Facebook profiles.

Gaining a Foothold

According to the 12-page indictment (PDF), this compromise originated with the invocation of arbitrary user requests on a server ran by Capital One in its AWS account. The indictment does not detail the specific vulnerability that enabled these commands, but most signs point to it being a Server-Side Request Forgery (SSRF) attack. An SSRF attack tricks a server into executing commands on behalf of a remote user, enabling the user to treat the server as a proxy for his or her requests and get access to non-public endpoints.

Server-Side Request Forgery

The AWS Metadata Service

Because this server was hosted in AWS, it has access to a unique URL known as the metadata service, accessible at http://169.254.169.254. Typically, this URL is used to provide an HTTP API for node-level information such as the node’s IP address, placement within the AWS network, and hostname. This endpoint is a very useful service for developers of applications in the AWS cloud.

One particularly important function of the metadata service is to provide temporary credentials that give the node access to other AWS services based on a permission policy defined in the instance’s IAM role. IAM roles are an alternative to long-lived user access keys and secrets; rather than hard-coding an access key into an application’s configuration, the application simply requests credentials from the metadata endpoint periodically. All of AWS’s SDKs handle this request automatically via a chain of checks in which they look for the presence of credentials in environment variables, a config file, locally within the application code, or via the metadata endpoint.

Elevating Access

By combining the SSRF attack from earlier with the knowledge that an AWS EC2 server has access to a metadata endpoint containing temporary credentials, the attacker was able to trick the server into making a request to the following URL:

http://169.254.169.254/iam/security-credentials

This endpoint returned a role name, which the indictment lists as “*****-WAF-Role,” implying that the accessed server was likely a web application firewall on Capital One’s network.

Armed with the role name, the attacker then queried the full endpoint:

http://169.254.169.254/iam/security-credentials/*****-WAF-Role

which returned a full set of temporary credentials originally assigned to the EC2 instance itself:

{
AccessKeyId: "<access key>",
SecretAccessKey: "<secret key>",
}

These are standard AWS credentials that can be used to access the AWS APIs via the AWS CLI or any SDK. Because the IAM role did not have additional conditions attached to it that prevented it from being used outside of the Capital One network, anyone on the planet could use those credentials to sign their own API requests to the AWS API as if they were the EC2 instance inside the network.

Putting It All Together

According to the indictment, once the attacker gained access to these credentials, she ran the AWS S3 “ListBuckets” command. For this to work, the IAM role policy needed to allow this API call via the permissions defined in its IAM policy. The indictment does not outline the exact permissions that were assigned, but we can assume that it allowed at least this API call, if not many others. For example, the following policy would have been sufficient to enable this attack.

{
"Effect": "Allow",
"Actions": [
"s3:ListBuckets",
"s3:Sync"
],
"Resource": "*"
}

After running s3:ListBuckets, a full list of all of the AWS S3 buckets in the compromised account would have been printed.

$ aws s3 ls
2019-08-01 11:01:10 bucketone
2019-08-01 12:00:23 buckettwo

The indictment mentions that this command was run several times. The AWS s3:Sync command was then used to copy the data from these buckets onto the local machine of the attacker and the result is wall-to-wall unfavorable media coverage.

$ aws s3 sync s3://bucketone .

What Went Wrong?

Ultimately, this attack was the result of a vulnerability combined with a misconfiguration. The SSRF attack used to obtain access to the metadata endpoint is the key that made this entire scenario possible, but the subsequent misconfiguration turned that vulnerability into a full compromise.

Security is a layered approach — often referred to as the security onion. Once the attacker had gained access to the instance’s IAM credentials, she then took advantage of a considerable misconfiguration — the fact that this instance had excessive permission to list and access data in a large number of S3 bucket locations.

While it may be easy to blame Capital One’s developers for the loss of data, the truth is that IAM role misconfigurations are likely present in nearly every single AWS account. Very few developers take the time to carefully list each permission required; oftentimes a wildcard is used in many more places than it should be, resulting in unintended access. Without a compromising factor, this misconfiguration is likely to go unnoticed indefinitely.

One could also argue that there was not sufficient monitoring in place to detect the initial access of the credentials from outside of Capital One’s network. Based on the indictment’s analysis, we can conclude that CloudTrail logging was enabled. These logs would have indicated that the role was being accessed externally, potentially with sufficient time for someone to respond and deactivate the role’s permissions.

What Went Right?

While this was inarguably a terrible situation, the fact that Capital One was able to locate the exact requests in question meant they were at least following the best practices of enabling CloudTrail logs.

Additionally, whereas a number of previous incidents resulted from S3 bucket permissions that enabled direct public access, that does not appear to be the case here; the attacker was able to gain internal access via an externally-facing vulnerability.

Protecting Yourself

If we had to take a guess, we would wager that a solid majority of AWS accounts are vulnerable to at least half of what is described above. Creating tightly-scoped IAM policies is time consuming and can make adding additional functionality to an application in the future difficult.

At a minimum, consider the following recommendations:

  1. Ensure each application, EC2 instance, or autoscaling group has its own IAM role. Do not share roles across unrelated applications.
  2. Scope the permissions of each role to enable access only to the AWS resources required. The “WAF” role described above did not require access to list S3 buckets “in the normal course of business” (according to the indictment).
  3. If possible, include a “Condition” statement within the IAM role to scope the access to known IP addresses or VPC endpoints.
  4. Ensure AWS CloudTrail is enabled in all regions and for all services. If you have particularly sensitive data stored within S3 (social security numbers certainly qualify!) be sure to also enable read-level logs for S3 bucket objects.
  5. Monitor CloudTrail logs for suspicious activity, including access to APIs from IPs outside of the known network addresses.
  6. Continue to audit web applications for application security vulnerabilities, and remember that cloud-based applications have access to additional endpoints and services due to their integration into the broader AWS ecosystem.

Conclusion

Security in the cloud can be incredibly challenging. As we have seen with this hack, as well has scores of others over the past few years, sometimes all it takes for a company to lose millions of records or customer data is the presence of an asterisk in an IAM policy. Continuing to audit and monitor for these issues is paramount to maintaining a secure environment.

CloudSploit is a provider of open-source and SaaS-based cloud security monitoring software for AWS, Azure, Oracle, and Google Cloud.

--

--