AWS - S3 Unauthenticated Enum

Support HackTricks

S3 Public Buckets

バケットは、任意のユーザーがバケットの内容をリストできる場合、「パブリック」と見なされ、バケットの内容が特定のユーザーのみがリストまたは書き込みできる場合、**「プライベート」**と見なされます。

企業は、バケットの権限を誤って設定し、すべてのものまたはAWSの任意のアカウントで認証されたすべての人(つまり誰でも)にアクセスを許可することがあります。注意すべきは、そのような誤設定があっても、バケットが独自のアクセス制御リスト(ACL)を持っているため、いくつかのアクションは実行できない場合があることです。

AWS-S3の誤設定についてはこちらを参照してください: http://flaws.cloud および http://flaws2.cloud/

Finding AWS Buckets

ウェブページがAWSを使用してリソースを保存している場合を見つけるためのさまざまな方法:

Enumeration & OSINT:

  • wappalyzer ブラウザプラグインを使用

  • burp(ウェブのスパイダー)を使用するか、手動でページをナビゲートして、すべてのロードされたリソースが履歴に保存されます。

  • リソースを確認するドメイン:

http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
  • resources.domain.comのようなCNAMEを確認し、bucket.s3.amazonaws.comのCNAMEを持っている可能性があります。

  • すでに発見されたオープンバケットがあるウェブ https://buckets.grayhatwarfare.com を確認。

  • バケット名バケットドメイン名同じである必要があります。

  • flaws.cloudIP 52.92.181.107にあり、そこに行くと https://aws.amazon.com/s3/ にリダイレクトされます。また、dig -x 52.92.181.107s3-website-us-west-2.amazonaws.comを返します。

  • バケットであることを確認するために、https://flaws.cloud.s3.amazonaws.com/訪問することもできます。

Brute-Force

ペンテストしている会社に関連する名前をブルートフォースすることでバケットを見つけることができます:

# 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
### Remove lines ending with "."
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

S3オープンバケットがある場合、BucketLoot は自動的に興味深い情報を検索できます。

Find the Region

AWSがサポートするすべてのリージョンは https://docs.aws.amazon.com/general/latest/gr/s3.html で確認できます。

By DNS

発見されたIPのDNSリクエストを行うことで、**digおよびnslookup**を使用してバケットのリージョンを取得できます:

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 または、バケットにアクセスするには、次のURLを訪問します: flaws.cloud.s3-us-west-2.amazonaws.com

試してみる

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

バケットの列挙

バケットの公開状態をテストするには、ユーザーは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>

Public URL template

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

公開バケットからアカウントIDを取得

新しい S3:ResourceAccount ポリシー条件キー を利用することで、AWSアカウントを特定することが可能です。この条件は、アカウントが所属するS3バケットに基づいてアクセスを制限します(他のアカウントベースのポリシーは、リクエスト元のプリンシパルが所属するアカウントに基づいて制限します)。 そして、ポリシーにはワイルドカードを含めることができるため、一度に一つの数字だけでアカウント番号を見つけることが可能です。

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

# 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、さらにはタグの値を取得するためにも機能します(タグキーを知っている場合)。詳細はoriginal researchおよびこのエクスプロイトを自動化するツールconditional-loveで確認できます。

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

このブログ記事で説明されているように、バケットをリストする権限がある場合、次のようなリクエストを送信することで、そのバケットが属する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>

エラーが「Access Denied」の場合、それはアカウントIDが間違っていることを意味します。

ルートアカウント列挙として使用されるメール

このブログ記事で説明されているように、S3バケットにACLを介してメールアドレスに権限を付与しようとすることで、そのメールアドレスがAWSアカウントに関連しているかどうかを確認することが可能です。エラーが発生しない場合、そのメールは何らかのAWSアカウントのルートユーザーであることを意味します:

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

参考文献

HackTricksをサポートする

Last updated