探索亚马逊S3存储桶:公开与私有权限的安全分析

本文详细介绍了如何通过脚本枚举亚马逊S3存储桶的公开与私有状态,分析不同数据中心的访问差异,并演示如何获取存储桶内的文件列表及权限状态,涉及实际XML响应和区域重定向机制。

亚马逊S3存储桶里有什么?

在回顾一些旧的Hak5剧集时,我发现了关于亚马逊S3存储的内容。如果你不知道S3是什么,我建议去看看那一集,它提供了很好的介绍,也是我开始这个项目前的全部知识。吸引我和Darren注意的是,Jason提到每个存储桶在整个S3系统中必须有唯一的名称。一听到这个,我就想:让我们来暴力破解一些存储桶名吧。

于是我注册了免费套餐并开始调查。我创建了几个存储桶并查看了选项。默认情况下,存储桶是私有的,只有所有者可以访问,但你可以添加新权限使存储桶公开可访问。我设置了一个私有存储桶和一个公共存储桶,然后访问它们的URL看看会发生什么,得到了以下响应:

私有存储桶

1
2
3
4
5
6
<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>7F3987394757439B</RequestId>
    <HostId>kyMIhkpoWafjruFFairkfim383jtznAnwiyKSTxv7+/CIHqMBcqrXV2gr+EuALUp</HostId>
</Error>

公共存储桶

1
2
3
4
5
6
7
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Name>digipublic</Name>
    <Prefix></Prefix>
    <Marker></Marker>
    <MaxKeys>1000</MaxKeys>
    <IsTruncated>false</IsTruncated>
</ListBucketResult>

两者之间有明显的区别,因此在脚本中测试会很容易。接下来我查看了区域。设置存储桶时,你可以指定数据存储在五个数据中心中的哪一个,这样数据就更接近目标受众。你有以下选项:

  • US Standard
  • Ireland
  • Northern California
  • Singapore
  • Tokyo

我在每个区域都设置了一个存储桶并访问它们,访问时的区别在于主机名,映射如下:

但由于存储桶名称在整个S3中必须是唯一的,如果你用爱尔兰的主机名访问东京的存储桶会发生什么?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<Error>
    <Code>PermanentRedirect</Code>
    <Message>
        The bucket you are attempting to access must be addressed using the
        specified endpoint. Please send all future requests to this endpoint.
    </Message>
    <RequestId>4834475949AFC737</RequestId>
    <Bucket>digitokyo</Bucket>
    <HostId>TC1DCxcxiejfiek33492034AqtEVBxr+1Oj0GJvmCktGVrlcdZz9YjX5wHMbITi2</HostId>
    <Endpoint>digitokyo.s3-ap-northeast-1.amazonaws.com</Endpoint>
</Error>

它们会友好地将你重定向到正确的主机名。

有了所有这些信息,我构建了一个脚本,它会获取一个单词列表并遍历它,尝试访问每个单词的存储桶。它很好地解析了返回的XML,跟随重定向,并生成一个显示公共、私有和未分配存储桶的列表。

这很好,但文件呢?我在我的公共存储桶中放了一些文件并访问它的URL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Name>digipublic</Name>
    <Prefix></Prefix>
    <Marker></Marker>
    <MaxKeys>1000</MaxKeys>
    <IsTruncated>false</IsTruncated>
    <Contents>
        <Key>my_file</Key>
        <LastModified>2011-05-16T10:47:16.000Z</LastModified>
        <ETag>"51fff3c9087648822c0a21212907934a"</ETag>
        <Size>6429</Size>
        <StorageClass>STANDARD</StorageClass>
    </Contents>
</ListBucketResult>

这是一个目录列表,很好!

我放入了更多文件,一些私有,一些公共,它们都显示在列表中。然而,尝试访问私有文件会返回“403 Forbidden”和一堆类似于私有存储桶的XML。但我可以利用这一点,通过对目录列表中的每个文件执行HEAD操作,我可以得到“200 OK”或“403 Forbidden”,这意味着我现在可以枚举所有文件,看看它们是公共还是私有的。

快速总结一下…给定一个单词列表,我可以检查哪些存储桶存在,以及它们是公共还是私有的。对于所有公共的存储桶,我可以获取目录列表,并从该列表中查看哪些文件是公共的,哪些是私有的。我认为这对于一上午的工作来说相当不错。

我将这个脚本命名为Bucket Finder,你可以从它的项目页面下载。

我用一些不错的长单词列表运行了几次脚本,并得到了一些有趣的数据,但由于这篇文章有点长了,我就此打住,你可以在《分析亚马逊的存储桶》中阅读分析。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计