AWS - S3 Unauthenticated Enum

Reading time: 8 minutes

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”**으로 간주되고, 버킷의 내용이 특정 사용자만 열람하거나 작성할 수 있으면 **“private”**로 간주됩니다.

기업은 버킷 권한이 잘못 구성되어 모든 것에 접근을 허용하거나 AWS의 어떤 계정으로 인증된 모든 사용자에게(즉 누구에게나) 접근을 허용할 수 있습니다. 다만 이러한 잘못된 구성에도 불구하고 버킷 자체의 access control lists (ACLs) 때문에 일부 작업은 수행할 수 없을 수도 있습니다.

AWS-S3 잘못된 구성에 대해 알아보기: http://flaws.cloud http://flaws2.cloud/

AWS 버킷 찾기

웹페이지가 AWS를 사용해 리소스를 저장하는 경우를 찾는 여러 방법:

Enumeration & OSINT:

  • wappalyzer 브라우저 플러그인 사용
  • burp(spidering the web)를 사용하거나 페이지를 수동으로 탐색하면 로드된 모든 resources가 History에 저장됩니다.
  • 다음과 같은 도메인에서 resources를 확인:
http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
  • resources.domain.combucket.s3.amazonaws.com 같은 CNAME을 가질 수 있으므로 CNAMES를 확인
  • s3dns – DNS 트래픽을 분석해 클라우드 스토리지 버킷(S3, GCP, Azure)을 수동적으로 식별하는 경량 DNS 서버입니다. CNAME을 감지하고 해석 체인을 따라가며 버킷 패턴과 매칭하여 brute-force 또는 API 기반 검색의 시끄러운 대안이 됩니다. recon 및 OSINT 워크플로에 적합합니다.
  • 이미 발견된 open buckets를 모아둔 사이트 https://buckets.grayhatwarfare.com 확인
  • **버킷 이름(bucket name)**과 **버킷 도메인 이름(bucket domain name)**은 같아야 합니다.
  • 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

pentesting 대상 회사와 관련된 이름을 brute-forcing하여 버킷을 찾을 수 있습니다:

# 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

S3 버킷에서 정보 수집

S3 오픈 버킷이 있을 경우, BucketLoot는 자동으로 흥미로운 정보를 검색할 수 있습니다.

리전 확인

지원되는 모든 AWS 리전은 https://docs.aws.amazon.com/general/latest/gr/s3.html에서 확인할 수 있습니다

DNS로 확인

발견한 IP에 대해 dig 또는 **nslookup**을 사용해 DNS 요청을 하면 버킷의 리전을 확인할 수 있습니다:

bash
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.

Check that the resolved domain have the word "website".
You can access the static website going to: flaws.cloud.s3-website-us-west-2.amazonaws.com
or you can access the bucket visiting: 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개의 객체를 나열합니다.

모두에게 공개:

비공개:

You can also check this with the cli:

bash
#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]

bucket에 도메인 이름이 없으면, enumerate하려 할 때 전체 AWSs3 도메인을 적지 말고 bucket 이름만 넣으세요. 예: s3://<BUCKETNAME>

공개 URL 템플릿

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

공개 Bucket에서 Account ID 얻기

AWS 계정을 새 S3:ResourceAccount Policy Condition Key를 이용해 확인할 수 있습니다. 이 조건은 계정이 속한 S3 bucket을 기준으로 액세스를 제한합니다 (다른 계정 기반 정책은 요청하는 주체가 속한 계정을 기준으로 제한합니다).
그리고 정책이 wildcards를 포함할 수 있기 때문에 계정 번호를 한 숫자씩 알아내는 것이 가능합니다.

이 도구는 이 과정을 자동화합니다:

bash
# 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에서도 작동하며, 태그 키를 알고 있다면 태그 값까지 얻을 수 있습니다. 자세한 내용과 이 exploitation을 자동화하는 도구는 original researchconditional-love를 참고하세요.

버킷이 AWS 계정에 속하는지 확인하기

this blog post, 버킷을 나열할 권한이 있다면 버킷이 속한 accountID를 다음과 같은 요청을 전송해 확인할 수 있습니다:

bash
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 account enumeration으로 사용

As explained in this blog post, ACLs를 통해 S3 버킷에 이메일 권한을 부여해보면 해당 이메일 주소가 어떤 AWS account와 연관되어 있는지 확인할 수 있습니다. 이 시도가 오류를 발생시키지 않으면 해당 이메일은 어떤 AWS 계정의 root user임을 의미합니다:

python
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 지원하기