Codefinger / S3 Ransomware - Stolen AWS Keys → Valid Access → Bucket Enum → SSE-C Encryption → 7-Day Delete + BTC Ransom
A financially motivated actor tracked as Codefinger used compromised or publicly exposed AWS access keys to encrypt victims' S3 buckets using AWS's own Server-Side Encryption with Customer-Provided Keys (SSE-C). Because the attacker generates and holds the AES-256 key locally, and AWS stores only an HMAC of that key, victims cannot decrypt their data without paying. Codefinger applied S3 Lifecycle policies to delete the encrypted objects within seven days as ransom pressure and demanded payment in Bitcoin. No AWS vulnerability was exploited - the entire campaign relied on abusing valid credentials and native AWS features. Halcyon, which disclosed the campaign on January 13, 2025, observed at least two victim organisations.
Codefinger sourced valid AWS access key IDs and secret access keys that had been publicly disclosed or otherwise compromised. Long-lived IAM access keys routinely leak through committed source code, exposed config files, CI logs, and public buckets, and are harvested by scanners within minutes of exposure. Halcyon assessed the actor used keys with permissions to read and write S3 objects, so no privilege escalation or AWS vulnerability was needed - possession of a working key pair was sufficient.
Common leak paths: Git commits, public S3 buckets, CI/CD logs, hardcoded app config
Why it worked: Keys never rotated · No expiry · No detection of key use from new sources
Using the compromised keys, Codefinger authenticated to the victim's AWS account as a legitimate principal via the AWS SDK, CLI, or API. Because the request came from a valid IAM identity, it passed authentication with no anomaly. The keys carried s3:GetObject and s3:PutObject permissions - enough to read existing objects and overwrite them with encrypted copies. AWS CloudTrail recorded the API activity, but by default no alert fires on legitimate-looking S3 calls from a new IP or region.
Required IAM perms: s3:GetObject, s3:PutObject on target buckets
Detection gap: Valid-credential access from a new IP raised no default alert
With valid access, Codefinger enumerated the account's S3 footprint using native API calls to list buckets and objects, mapping which buckets held valuable data and were reachable with the key's permissions. These are ordinary read operations that generate no exploitation signal. The output told the attacker exactly which objects to target for encryption in the impact phase.
Goal: Identify readable/writable buckets holding business-critical data
Typical targets: Backups, application data, customer records, media assets
Codefinger encrypted each target object by re-writing it with Server-Side Encryption using Customer-Provided Keys (SSE-C). The attacker generated an AES-256 key locally and supplied it on the PutObject request via the x-amz-server-side-encryption-customer-algorithm and x-amz-server-side-encryption-customer-key headers. AWS performs the encryption but does not store the key - CloudTrail logs only an HMAC of it, which is insufficient to reconstruct the key. Once complete, the data is unrecoverable without the attacker's key, even by AWS. This turns a native, legitimate encryption feature into a ransomware primitive with no malware deployed.
Header 2: x-amz-server-side-encryption-customer-key: <attacker AES-256 key>
Key custody: Generated and stored locally by attacker - AWS keeps only an HMAC
Result: Objects unrecoverable without the attacker key - AWS cannot decrypt them
To force fast payment, Codefinger applied an S3 Lifecycle policy configured to permanently delete the encrypted objects within seven days. The attacker left a ransom note in each affected bucket with a Bitcoin address and payment instructions, and warned victims not to alter account permissions or attempt recovery. Because AWS never held the SSE-C key, victims who did not pay before the lifecycle timer expired lost the data outright. Halcyon reported at least two organisations were hit.
Ransom demand: Bitcoin payment for the AES-256 SSE-C decryption key
Ransom note: Left in-bucket · warned against changing IAM permissions
Confirmed victims: At least 2 organisations (Halcyon, Jan 2025)
