AWS - S3 Unauthenticated Enum

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

S3 Public Buckets

A bucket is considered “public” if any user can list the contents of the bucket, and “private” if the bucket’s contents can only be listed or written by certain users.

Companies might have buckets permissions miss-configured giving access either to everything or to everyone authenticated in AWS in any account (so to anyone). Note, that even with such misconfigurations some actions might not be able to be performed as buckets might have their own access control lists (ACLs).

Learn about AWS-S3 misconfiguration here: http://flaws.cloud and http://flaws2.cloud/

Finding AWS Buckets

Different methods to find when a webpage is using AWS to storage some resources:

Enumeration & OSINT:

  • Using wappalyzer browser plugin
  • Using burp (spidering the web) or by manually navigating through the page all resources loaded will be save in the History.
  • Check for resources in domains like:
http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
  • Check for CNAMES as resources.domain.com might have the CNAME bucket.s3.amazonaws.com
  • s3dns – DNS トラフィックを解析してクラウドストレージ buckets (S3, GCP, Azure) を受動的に識別する軽量な DNS サーバーです。CNAME を検出し、解決チェーンを辿り、bucket パターンと照合します。ブルートフォースや API ベースの検出の静かな代替手段を提供し、recon と OSINT ワークフローに最適です。
  • Check https://buckets.grayhatwarfare.com, a web with already discovered open buckets.
  • The bucket name and the bucket domain name needs to be the same.
  • flaws.cloud is in IP 52.92.181.107 and if you go there it redirects you to https://aws.amazon.com/s3/. Also, dig -x 52.92.181.107 gives s3-website-us-west-2.amazonaws.com.
  • To check it’s a bucket you can also visit https://flaws.cloud.s3.amazonaws.com/.

Brute-Force

You can find buckets by brute-forcing names related to the company you are pentesting:

# Generate a wordlist to create permutations
curl -s https://raw.githubusercontent.com/cujanovic/goaltdns/master/words.txt > /tmp/words-s3.txt.temp
curl -s https://raw.githubusercontent.com/jordanpotti/AWSBucketDump/master/BucketNames.txt >>/tmp/words-s3.txt.temp
cat /tmp/words-s3.txt.temp | sort -u > /tmp/words-s3.txt

# Generate a wordlist based on the domains and subdomains to test
## Write those domains and subdomains in subdomains.txt
cat subdomains.txt > /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "-" >> /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "\n" | sort -u >> /tmp/words-hosts-s3.txt

# Create permutations based in a list with the domains and subdomains to attack
goaltdns -l /tmp/words-hosts-s3.txt -w /tmp/words-s3.txt -o /tmp/final-words-s3.txt.temp
## The previous tool is specialized increating permutations for subdomains, lets filter that list
### 末尾が「.」で終わる行を削除cat /tmp/final-words-s3.txt.temp | grep -Ev "\.$" > /tmp/final-words-s3.txt.temp2
### Create list without TLD
cat /tmp/final-words-s3.txt.temp2 | sed -E 's/\.[a-zA-Z0-9]+$//' > /tmp/final-words-s3.txt.temp3
### Create list without dots
cat /tmp/final-words-s3.txt.temp3 | tr -d "." > /tmp/final-words-s3.txt.temp4http://phantom.s3.amazonaws.com/
### Create list without hyphens
cat /tmp/final-words-s3.txt.temp3 | tr "." "-" > /tmp/final-words-s3.txt.temp5

## Generate the final wordlist
cat /tmp/final-words-s3.txt.temp2 /tmp/final-words-s3.txt.temp3 /tmp/final-words-s3.txt.temp4 /tmp/final-words-s3.txt.temp5 | grep -v -- "-\." | awk '{print tolower($0)}' | sort -u > /tmp/final-words-s3.txt

## Call s3scanner
s3scanner --threads 100 scan --buckets-file /tmp/final-words-s3.txt  | grep bucket_exists

Loot S3 Buckets

Given S3 open buckets, BucketLoot can automatically search for interesting information.

Find the Region

