EXECUTE / RANSOMWARE DEMO
Ransomware vs. Object Lock, live
A small open-source script that writes locked backups to B2 through the S3 API, plays an attacker holding the backup admin's keys, and restores clean data. Run it in --simulate mode with no account, or point it at a test bucket.
target: in-memory simulation mode: COMPLIANCE ==> 1. Write 3 backups with Object Lock COMPLIANCE retention until 2026-10-18 04:58 UTC ok backups/2026-10-17/db-1.dump version 3604d198ce14 sha256 26168d125f6c ok backups/2026-10-17/db-2.dump version ff03a197b505 sha256 13c345fd9c10 ok backups/2026-10-17/db-3.dump version d511075ff711 sha256 ae2a726f95f6 ==> 2. Ransomware gets the backup admin's keys and attacks attack DELETE backups/2026-10-17/db-1.dump (no version id) note S3 returned success, but it only added a delete-marker. The locked version is still there. attack DELETE backups/2026-10-17/db-1.dump?versionId=3604d198ce14 BLOCKED object is WORM protected and cannot be deleted until 2026-10-18 04:58 UTC attack DELETE backups/2026-10-17/db-2.dump?versionId=ff03a197b505 BLOCKED object is WORM protected and cannot be deleted until 2026-10-18 04:58 UTC attack DELETE backups/2026-10-17/db-3.dump?versionId=d511075ff711 BLOCKED object is WORM protected and cannot be deleted until 2026-10-18 04:58 UTC attack PUT backups/2026-10-17/db-2.dump with encrypted bytes (encrypt-in-place) note new version 707e9604e0f1 written; the clean version is untouched underneath attack PutObjectRetention backups/2026-10-17/db-2.dump: shorten retention to now BLOCKED cannot shorten retention on a locked object ==> 3. Damage report: what a restore job sees as 'latest' backups/2026-10-17/db-1.dump: MISSING (delete marker) backups/2026-10-17/db-2.dump: ENCRYPTED backups/2026-10-17/db-3.dump: clean ==> 4. Recover: read the locked version ids and restore them as the latest ok backups/2026-10-17/db-1.dump restored from 3604d198ce14 sha256 26168d125f6c matches ok backups/2026-10-17/db-2.dump restored from ff03a197b505 sha256 13c345fd9c10 matches ok backups/2026-10-17/db-3.dump restored from d511075ff711 sha256 ae2a726f95f6 matches ==> 5. Result: 3/3 backups recovered byte-for-byte. Locked versions remain until 2026-10-18 UTC.
Recorded from the simulator, which models the S3 Object Lock rules the demo uses. Against real B2 the same calls return the same outcomes; the error text comes from B2.
What the attacker tries, and what happens
| Attack | Result |
|---|---|
DELETE key | "Success", but only a delete marker. The locked version stays. |
DELETE key?versionId= | AccessDenied until retain-until. |
| Overwrite with encrypted bytes | New version on top; clean version untouched. |
| Shorten retention | AccessDenied. COMPLIANCE: nobody can. GOVERNANCE: only keys with bypassGovernance. |
Run it against B2
pip install boto3
export B2_KEY_ID=... B2_APP_KEY=... B2_BUCKET=my-lock-test
export B2_ENDPOINT=https://s3.us-west-004.backblazeb2.com
python3 demo.py --mode GOVERNANCE --days 1 - Use a test bucket with Object Lock enabled and a standard application key scoped to it. The master key does not work with the S3-compatible API.
- Start in GOVERNANCE with
--days 1. COMPLIANCE objects cannot be deleted by anyone until retention ends, and they are billed until then.
Talk track
- "Your backups are the ransomware target now. Attackers go for the repository first."
- "Object Lock is enforced by the storage service on each version. Stolen keys do not unlock it."
- "Watch: delete looks like it worked. It didn't. Here's the clean version, restored, checksum matches."
- "Controls that matter: scoped keys, no bypassGovernance on backup keys, MFA, retention longer than your detection window."
Deeper: Security · Board: backup and ransomware.