当前位置:主页 > 资料 >

Bypassing and exploiting Bucket Upload Policies and Signed U
栏目分类:资料   发布日期:2018-08-03   浏览次数:

导读:本文为去找网小编(www.7zhao.net)为您推荐的Bypassing and exploiting Bucket Upload Policies and Signed URLs,希望对您有所帮助,谢谢! TL;DRBucket upload policies are a convenient way to upload data to a bucket directl

本文为去找网小编(www.7zhao.net)为您推荐的Bypassing and exploiting Bucket Upload Policies and Signed URLs,希望对您有所帮助,谢谢!

欢迎访问www.7zhao.net



TL;DRBucket upload policies are a convenient way to upload data to a bucket directly from the client. Going through the rules in upload policies and the logic related to some file-access scenarios we show how full bucket object listings were exposed with the ability to also modify or delete existing files in the bucket.

www.7zhao.net

What is a Bucket Policy?

(If you already know what bucket-policies and signed URLs are, you can jump directly to thepart below) 欢迎访问www.7zhao.net

A bucket policy is meant to be a secure way of directly uploading content to a cloud based bucket-storage, like Google Cloud Storage or AWS S3. The idea is that you create a policy defining what is allowed and not. You then sign the policy with a secret key and gives the policy and the signature to the client.

内容来自www.7zhao.net

The client can then upload files directly to the bucket, and the bucket-storage will validate if the uploaded content matches the policy. If it does, the file will be uploaded.

内容来自www.7zhao.net

Upload Policies vs Pre-Signed URLs

Before we begin, we need to make clear that there are multiple ways to gain access to objects inside a bucket. The (AWS) and  (Google Cloud Storage) methods only allow uploading content, using a POST-request to the bucket.

欢迎访问www.7zhao.net

Another method called (AWS) or  (Google Cloud Storage) allow more than just modifying the object. Depending on the HTTP-method defined by the pre-sign logic, we can PUT, DELETE or GET objects which are private per default.

www.7zhao.net

Pre-Signed URLs are way more lax compared to the POST Policy version when it comes to defining content-type, access control and similar to the file being uploaded. Signed URLs are also more frequently implemented using broken custom logic as you will see below.

