如何绕过并利用Bucket的上传策略和URL签名
简介
Bucket上传策略是一种直接从客户端向Bucket(存储空间)上传数据的便捷方式。通过上传策略中的规则以及与访问某些文件的相关逻辑,我们将展示如何拿到完整的Bucket对象列表,同时能够修改或删除Bucket中的现有文件。
什么是Bucket策略
(如果你早已经知道了什么是Bucket策略和URL签名,那么你完全可以直接跳转到下面的“利用”部分)
Bucket策略是一种将内容直接上传到基于云端的大型存储区(如Google云端存储或AWS S3)的安全方式。我们的想法是创建一个定义有检验是否允许文件上传的策略,随后使用密钥对策略进行签名,并将策略和签名提交给客户端。
然后,客户端可以直接将文件上传到Bucket,Bucket存储会验证上传的内容和策略是否匹配。如果匹配,则上传文件。
上传策略与URL预签名
在开始之前,我们需要明确指出有多种方法可以访问Bucket中的对象。使用POST请求访问Bucket时,POST策略(AWS)和POST对象 (谷歌云存储)方式只允许上传内容。
另一种称为URL预签名(AWS)或URL签名(Google云端存储)的方式就不仅仅是可以修改对象。我们是否可以PUT、DELETE或GET 默认的私有对象,这取决于预签名逻辑定义的HTTP方式。
在定义内容类型(Content-Type)、访问控制和文件上传时,URL预签名与POST策略相比会相对宽松。使用错误的自定义逻辑也会更频繁地执行URL签名,如下所示。
这里有很多允许某人访问上传内容的方法,其中一个是AssumeRoleWithWebIdentity ,类似于POST策略,区别在于你可以获得由预定义的IAM Role(身份和访问管理角色)创建的临时安全凭证(ASIA *)。
如何发现上传策略或URL签名
这是使用POST方法的上传请求,如下所示:
该策略使用的是ba64编码的JSON,如下所示:
{
"expiration":"2018-07-31T13:55:50Z",
"conditions": [
{"bucket": "bucket-name"},
["starts-with", "$key", "acc123"],
{"acl": "public-read"},
{"success_action_redirect":"https://dashboard.example.com/"},
["starts-with", "$Content-Type", ""],
["content-length-range", 0, 524288]
]
}
在AWS S3上的类似于下面的URL签名:
https://bucket-name.s3.amazonaws.com/?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA…
就像谷歌云存储一样:
HTTPS ://storage.googleapis.com/uploads/images/test.png?Expires=1515198382&GoogleAccessId=example%40example.iam.gserviceaccount.com&Signature=dlMA---
上传策略的利用
如果我们想要发现策略中的错误,并对其进行利用,那么我们需要定义一些不同的属性:
l Access = Yes-在上传后,我们是否可以以某种方式访问该文件。在策略中ACL是否被定义为public-read或者能够接收上传文件的URL预签名。在策略中上传但未定义ACL的对象默认为私有。
l Inline=Yes-如果你能够修改content-disposition文件,那么我们可以在内联中提供内容。如果策略中根本没有定义,那么文件则以内联方式提供。
1. starts-with $key是空的
例:
["starts-with", "$key",""]
可以上传文件到Bucket中的任何位置,覆盖任何对象。你可以将key属性设置为任何内容,并且接受该策略。
注意:在某些情况下,这种利用很困难。例如,只有一个Bucket用于上传从未公开的或以后会使用的名为UUID(通用唯一标识符)的对象。在这种情况下,我们不知道要覆盖哪些文件,并且无法知道Bucket中其他对象的名称。
2. starts-with $key不包含路径分隔符或为所有用户都用相同的路径
例:
["starts-with", "$key","acc_1322342m3423"]
如果策略的 $key部分包含一个已定义的部分,但是没有路径分隔符,我们可以将内容直接放在Bucket的根目录中。如果 Access=Yes和 Inline=Yes,并取决于content-type的类型(参见#3和#4),我们则可以通过安装AppCache-manifest来窃取其他用户上传的URL(AppCache中的相关漏洞是由我和 @avlidienbrunn以及@filedescriptor分别发现的)。
如果上传对象的路径对所有用户都是相同的,那这个问题也一样适用。
3. starts-with $Content-Type为空
例:
["starts-with","$Content-Type", ""]
如果Access=Yes 和Inline=Yes,我们就可以在Bucket域上传text/html并提供此服务,如#2所示,我们可以使用它来运行javascript或在此路径上安装AppCache-manifest,这意味着在此路径下访问的所有文件都将泄露给攻击者。
4.使用starts-with $Content-Type定义内容类型
例:
["starts-with","$Content-Type", "image/jpeg"]
这个和#3一样,我们可以添加一些内容来使第一个内容类型成为一个未知的mime类型,随后追加text/html,文件将被认作为text/html类型:
Content-type: image/jpegz;text/html
此外,如果S3-Bucket托管在公司的子域中,通过利用上述策略,我们还可以通过上传HTML文件在域上运行javascript。
简介
Bucket上传策略是一种直接从客户端向Bucket(存储空间)上传数据的便捷方式。通过上传策略中的规则以及与访问某些文件的相关逻辑,我们将展示如何拿到完整的Bucket对象列表,同时能够修改或删除Bucket中的现有文件。
什么是Bucket策略
(如果你早已经知道了什么是Bucket策略和URL签名,那么你完全可以直接跳转到下面的“利用”部分)
Bucket策略是一种将内容直接上传到基于云端的大型存储区(如Google云端存储或AWS S3)的安全方式。我们的想法是创建一个定义有检验是否允许文件上传的策略,随后使用密钥对策略进行签名,并将策略和签名提交给客户端。
然后,客户端可以直接将文件上传到Bucket,Bucket存储会验证上传的内容和策略是否匹配。如果匹配,则上传文件。
上传策略与URL预签名
在开始之前,我们需要明确指出有多种方法可以访问Bucket中的对象。使用POST请求访问Bucket时,POST策略(AWS)和POST对象 (谷歌云存储)方式只允许上传内容。
另一种称为URL预签名(AWS)或URL签名(Google云端存储)的方式就不仅仅是可以修改对象。我们是否可以PUT、DELETE或GET 默认的私有对象,这取决于预签名逻辑定义的HTTP方式。 本文来自无奈人生安全网
在定义内容类型(Content-Type)、访问控制和文件上传时,URL预签名与POST策略相比会相对宽松。使用错误的自定义逻辑也会更频繁地执行URL签名,如下所示。
这里有很多允许某人访问上传内容的方法,其中一个是AssumeRoleWithWebIdentity ,类似于POST策略,区别在于你可以获得由预定义的IAM Role(身份和访问管理角色)创建的临时安全凭证(ASIA *)。
如何发现上传策略或URL签名
这是使用POST方法的上传请求,如下所示:
该策略使用的是ba64编码的JSON,如下所示:
{
"expiration":"2018-07-31T13:55:50Z",
"conditions": [
{"bucket": "bucket-name"},
["starts-with", "$key", "acc123"],
{"acl": "public-read"},
{"success_action_redirect":"https://dashboard.example.com/"}, 本文来自无奈人生安全网
["starts-with", "$Content-Type", ""],
["content-length-range", 0, 524288]
]
}
在AWS S3上的类似于下面的URL签名:
https://bucket-name.s3.amazonaws.com/?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA…
就像谷歌云存储一样:
HTTPS ://storage.googleapis.com/uploads/images/test.png?Expires=1515198382&GoogleAccessId=example%40example.iam.gserviceaccount.com&Signature=dlMA---
上传策略的利用
如果我们想要发现策略中的错误,并对其进行利用,那么我们需要定义一些不同的属性:
l Access = Yes-在上传后,我们是否可以以某种方式访问该文件。在策略中ACL是否被定义为public-read或者能够接收上传文件的URL预签名。在策略中上传但未定义ACL的对象默认为私有。
l Inline=Yes-如果你能够修改content-disposition文件,那么我们可以在内联中提供内容。如果策略中根本没有定义,那么文件则以内联方式提供。
1. starts-with $key是空的
例:
["starts-with", "$key",""]
无奈人生安全网
可以上传文件到Bucket中的任何位置,覆盖任何对象。你可以将key属性设置为任何内容,并且接受该策略。
注意:在某些情况下,这种利用很困难。例如,只有一个Bucket用于上传从未公开的或以后会使用的名为UUID(通用唯一标识符)的对象。在这种情况下,我们不知道要覆盖哪些文件,并且无法知道Bucket中其他对象的名称。
2. starts-with $key不包含路径分隔符或为所有用户都用相同的路径
例:
["starts-with", "$key","acc_1322342m3423"]
如果策略的 $key部分包含一个已定义的部分,但是没有路径分隔符,我们可以将内容直接放在Bucket的根目录中。如果 Access=Yes和 Inline=Yes,并取决于content-type的类型(参见#3和#4),我们则可以通过安装AppCache-manifest来窃取其他用户上传的URL(AppCache中的相关漏洞是由我和 @avlidienbrunn以及@filedescriptor分别发现的)。
www.wnhack.com
如果上传对象的路径对所有用户都是相同的,那这个问题也一样适用。
3. starts-with $Content-Type为空
例:
["starts-with","$Content-Type", ""]
如果Access=Yes 和Inline=Yes,我们就可以在Bucket域上传text/html并提供此服务,如#2所示,我们可以使用它来运行javascript或在此路径上安装AppCache-manifest,这意味着在此路径下访问的所有文件都将泄露给攻击者。
4.使用starts-with $Content-Type定义内容类型
例:
["starts-with","$Content-Type", "image/jpeg"]
这个和#3一样,我们可以添加一些内容来使第一个内容类型成为一个未知的mime类型,随后追加text/html,文件将被认作为text/html类型:
Content-type: image/jpegz;text/html
此外,如果S3-Bucket托管在公司的子域中,通过利用上述策略,我们还可以通过上传HTML文件在域上运行javascript。
www.wnhack.com