Ransomware in AWS S3: SSE-C

January 19, 2025
Jason Kao

Recently, there's been coverage and reports of ransomware in cloud targeting data stored in AWS S3, specifically attacks leveraging SSE-C, server-side encryption with customer-provided keys. We've seen threads and questions in forums such as Slack, Reddit, and other places. We'll clarify findings, differentiate what is unique, break down the attack vectors, and go through techniques to prevent against ransomware attacks like this in the future.

Our previous research can help by both using Organizational Policies to prevent encryption with unauthorized mechanisms and understand what IAM Permissions are required to update encryption on resources in AWS: 


Links:

Explaining the S3 SSE-C Ransomware Approach

Using the cybersecurity framework, MITRE ATT&CK, we can break down this specific ransomware technique into the following:

Attackers obtained valid credentials with access to AWS.  Halcyon refers to these as "AWS Keys" while AWS's post refers to them as "valid customer credentials".

In this case, there's a high likelihood that these credentials are credentials tied to an IAM User, which come in the form of long-term credentials via an access Key ID and a secret access key.  Note: IAM Users can also be used for AWS Console login with a username and password.

We theorize that the attackers conducted reconnaissance with the compromised credentials to identify targets of interest.  Otherwise, they would have to have knowledge of assets within the cloud environment

With regards to S3, this could look like s3:ListBuckets and s3:ListObjects. We theorize that the attackers had overly permissive IAM access that permitted them to conduct reconnaissance and identify data targets for ransomware

There's a slight difference between the AWS and Halcyon reports on what actions were taken by the attackers. Both most likely refer to the S3 CopyObject operation, s3 cp , which requires permissions to both s3:GetObject and s3:PutObject .

In both the AWS and Halcyon report, the attacker encrypts the data with SSE-C, an example command is below:

aws s3 cp s3://<bucket_with_data>/<file_name> s3://<bucket_with_data>/<file_name> \
--sse-c AES256 \
--sse-c-key <customer_provided_key_here> 

SSE-C Encryption in AWS is a unique encryption option that permits for server-side encryption with customer-provided keys where data is stored with a customer-provided key. Amazon S3 will manage the encryption and decryption. This encryption is unique where Amazon S3 does not store the encryption key, instead it stores a HMAC value of the encryption key that can't be used to derive the value of the encryption key or to decrypt the encrypted data.

Thus, when data was encrypted with the attacker's encryption keys via SSE-C, the data cannot be decrypted without access to the attacker's encryption key (and thus the ransomware impact).

Halcyon also mentions that files were marked for deletion within seven days using the S3 Object Lifecycle Configuration. This was likely done via the s3:PutLifecycleConfiguration  permission. With S3 lifecycle configurations, an expiration action can be configured for a bucket so that when an object expires, Amazon S3 deletes expired objects on your behalf. Halcyon surmises that this adds urgency to the ransomware demand.

Note: in other ransomware attacks, exfiltration can occur where data is exfiltrated and then a ransom may be demanded to prevent release of sensitive data.

Observations and Questions on Ransomware in S3

Difficulty to Track

Default settings in AWS CloudTrail (AWS's logging for API calls) do not log data events. While management events are logged by CloudTrail, data events are not logged by default. Events such as the following object-level (and data) are not logged:

Without data plane logging, this S3 ransomware attack via SSE-C is difficult to track.  While there may earlier indicators of compromise via reconnaissance in management events such as s3:ListBuckets, the ransomware impact activities most likely were not recorded in AWS CloudTrail.

While it's possible to enable data event logging, this can get expensive due to additional charges applying for data events and the high-volume nature of data events.

Uniqueness of SSE-C Ransomware in AWS

While some articles sensationalize how unique this attack is, here's what we think:

Using SSE-C does make the ransomware attack more streamlined as shown in the encryption CLI command above.  When ransomware attacks are more complex, the ability for attackers to successfully complete the attack prior to detection becomes more difficult.

With SSE-C and S3, the following 1 command can encrypt all data in an S3 bucket with the attacker-controlled encryption key (requires s3:GetObject, s3:PutObject, and s3:ListObject permissions):

aws s3 cp --recursive \
s3://<ransomware_bucket>/ s3://<ransomware_bucket>/ \
--sse-c AES256 --sse-c-key <customer_provided_key>

Differing Attributions and Ownership of Discovery by Halcyon and AWS Research

While AWS's post came within days of the Halcyon research post, it does not mention Halcyon and only mentions that the AWS Customer Incident Response Team (CIRT) and AWS's automated security monitoring systems identified an increase in unusual encryption activity. Halcyon's post attributes identification to the Halcyon RISE team.

AWS's Blog on S3 SSE-C Ransomware
Halcyon's Blog on S3 SSE-C Ransomware

Securing Data in S3 and Preventing S3 SSE-C Ransomware

We'll categorize security strategy into 2 categories:

IAM Protection for Access Keys

We see IAM as a key component of preventing S3 SSE-C Ransomware.  In this case, this attack was possible via compromised credentials in AWS. The following measures with IAM are preventative measures to help prevent SSE-C ransomware.

Access Keys in AWS are typically tied to long-term credentials such as IAM users. In AWS, security best practices recommend moving away from long-term credentials to short term credentials.  Instead of IAM Users, IAM roles are preferred.

For more details about temporary credentials in AWS, AWS has extensive documentation and AWS STS.

The following permissions were most likely used in this ransomware attack:

By removing a combination or scoping those permissions down, the ransomware attack may have been prevented.  Without s3:ListObjects and s3:ListBuckets, it may have been difficult for attackers to identify data targets.

It's possible that s3:PutObject and s3:GetObject were necessary permissions - for either a human identity or non-human identity. If the IAM user credentials did not need those permissions, they could be removed as well.

For prevention of data deletion, the following S3 permissions should be considered:

We can use a bucket policy to prevent against deletion as follows:

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DenyDelete",
			"Principal": "*",
			"Effect": "Deny",
			"Action": [
				"s3:PutLifecycleConfiguration",
				"s3:DeleteObject",
				"s3:DeleteObjectVersion"
			],
			"Resource": [
				"arn:aws:s3:::protected-bucket",
				"arn:aws:s3:::protected-bucket/*"
			]
		}
	]
}

Policy Protection for Encryption in S3

Certain policies such as resource-based policies (bucket policies) and organization policies such as Resource Control Policies can be used to prevent SSE-C encryption.

Note: These security measures do not protect against compromised credentials.  Rather, these measures prevent undesired usage of SSE-C.

The following options are available for server side encryption in S3:

Note: we'll focus on SSE-S3, SSE-KMS, SSE-C (as DSSE-KMS requires usage of a KMS key).

We'll focus on how to use bucket policies and organizational policies to allow or deny certain types of encryption

We can use the following bucket policy to deny object uploads with SSE-C encryption:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenySSEC",
            "Effect": "Deny",
            "Principal": "*",
            "Action": [
            	"s3:PutObject",
                "s3:ReplicateObject"
            ],
            "Resource": "arn:aws:s3:::your-protected-bucket/*",
            "Condition": {
        		"Null": {
          			"s3:x-amz-server-side-encryption-customer-algorithm": "false"
        		}
      		}
        }
    ]
}

We can take it further and use a bucket policy that denies non-KMS (AWS Managed Key or CMK):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenySSEC",
            "Effect": "Deny",
            "Principal": "*",
            "Action": [
            	"s3:PutObject",
                "s3:ReplicateObject"
            ],
            "Resource": "arn:aws:s3:::your-protected-bucket/*",
            "Condition": {
        		"Null": {
          			"s3:x-amz-server-side-encryption-aws-kms-key-id": "true"
        		}
      		}
        }
    ]
}

Or use a bucket policy that requires a specific CMK:

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DenyUnlessSpecificKMSKeyUsed",
			"Principal": "*",
			"Effect": "Deny",
			"Action": [
				"s3:PutObject",
				"s3:ReplicateObject"
			],
			"Resource": [
				"arn:aws:s3:::<example-bucket-fog-security>/*"
			],
			"Condition": {
				"ArnNotEquals": {
					"s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:us-east-1:123412341234:key/12341234-1234-1234-1234-123412341234"
				}
			}
		}
	]
}

The following RCP will deny object uploads with SSE-C encryption:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenySSECEncryption",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:PutObject",
        "s3:ReplicateObject"
      ],
      "Resource": "*",
      "Condition": {
        "Null": {
          "s3:x-amz-server-side-encryption-customer-algorithm": "false"
        }
      }
    }
  ]
}

To add more constraints and nuance to S3 encryption, the following RCP requires KMS Encryption (which can be either an AWS Managed Key or Customer Managed Key).  This denies encryption via SSE-C (customer-provided) or SSE-S3 (transparent S3 Owned).

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EnforceKMSEncryption",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:PutObject",
        "s3:ReplicateObject"
      ],
      "Resource": "*",
      "Condition": {
        "Null": {
          "s3:x-amz-server-side-encryption-aws-kms-key-id": "true"
        }
      }
    }
  ]
}

In this case, we prefer using RCPs due to their impact on restricting access to resources within your organization.

With this ransomware scenario, both RCPs and SCPs could offer protection to prevent encryption with SSE-C.  For more reading about how to use RCPs and SCPs, see our research on using both RCPs and SCPs and using RCPs with KMS for creating data perimeters.

Data Backup

Data Backup helps with reducing impact of ransomware and improving service restoration.  In this specific ransomware attack, it can reduce recovery time.

We recommend "air-gapping" backups and isolating IAM impact for both primary data sources and backup. With AWS, this can look like separating IAM principal access to both data sources and backup (some strategies include using different AWS accounts to host the backups) and using different KMS Keys for encryption of data sources and backup.  

One benefit of using the AWS Backup service for S3 is that independent AWS Backup encryption is supported (where a different encryption key is used for the data backup).

When ransomware includes data exfiltration, data backup does not protect against malicious actors publicizing sensitive data sets.

Conclusion

If you want to talk more about ransomware prevention, cloud data security, or have questions on our analysis above, we are happy to chat at info@fogsecurity.io.

References

Fog Security: Protecting Data and Preventing Ransonware: The IAM Guide to Managing and Updating Encryption for AWS Resources

Fog Security: Creating a Data Perimeter with Resource Control Policies (RCPs) and AWS KMS

AWS S3: Protecting Data with Server-Side Encryption

AWS: Preventing Unintended Encryption of Amazon S3 Objects

AWS S3: Using Server-Side Encryption with Customer-Provided Keys (SSE-C)

Halcyon: Abusing AWS Native Service; Ransomware Encryption S3 Buckets with SSE-C

Subscribe to stay up to date on cloud data security and our work.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.