You can find all the supported regions by AWS in https://docs.aws.amazon.com/general/latest/gr/s3.html

By DNS

You can get the region of a bucket with a dig and nslookup by doing a DNS request of the discovered IP:

dig flaws.cloud
;; ANSWER SECTION:
flaws.cloud.    5    IN    A    52.218.192.11

nslookup 52.218.192.11
Non-authoritative answer:
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.

解決されたドメインに “website” という語が含まれていることを確認します。
静的ウェブサイトには次のURLにアクセスして確認できます: flaws.cloud.s3-website-us-west-2.amazonaws.com
またはバケットにアクセスするには次を訪問します: flaws.cloud.s3-us-west-2.amazonaws.com

試して確認する

バケットにアクセスしようとしたとき、ドメイン名に別のリージョンを指定した場合(例えばバケットが bucket.s3.amazonaws.com にあるのに bucket.s3-website-us-west-2.amazonaws.com にアクセスしようとした場合)、正しい場所が示されます:

バケットの列挙

バケットの公開状態を確認するには、ユーザーがブラウザのURL欄にそのURLを入力するだけです。プライベートなバケットは “Access Denied” と応答します。パブリックなバケットは保存されている最初の1,000個のオブジェクトを一覧表示します。

全員に公開:

プライベート:

これをcliで確認することもできます:

#Use --no-sign-request for check Everyones permissions
#Use --profile <PROFILE_NAME> to indicate the AWS profile(keys) that youwant to use: Check for "Any Authenticated AWS User" permissions
#--recursive if you want list recursivelyls
#Opcionally you can select the region if you now it
aws s3 ls s3://flaws.cloud/ [--no-sign-request] [--profile <PROFILE_NAME>] [ --recursive] [--region us-west-2]

バケットにドメイン名がない場合、列挙を試みるときは、バケット名だけを入力し、AWSs3ドメイン全体は入力しないでください。例: s3://<BUCKETNAME>

公開URLテンプレート

https://{user_provided}.s3.amazonaws.com

公開 Bucket からアカウントIDを取得

新しい S3:ResourceAccount Policy Condition Key を利用することで、AWS アカウントを特定することが可能です。この条件は restricts access based on the S3 bucket an account is in (他のアカウントベースのポリシーは、要求元プリンシパルが所属するアカウントに基づいて制限します)。
また、ポリシーに wildcards を含めることができるため、アカウント番号を just one number at a time で見つけることが可能です。

このツールはそのプロセスを自動化します:

# Installation
pipx install s3-account-search
pip install s3-account-search
# With a bucket
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket
# With an object
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket/path/to/object.ext

この手法は、API Gateway URLs、Lambda URLs、Data Exchange data sets、そして tags の値(tag key を知っていれば)を取得することにも使えます。詳細は original research および、この悪用を自動化するツール conditional-love を参照してください。

バケットが AWS アカウントに属していることを確認する

説明したように this blog post、もしバケットを一覧表示する権限がある場合、バケットが属する accountID を次のようなリクエストを送信して確認できます:

curl -X GET "[bucketname].amazonaws.com/" \
-H "x-amz-expected-bucket-owner: [correct-account-id]"

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">...</ListBucketResult>

If the error is an “Access Denied” it means that the account ID was wrong.

rootアカウントの列挙に使用されたメール

As explained in this blog post, it’s possible to check if an email address is related to any AWS account by メールに権限を付与しようとする over a S3 bucket via ACLs. If this doesn’t trigger an error, it means that the email is a root user of some AWS account:

s3_client.put_bucket_acl(
Bucket=bucket_name,
AccessControlPolicy={
'Grants': [
{
'Grantee': {
'EmailAddress': 'some@emailtotest.com',
'Type': 'AmazonCustomerByEmail',
},
'Permission': 'READ'
},
],
'Owner': {
'DisplayName': 'Whatever',
'ID': 'c3d78ab5093a9ab8a5184de715d409c2ab5a0e2da66f08c2f6cc5c0bdeadbeef'
}
}
)

参考資料

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする