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/
  • Перевірте CNAMES, оскільки resources.domain.com може мати CNAME bucket.s3.amazonaws.com

  • Перевірте https://buckets.grayhatwarfare.com, веб-сайт з уже виявленими відкритими бакетами.

  • Ім'я бакета та доменне ім'я бакета повинні бути однаковими.

  • flaws.cloud знаходиться в IP 52.92.181.107, і якщо ви туди перейдете, вас перенаправить на https://aws.amazon.com/s3/. Також, dig -x 52.92.181.107 дає s3-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

Ви можете отримати регіон бакета за допомогою dig та nslookup, зробивши DNS запит виявленої 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". Ви можете отримати доступ до статичного веб-сайту, перейшовши за адресою: 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 у своєму веб-браузері. Приватний бакет відповість "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

Отримання ID облікового запису з публічного бакету

Можливо визначити обліковий запис AWS, скориставшись новим S3:ResourceAccount ключем умови політики. Ця умова обмежує доступ на основі 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

Ця техніка також працює з URL-адресами API Gateway, URL-адресами Lambda, наборами даних Data Exchange і навіть для отримання значення тегів (якщо ви знаєте ключ тегу). Ви можете знайти більше інформації в оригінальному дослідженні та інструменті 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>

Якщо помилка є "Доступ заборонено", це означає, що ідентифікатор облікового запису був неправильним.

Використані електронні адреси для перерахунку кореневих облікових записів

Як пояснено в цьому блозі, можливо перевірити, чи пов'язана електронна адреса з будь-яким обліковим записом AWS, спробувавши надати електронній адресі дозволи на S3 бакет через ACL. Якщо це не викликає помилки, це означає, що електронна адреса є кореневим користувачем деякого облікового запису 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'
}
}
)

References

Підтримайте HackTricks

Last updated