-- 云对象存储 --
简介
- 对象: 用户上传的每一个文件都会被封装成对象, 而文件附加的其它信息即为对象的属性
- 索引: 每个对象有名为key的属性, 用于索引, 可通过key对存储对象进行直接的搜索和定位
- 存储桶(Bucket桶): 用于存储对象, 可创建多个存储桶以分类存储不同的对象
- 收费: 云存储一般通过记录 读写次数 与 流量大小 来计费, 存储桶的创建与销毁为免费操作
- 存储结构: 对象存储无目录结构, 本质上所有文件都在同一层次下 且没有文件夹的概念, 但为了兼容本地存储系统, 通过用key模拟了目录结构, 通过用/分隔key来表示目录结构, 如
dict1/dict2/file
就 表示 目录dict1中的 目录dict2中的 文件file - 空文件夹: 某些云平台 提供了文件夹对象, 其key以
/
结尾, 如dict1/dict2/
- 种类: 腾讯云COS 阿里云COS 华为云OBS 百度云BOS
权限
- AccessKeyID(AK): 相当于用户名, 声明身份 用于在访问云对象时 表明身份, 从而根据 对应绑定的权限策略, 来决定用户可操作的资源范围
- SecretAccessKey(SK): 相当于密码, 与AK配对, 验证身份 用于加密请求数据, 生成数字签名, 保证请求的完整性和不可篡改性, 并通过签名认证, 防止伪造
- 存储桶访问权限类别私有读写(默认): 只有该存储桶的创建者 及 有授权的账号 有读写权限
公有读私有写: 任何人(包括匿名访问者)有读权限, 该存储桶的创建者 及 有授权的账号 有写权限
公有读写: 任何人(包括匿名访问者)都有读写权限 -
访问域名: COS:
<存储桶名称>-<APPID>.cos.<地区>.myqcloud.com
- APPID: 腾讯云为每个账号分配的唯一数字标识符, 通常为12位数字
- Bucket ID: 即
<存储桶名称>-<APPID>
- 特点: 通过默认域名访问对象时, 其响应的
Content-Disposition
一定为attachment OSS:<存储桶名称>.oss-<地区>.aliyuncs.com
-- 云对象存储漏洞 --
信息收集
- Bucket名爆破: 当获取了一个桶的域名时, 可以通过改变 桶名/地区 部分来爆破 以找出其它存储桶 注: 只对COS OBS等 存储域名会根据用户而改变的云 有效
- 对象遍历: 当拥有对应权限时, 可以GET访问根目录, 即可返回桶的所有对象的信息 COS: GetBucket | OSS: ListObject
未授权访问
- 利用: 使用PUT方法可上传对象, 访问路径为对象存储 路径与对象名, 请求体为对象的内容 使用GET方法可获取对象, 访问 对应路径与对象名, 即可获取
- 原理: 当桶开启了 公有读和公有写 时, 就可以直接往桶里上传/获取对象
- 特点: 未授权访问读对象时, 无法使用
respose-*
来操控对应的响应头 (在以前可以, 这是之后为了应对xss而做出的防护措施)
文件上传2xss(写对象)
- 前提: 能往桶中上传可造成xss的文件类型; 或者虽然不能上传能造成xss的文件类型, 但能操控往桶中上传对象时的Content-Type请求头
- 情景:
- 未授权访问/拥有aksk, 能直接往桶中上传 可造成xss的文件类型
- 能通过服务端上传, 服务端签好名后, 服务端自行上传文件, 但能操控上传时的Content-Type文件头(通常为服务端会根据用户上传的请求头, 改变自行上传的请求头)
- 能通过服务端上传, 服务端签好名后, 服务端让用户自行请求, 此时能修改Content-Type请求头(仅限COS, COS的签名不包含 对请求头的验证; 而OSS包含)
- 服务端将签名程序放置在前端 - 服务端会生成临时密钥, 并放置在前端, 通过前端代码对用户上传对象进行签名; 此时可直接更改的签名程序, 更改Content-Type, 然后再进行签名
- 原理:
- 上传对象的请求中的Content-Type/Content-Disposition请求头会算作 对象的属性, 在读对象时, 会将这些属性化为相应的相应头
- 当没有上述情况, 在读取桶的对象时, 响应中 会根据对象后缀名 返回对应的Content-Type
- 签好名的PUT对象上传请求, 不能更改其请求体和请求路径, 但可以修改Content-Type/Content-Disposition请求头(仅限COS, COS的签名不包含 对GET参数的验证; 而OSS包含)
- 注意: COS通过默认域名访问对象时, 其响应的
Content-Disposition
一定为attachment
文件上传2xss(读对象)
- 前提: 有权限从存储桶中 读取对象(不包括匿名访问), 并更改请求参数
- 情景:
- 拥有aksk, 能直接自行签名, 所以可以加上
response-*
请求参数 - 能通过服务端获取对象, 服务端签好名后, 服务端自行获取文件以展示, 但能操控获取时的GET请求头(通常为服务端会根据用户的请求头, 改变自行获取的请求头)
- 能通过服务端上传, 服务端签好名后, 服务端让用户自行请求, 此时能修改GET请求擦买手机(仅限COS, COS的签名不包含 对请求头的验证; 而OSS包含)
- 服务端将签名程序放置在前端 - 服务端会生成临时密钥, 并放置在前端, 通过前端代码对用户上传对象进行签名; 此时可直接更改的签名程序, 更改GET请求参数, 然后再进行签名
- 阿里云存储桶开启CDN回溯, 此时会给CDN直接读取OSS对象的权限(但无写权限), 此时通过CDN直接使用
response-*
(后来阿里云禁止了GET请求中的response-content-type
, 但还可用response-content-disposition
)
- 拥有aksk, 能直接自行签名, 所以可以加上
- 原理:
- 访问云对象时, 可添加GET请求参数
response-*
以操控对应响应头的值 所以可以在读取请求中用response-content-type
与response-content-disposition
头, 以操控响应中的相应字段 (未授权访问时不能使用response-*
的) - 签好名的GET对象获取请求, 不能更改其请求体和请求路径, 但可以修改GET请求参数 (仅限COS, COS的签名不包含 对GET参数的验证; 而OSS包含)
response-*
的优先级>对象属性中的对应请求头>根据对象后缀自行解析
- 访问云对象时, 可添加GET请求参数
- 注意: COS通过默认域名访问对象时, 其响应的
Content-Disposition
一定为attachment