对象存储被勒索、被刷爆?用版本控制 + Object Lock 把“不可删除”焊死在桶上

对象存储被勒索、被刷爆?用版本控制 + Object Lock 把"不可删除"焊死在桶上
一套 S3 兼容存储,攻击者拿到泄露的 AK/SK 之后,先 aws s3 ls 把对象列一圈,再用 aws s3 rm --recursive 把桶清空,或者把每个对象下载、本地加密、用同名覆盖回去,然后发来比特币账单——这不是电影桥段,是 2025-2026 年真实发生的对象存储勒索剧本。AWS 在 2026 年 4 月还默认关掉了新建桶的 SSE-C 服务端加密写权限,说明连云厂商都在收紧存储安全默认值。你手上的 bucket,真的扛得住这一下吗?
为什么对象存储成了勒索重灾区
对象存储的攻击面很朴素:公开读/写权限、aws configure 时误提交的 AK/SK,以及给应用账号配的 s3:*。一旦凭证泄露,攻击者常用的三步是列对象、整桶同步走、或者加密覆盖。下面这段就是真实的"搬空"命令,无需任何额外工具:
# 泄露的 AK/SK 落到攻击者手里后
aws configure set aws_access_key_id AKIAxxxx
aws configure set aws_secret_access_key xxxx
# 把整个桶同步到本地,或换成 aws s3 rm --recursive 直接清空
aws s3 sync s3://victim-bucket ./loot/
更隐蔽的是"加密覆盖"型勒索:攻击者下载对象、本地用 AES 加密、再用同名 PUT 写回,原内容被覆盖,你不付赎金就拿不回来。这就是为什么"能读能写"的过度授权比"公开读"更危险——公开读只是泄露,过度写权限能直接毁数据。
第一道防线:Block Public Access + 最小权限
先堵住最蠢的口子。除非你的 bucket 真的要当静态网站给全网读,否则一律开 Block Public Access:
aws s3api put-public-access-block \--bucket victim-bucket \--public-access-block-configuration \"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
IAM 侧坚持最小权限:应用账号只给 s3:GetObject / s3:PutObject 到具体前缀,绝不给 s3:*。前端直传不要用永久 AK,改用后端生成 预签名 URL,限定 HTTP 方法、过期时间(5 分钟足够一次上传):
aws s3 presign s3://victim-bucket/uploads/${uuid}.png \--expires-in 300
预签名 URL 把"临时授权"和"暴露长期密钥"解耦,是公开写场景的标配替代方案。代价是 URL 一旦在到期前泄露仍有窗口,所以过期时间要尽量短,别为了省事设成 7 天。
被覆盖了还能救:版本控制
即使攻击者覆写了对象,只要开了版本控制,旧版本还在。开起来一行:
aws s3api put-bucket-versioning \--bucket victim-bucket \--versioning-configuration Status=Enabled
真被加密覆盖了,可以翻出攻击发生前的版本恢复(Danube Data 2026 指南里有完整脚本):
aws s3api list-object-versions --bucket victim-bucket
# 对每个 key,找到攻击时间戳之前的 version-id,删除被污染的版本
aws s3api delete-object --bucket victim-bucket \--key "report.pdf" --version-id "xxxxxxxx"
但版本控制救不了所有情况:攻击者若拿到完整凭证,可以连版本一起删(除非开了 MFA Delete)。它挡的是"误删 + 覆盖",挡不住"持完整权限的定向破坏"。
把"不可删除"焊死:Object Lock / WORM
要连 root 账号都删不掉,得靠 Object Lock(WORM,Write Once Read Many)。它必须在建桶时开启,且锁定期间的对象无法被覆盖或删除:
aws s3api create-bucket --bucket compliance-records \--object-lock-enabled-for-bucket \--endpoint-url https://s3.your-endpoint
# 默认合规留存 7 年(2555 天)示例
aws s3api put-object-lock-configuration \--bucket compliance-records \--object-lock-configuration '{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":2555}}}'
两种模式要分清:GOVERNANCE 模式下特定管理员权限还能覆盖;COMPLIANCE 模式下连 root 都不能删,到期前物理上不可动。这对勒索防御是关键——攻击者就算拿满权限,也动不了锁定期内的对象。
代价很硬:Object Lock 必须建桶时开,已存在的桶要迁数据;锁定期内的对象无法修改,留存天数得按业务和合规算准;锁定后不能关闭。把核心 bucket(备份、审计日志、合规存档)用 COMPLIANCE 模式锁上,比事后救火划算得多。
纵深防御链与取舍
单点防护都会漏,下面是六层纵深防御(从外到内),每一层都填补上一层的盲区:

每层控制手段"挡什么 / 代价是什么",摊开看更清楚:

踩坑与取舍
- Object Lock 不能事后补:已运行的生产桶要开,得新建带锁的桶再迁数据。迁移窗口要排好,别在业务高峰做,否则版本/锁定状态不一致会给你埋雷。
- 跨区域复制必须用独立凭证:如果源桶和异地副本用的是同一把 AK,攻击者拿到一把就全端了。异地复制的账号要单独发密钥、单独收权限。
- 监控是最后一道:开访问日志或 CloudTrail,对
DeleteObject /DeleteObjects的突增做告警。等发现时桶已经被清了一半,就太晚了。 - 成本是真实开销:版本控制和 Object Lock 都会多存副本,容量账单会涨。按数据重要度分级——核心桶上全套,临时桶只开 Block Public Access 就够了。
收尾:照着这张清单做
- 给所有桶开 Block Public Access,再审计一遍 IAM,把
s3:*砍到具体前缀。 - 前端直传全部改预签名 URL,过期时间压到 5 分钟以内。
- 对所有桶开版本控制。
- 备份、审计、合规三类核心桶开 Object Lock(COMPLIANCE 模式),锁定期按业务定。
- 关键数据做跨区域复制,且用独立凭证的账号。
- 开访问日志 + 删除突增告警,接入你的监控面板。
自建对象存储也一样能落地这套防护。RustFS 这类 S3 兼容存储支持版本控制、Object Lock(WORM)以及服务端加密,自建集群也能把"不可删除"焊死在桶上。如果你正在评估替换已被 archived 的 MinIO 社区版,可以顺手把安全基线一起对齐:https://github.com/rustfs/rustfs