AWS - S3 Unauthenticated Enum

Support HackTricks

S3 Public Buckets

Bucket jest uważany za „publiczny”, jeśli każdy użytkownik może wylistować zawartość bucketa, a za „prywatny”, jeśli zawartość bucketa może być wylistowana lub zapisana tylko przez określonych użytkowników.

Firmy mogą mieć błędnie skonfigurowane uprawnienia bucketów, co daje dostęp albo do wszystkiego, albo do wszystkich uwierzytelnionych w AWS w dowolnym koncie (czyli do każdego). Należy zauważyć, że nawet przy takich błędach niektóre działania mogą nie być możliwe do wykonania, ponieważ buckety mogą mieć własne listy kontroli dostępu (ACL).

Dowiedz się o błędach konfiguracji AWS-S3 tutaj: http://flaws.cloud i http://flaws2.cloud/

Finding AWS Buckets

Różne metody, aby znaleźć, kiedy strona internetowa korzysta z AWS do przechowywania niektórych zasobów:

Enumeration & OSINT:

  • Używając wtyczki przeglądarki wappalyzer

  • Używając burp (spidering sieci) lub ręcznie nawigując po stronie, wszystkie zasoby załadowane będą zapisane w Historii.

  • Sprawdź zasoby w domenach takich jak:

http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
  • Sprawdź CNAMES, ponieważ resources.domain.com może mieć CNAME bucket.s3.amazonaws.com

  • Sprawdź https://buckets.grayhatwarfare.com, stronę z już odkrytymi otwartymi bucketami.

  • Nazwa bucketa i nazwa domeny bucketa muszą być takie same.

  • flaws.cloud jest w IP 52.92.181.107 i jeśli tam pójdziesz, przekierowuje cię do https://aws.amazon.com/s3/. Również dig -x 52.92.181.107 daje s3-website-us-west-2.amazonaws.com.

  • Aby sprawdzić, czy to jest bucket, możesz również odwiedzić https://flaws.cloud.s3.amazonaws.com/.

Brute-Force

Możesz znaleźć buckety, brute-forcing nazwy związane z firmą, którą testujesz:

# 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

Dzięki otwartym bucketom S3, BucketLoot może automatycznie szukać interesujących informacji.

Find the Region

Możesz znaleźć wszystkie obsługiwane regiony przez AWS w https://docs.aws.amazon.com/general/latest/gr/s3.html

By DNS

Możesz uzyskać region bucketa za pomocą dig i nslookup, wykonując żądanie DNS odkrytego 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.

Sprawdź, czy rozwiązana domena zawiera słowo "website". Możesz uzyskać dostęp do statycznej strony internetowej, przechodząc do: flaws.cloud.s3-website-us-west-2.amazonaws.com lub możesz uzyskać dostęp do koszyka, odwiedzając: flaws.cloud.s3-us-west-2.amazonaws.com

Próbując

Jeśli spróbujesz uzyskać dostęp do koszyka, ale w nazwie domeny określisz inny region (na przykład koszyk znajduje się w bucket.s3.amazonaws.com, ale próbujesz uzyskać dostęp do bucket.s3-website-us-west-2.amazonaws.com, wtedy zostaniesz skierowany do poprawnej lokalizacji:

Enumeracja koszyka

Aby przetestować otwartość koszyka, użytkownik może po prostu wpisać adres URL w swojej przeglądarce internetowej. Prywatny koszyk odpowie "Access Denied". Publiczny koszyk wyświetli pierwsze 1,000 obiektów, które zostały zapisane.

Otwarty dla wszystkich:

Prywatny:

Możesz to również sprawdzić za pomocą 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]

Jeśli koszyk nie ma nazwy domeny, próbując go enumerować, wprowadź tylko nazwę koszyka i nie całą domenę AWSs3. Przykład: s3://<BUCKETNAME>

Szablon publicznego URL-a

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

Uzyskaj identyfikator konta z publicznego koszyka

Możliwe jest określenie konta AWS, korzystając z nowego S3:ResourceAccount klucza warunkowego polityki. Ten warunek ogranicza dostęp na podstawie koszyka S3, w którym znajduje się konto (inne polityki oparte na koncie ograniczają dostęp na podstawie konta, w którym znajduje się żądający podmiot). A ponieważ polityka może zawierać znaki wieloznaczne, możliwe jest znalezienie numeru konta tylko jeden numer na raz.

To narzędzie automatyzuje ten proces:

# 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

Ta technika działa również z adresami URL API Gateway, adresami URL Lambda, zestawami danych Data Exchange, a nawet do uzyskania wartości tagów (jeśli znasz klucz tagu). Więcej informacji można znaleźć w oryginalnych badaniach oraz w narzędziu conditional-love, aby zautomatyzować tę eksploitację.

Potwierdzanie, że koszyk należy do konta AWS

Jak wyjaśniono w tym wpisie na blogu, jeśli masz uprawnienia do wylistowania koszyka możliwe jest potwierdzenie accountID, do którego należy koszyk, wysyłając żądanie takie jak:

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>

Jeśli błąd to „Access Denied”, oznacza to, że identyfikator konta był błędny.

Użyte e-maile jako enumeracja konta root

Jak wyjaśniono w tym wpisie na blogu, możliwe jest sprawdzenie, czy adres e-mail jest powiązany z jakimkolwiek kontem AWS, próbując przyznać e-mailowi uprawnienia do koszyka S3 za pomocą ACL. Jeśli to nie wywoła błędu, oznacza to, że e-mail jest użytkownikiem root jakiegoś konta 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

Wsparcie HackTricks

Last updated