去找(www.7zhao.net欢迎您

There are even more ways to allow someone access to upload content, one being which is similar to the POST Policy, with the difference being you get temporary security credentials back (ASIA * ) created by a pre-defined IAM Role.

去找(www.7zhao.net欢迎您

How to spot an upload policy or signed URL

This is how an upload request using POST looks like: copyright www.7zhao.net

去找(www.7zhao.net欢迎您

The policy is a base64-encoded JSON that looks something like this:

去找(www.7zhao.net欢迎您

{
 "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]
 ]
} 
去找(www.7zhao.net欢迎您

A signed URL looks like this on AWS S3: www.7zhao.net

https://bucket-name.s3.amazonaws.com/?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA... copyright www.7zhao.net 

And like this for Google Cloud Storage: 欢迎访问www.7zhao.net

https://storage.googleapis.com/uploads/images/test.png?Expires=1515198382&GoogleAccessId=example%40example.iam.gserviceaccount.com&Signature=dlMA--- 内容来自www.7zhao.net 

Exploiting upload policies

Now to the fun part! 本文来自去找www.7zhao.net

To abuse upload policies we need to define some different properties that matter if we want to spot errors in the policy: 内容来自www.7zhao.net

  • Access=Yes  – If we can access the file somehow after upload. If  ACL  is defined as  public-read  in the policy or by being able to receive a pre-signed URL for the uploaded file. Objects uploaded without a defined ACL in the policy are private per default.
  • Inline=Yes  – If you’re able to modify the  content-disposition  of the file, so we can serve it inline in the bucket. If it’s not defined at all in the policy, files are served inline.

1. starts-with $key is empty

Example: copyright www.7zhao.net

["starts-with", "$key", ""] 去找(www.7zhao.net欢迎您 

This is not great. We are now able to upload to any location in the bucket and we’re able to overwrite any object. You can set the key -property into anything and the policy will be accepted.

本文来自去找www.7zhao.net

NB: There are scenarios where the exploitability of this is still hard, for example with a bucket only used to upload objects named as UUIDs (Universally unique identifiers) that are never exposed or used further. In this case we do not know what files to overwrite and there’s no way to know the names of other objects in the bucket. www.7zhao.net

2. starts-with $key does not contain a path separator or uses same path for all users

Example: 本文来自去找www.7zhao.net

["starts-with", "$key", "acc_1322342m3423"] 
www.7zhao.net

If the $key -part of the policy contains a defined part, but without a path separator, we can place content directly in the root-directory of the bucket. If  Access=Yes and  Inline=Yes and depending on the  content-type (see #3 and #4) we can abuse this by installing an AppCache-manifest to  ( in AppCache found by  +me and  independently).

去找(www.7zhao.net欢迎您

欢迎访问www.7zhao.net

The same issue applies if the path the objects are uploaded to is the same for all users.

欢迎访问www.7zhao.net

3. starts-with $Content-Type is empty

Example:

copyright www.7zhao.net

["starts-with", "$Content-Type", ""] 本文来自去找www.7zhao.net 

If Access=Yes and  Inline=Yes we can now upload  text/html and serve this on the bucket domain. As shown in #2 we can use this to either run javascript or install an AppCache-manifest on this path, meaning all files accessed under this path will be leaked to the attacker. 去找(www.7zhao.net欢迎您

4. Content-type is defined using starts-with $Content-Type

Example: 欢迎访问www.7zhao.net

["starts-with", "$Content-Type", "image/jpeg"] 欢迎访问www.7zhao.net 

This is the same thing as #3 really, we can just append something to make the first content-type an unknown mime-type, and append text/html after and the file will be served as  text/html :

欢迎访问www.7zhao.net

Content-type: image/jpegz;text/html copyright www.7zhao.net 

Also, if the S3-bucket is hosted on a subdomain of the company, by abusing the policies above we could also run javascript on the domain by uploading an HTML-file. 本文来自去找www.7zhao.net

The most interesting part with this was the exploitation of websites with uploaded content on a sandboxed domain.

欢迎访问www.7zhao.net

Exploiting signed URLs using custom logic

Signed URLs are signed server-side and served to the client to allow them to either upload, modify or access the content. The most common problem with these are when websites build custom logic to retrieve them.

本文来自去找www.7zhao.net

To first understand how you can abuse signed URLs, it’s important to know that per default, being able to get a signed GET-URL to the root of the bucket will show you the file-listing of the bucket. This is exactly like being exposed using a public listable bucket with the difference that this bucket most certainly contains private data for other users. 欢迎访问www.7zhao.net

Remember, when we know about other files in the bucket, we can request a signed URL for them as well, which will allow us to get access to private files.

内容来自www.7zhao.net

So, goal is always to try to get to the root or to another file we know exist.

copyright www.7zhao.net

Examples of broken custom logic

Here are some examples where the logic actually exposed the root path of the bucket by issuing a signed GET-URL. 去找(www.7zhao.net欢迎您

1. Full read access to complete bucket using get-image -endpoint 本文来自去找www.7zhao.net

The following request:

www.7zhao.net

https://freehand.example.com/api/get-image?key=abc&document=xyz 去找(www.7zhao.net欢迎您 

Gave the following signed URL: 本文来自去找www.7zhao.net

https://prodapp.s3.amazonaws.com/documents/648475/images/abc?X-Amz-Algorithm=AWS4-HMAC-SHA256... 内容来自www.7zhao.net 

But, the endpoint normalized the URL before signing it, so by using path-traversal, we could actually make it point to the root of the bucket:

去找(www.7zhao.net欢迎您

https://freehand.example.com/api/get-image?key=../../../&document=xyz 

copyright www.7zhao.net

Resulted in: 欢迎访问www.7zhao.net

https://prodapp.s3.amazonaws.com/?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA... 

copyright www.7zhao.net

And this URL gave the listing for every file in the bucket. copyright www.7zhao.net

2. Full read access due to regular expression parsing of signed URL request

Here’s another example, the following request was made to an endpoint on the website to get a signed URL of the object you wanted: 本文来自去找www.7zhao.net

POST /api/file_service/file_upload_policies/s3_url_signature.json HTTP/1.1
Host: sectest.example.com

{"url":"https://example-bucket.s3.amazonaws.com/dir/file.png"} 内容来自www.7zhao.net 

What it would do is parse the URL and extract parts of it to the signed URL and in return you would get this: 本文来自去找www.7zhao.net

{"signedUrl": "https://s3.amazonaws.com/example-bucket/dir/file.png?X-Amz-Algorithm=AWS4-HMAC..."} 欢迎访问www.7zhao.net 

An S3-bucket can be accessed using both a subdomain and a path on s3.amazonaws.com, and in this case, the server-side logic was changing the URL to a path-based bucket URL. www.7zhao.net

By tricking the URL extraction, you could send in something like this:

www.7zhao.net

{"url":"https://.x./example-bucket"} 

copyright www.7zhao.net

and it would give you back a signed URL like this: 去找(www.7zhao.net欢迎您

{"signedURL":"https://s3.amazonaws.com//example-beta?X-Amz-Algorithm=AWS4-HMAC..."} 

去找(www.7zhao.net欢迎您

And this URL would show the complete file listing of the bucket.

www.7zhao.net

3. Abusing temporary signed URL links

This example is from two years ago and the first issue I found related to Signed URLs.

copyright www.7zhao.net

On the site, when uploading a file you first created a random-key on secure.example.com : www.7zhao.net

POST /api/s3_file/ HTTP/1.1
Host: secure.example.com

{"id":null,"random_key":"abc-123-def-456-ghi-789","s3_key":"/file.jpg","uploader_id":71957,"employee_id":null} 去找(www.7zhao.net欢迎您 

In return, you would get back:

本文来自去找www.7zhao.net

HTTP/1.1 201 CREATED

{"employee_id":null, "s3_key": "/file.jpg", "uploader_id": 71957, "random_key":"abc-123-def-456-ghi-789", "id": null} 欢迎访问www.7zhao.net 

This meant, that the following URL:

www.7zhao.net

https://secure.example.com/files/abc-123-def-456-ghi-789 去找(www.7zhao.net欢迎您 

would then redirect to:

本文来自去找www.7zhao.net

Location: https://example.s3.amazonaws.com/file.jpg?Signature=i0YZ... 欢迎访问www.7zhao.net 

It was then possible to send in the following s3_key : 本文来自去找www.7zhao.net

"random_key":"xx1234","s3_key":"/" 本文来自去找www.7zhao.net 

Which would then have the following URL:

www.7zhao.net

https://secure.example.com/files/xx1234 

copyright www.7zhao.net

redirect to:

本文来自去找www.7zhao.net

Location: https://example.s3.amazonaws.com/?Signature=i0YZ... 

本文来自去找www.7zhao.net

Bingo! I now had the file listing of their bucket. This specific example turned out to be very bad. The website used one bucket for all their data, containing every document and file they had. When I tried extracting the file-listing to show the company, the bucket was massive, millions and millions of files. I directly sent the bug to the company and they came back with an awesome response: 去找(www.7zhao.net欢迎您

copyright www.7zhao.net

Recommendations

An upload policy should be generated specifically per every file-upload request, or at least per every user. 欢迎访问www.7zhao.net

  • The  $key  should be defined completely, with a unique, random generated name and inside a randomly generated path.
  • The  content-disposition  should preferably be defined as  attachment .
  • acl  should preferably be  private  or not defined at all.
  • content-type  should either be explicitly set (not using  starts-with ) or not set at all.

And, creating a signed URL should never be based on parameters by the user, as you can see above, this can clearly end up in scenarios which was not expected. 本文来自去找www.7zhao.net

The worst case I ever saw was: 本文来自去找www.7zhao.net

https://secure.example.com/api/file_upload_policies/multipart_signature?to_sign=GET%0A%0A%0A%0Ax-amz-date%3AFri%2C%2009%20Mar%202018%2000%3A11%3A28%20GMT%0A%2Fbucket-name%2F&datetime=Fri,%2009%20Mar%202018%2000:11:28%20GMT 本文来自去找www.7zhao.net 

You gave it exactly the request you wanted to sign, and it gave back the signature of whatever you asked it to sign:

www.7zhao.net

0zfAa9zIBlXH76rTitXXXuhEyJI= 内容来自www.7zhao.net 

Which could then be used to make the request you got a signature for:

本文来自去找www.7zhao.net

curl -H "Authorization: AWS AKIAJAXXPZR2XXX7ZXXX:0zfAa9zIBlXH76rTitXXXuhEyJI=" -H "x-amz-date: Fri, 09 Mar 2018 00:11:28 GMT" https://s3.amazonaws.com/bucket-name/ 
copyright www.7zhao.net

The same signing method is used for more things than just S3, and this gave you the ability to sign every request you wanted to any AWS-service the AWS-key was allowed to use. copyright www.7zhao.net

Author:

去找(www.7zhao.net欢迎您

Security Advisor

欢迎访问www.7zhao.net

Built by ethical hackers,Detectify is a web vulnerability scanner that checks for 1000+ known vulnerabilities. Part of how we achieve this is by sourcing external research from our community of hackers and from our internal security researchers including Frans Rosén.

欢迎访问www.7zhao.net

Other research on S3 buckets: A deep dive into AWS S3 access controls – taking full control over your assets

copyright www.7zhao.net

copyright www.7zhao.net


本文原文地址:https://labs.detectify.com/2018/08/02/bypassing-exploiting-bucket-upload-policies-signed-urls/

以上为Bypassing and exploiting Bucket Upload Policies and Signed URLs文章的全部内容,若您也有好的文章,欢迎与我们分享!

内容来自www.7zhao.net

Copyright ©2008-2017去找网版权所有   皖ICP备12002049号-2 皖公网安备 34088102000435号   关于我们|联系我们| 免责声明|友情链接|网站地图|手机版