- Tracebit은 공개·비공개 S3 버킷의 AWS Account ID를 추정하는 기법을 정리하고, 예시 버킷
bucket-alpha에서123456789101을 복원함 - 핵심 단서는 S3용 Interface VPC Endpoint 정책의
s3:ResourceAccount조건과, 요청이 자체 CloudTrail 로그에 남는지 여부임 - 비공개 버킷은 최종 응답이 계속
AccessDenied여도, VPC Endpoint 정책을 통과한 요청만 CloudTrail에 나타나므로 숫자 패턴 일치 여부를 판별할 수 있음 - 정책 전파와 CloudTrail 지연 때문에 단순 탐색은 약
40 * 12분 = 8시간까지 걸릴 수 있지만,aws:userid와RoleSessionName을 이용한 120개 정책 문장 병렬 테스트로 10분 미만까지 줄어듦 - 이 기법은
StringLike가s3:ResourceAccount에 부분 일치를 허용하기 때문에 가능하며, 일부 활동은 버킷 소유자의 CloudTrail에도 남을 수 있음
공개 버킷 기법에서 출발한 확장
- 2021년 Ben Bridts는 공개 S3 버킷의 AWS Account ID를 찾는 방법을 공개함
- Tracebit의 방식은 이 아이디어의 여러 요소를 재사용하되, 비공개 버킷까지 포함해 S3 버킷의 Account ID를 찾는 데 초점을 둠
- 예시 실행에서는
bucket-alpha에 대해 CloudTrail에서 통과한 세션 이름을 모아 최종적으로123456789101을 복원함
기존 공개 버킷 방식이 가능한 이유
- Ben Bridts의 방법은 세 조건이 맞물려 작동함
- 요청에 IAM 정책을 적용할 수 있음
- 정책이 요청을 허용했는지 차단했는지 추론할 수 있음
s3:ResourceAccount조건 키에 와일드카드 매칭을 적용할 수 있음
- 공개 버킷에서는 정책이 요청을 막으면
AccessDenied가 나고, 정책이 허용하면 요청이 성공하므로 정책 통과 여부를 쉽게 구분할 수 있음 s3:ResourceAccount를 한 자리씩 좁히면 전체 탐색 공간이 수조 개에서 수백 개 수준으로 줄어듦
비공개 버킷에서는 응답 대신 CloudTrail을 본다
- 비공개 버킷은 어떤 정책을 적용해도 대상 버킷 정책 때문에 최종 응답이 AccessDenied가 됨
- Tracebit 방식은 응답 결과가 아니라 요청이 자체 CloudTrail 로그에 나타나는지를 기준으로 삼음
- 요청이 CloudTrail에 나타나면 VPC Endpoint 정책은 허용했고, 이후 버킷 정책에서 거부된 것임
- 요청이 CloudTrail에 없으면 VPC Endpoint 정책에서 차단된 것임
- S3용 Interface VPC Endpoint를 만들면 요청에 VPC Endpoint 정책을 적용할 수 있고, 이 정책은 버킷 정책과 요청 주체의 IAM 정책 등 다른 정책들과 함께 평가됨
- VPC Endpoint 정책에서도
StringLike와일드카드와 리소스 조건 키를 사용할 수 있어 같은 탐색 방식이 가능함
기본 절차: 리전 확인부터 이벤트 조회까지
- 먼저 대상 버킷의 리전을 찾아야 함
- 버킷 HTTP 엔드포인트에
curl을 보내면 요청이 금지되어도x-amz-bucket-region헤더가 반환됨 - 예시에서는
bucket-alpha.s3.amazonaws.com응답 헤더에서us-east-1을 확인함
- 버킷 HTTP 엔드포인트에
- 대상 버킷과 같은 리전에 VPC와 S3용 VPC Endpoint를 배포함
- VPC Endpoint는 정책 적용이 가능한 Interface 타입이어야 함
- 해당 VPC Endpoint가 VPC의 S3 요청에 영향을 주므로, 이 목적 전용 VPC를 만드는 것이 좋음
- VPC 안에서 S3 요청을 보내기 위해 EC2 인스턴스를 실행하고, 해당 인스턴스가 S3용 VPC Endpoint를 사용하는지 확인함
- VPC Endpoint 정책을 수정해
s3:ResourceAccount가 특정 숫자로 시작하는지 테스트함- 예를 들어 Account ID가
0으로 시작하는지 확인하려면s3:ResourceAccount에"0*"조건을 둠
- 예를 들어 Account ID가
- EC2 인스턴스에서 대상 버킷에
GetBucketAcl같은 Management 요청을 보냄- Management 요청을 쓰면 CloudTrail 설정에서 별도 처리가 덜 필요함
- 요청 결과는 예상대로
AccessDenied가 됨
CloudTrail로 숫자 패턴을 판별하는 방식
- 요청 후 CloudTrail에서
GetBucketAcl이벤트가 나타나는지 조회함 - 이벤트가 나타나면 VPC Endpoint 정책이 요청을 허용한 것이므로 Account ID가 테스트한 패턴과 일치함
- 예:
"0*"조건에서 이벤트가 보이면 Account ID가0으로 시작함
- 예:
- 이벤트가 나타나지 않으면 VPC Endpoint 정책이 요청을 막은 것이므로 해당 패턴과 일치하지 않음
- CloudTrail에 이벤트가 나타나는 데 몇 분이 걸릴 수 있어, 이벤트가 없다고 판단하기 전 10분 대기를 권장함
- VPC Endpoint 정책 변경도 완전히 전파되어 적용되는 데 시간이 걸리며, 정책 수정 후 5분 대기가 잘 작동함
자동화했지만 기본 방식은 느리다
- Tracebit은 이 과정을 자동화하는 스크립트를 작성해 버킷의 Account ID를 안정적으로 찾을 수 있게 함
- 단순히 한 자리씩 모든 숫자를 확인하는 대신, 각 자리에서 이진 탐색에 가까운 방식으로 테스트 횟수를 줄임
- 예를 들어
s3:ResourceAccount조건에["0*", "1*", "2*", "3*", "4*"]처럼 여러 패턴을 넣어 범위를 나눔
- 예를 들어
- 그래도 정책 적용과 CloudTrail 확인 대기 시간이 병목으로 남음
- 이진 탐색을 써도 약
40 * 12분 = 8시간이 걸릴 수 있음
- 이진 탐색을 써도 약
- 몇 시간 실행한 예시에서는
bucket-alpha의 Account ID로123456789101을 성공적으로 찾음
120개 정책 문장으로 10분 미만까지 단축
- 더 빠른 방식은 VPC Endpoint 정책에 가능한 모든 자리·숫자 조합을 미리 넣는 것임
- 정책에는 총 120개 문장이 들어감
- AWS Account ID의 각 위치별 가능한 숫자 10개를 테스트함
- 각 문장은
s3:ResourceAccount의 특정 자리 패턴과aws:userid조건을 함께 사용함
aws:userid조건은 STSAssumeRole호출에서 자유롭게 지정할 수 있는RoleSessionName값을 매칭하는 데 사용됨- 특정
RoleSessionName으로 역할을 가정하면 특정 자리·숫자 테스트에 해당하는 정책 문장을 선택적으로 통과시킬 수 있음
- 특정
- 이 정책은 VPC Endpoint 정책의 최대 문자 길이에 간신히 들어감
- 모든 120개 가능성을 병렬로 테스트하므로 정책을 매번 수정하거나 CloudTrail 결과를 개별적으로 기다릴 필요가 줄어듦
- 이 방식으로 Account ID 탐색 시간이 10분 미만으로 줄어듦
노출 범위와 응용 가능성
- 일부 활동은 대상 버킷 소유자의 CloudTrail 로그에 보일 수 있음
- Tracebit은 공개 전에 AWS Security 팀과 상의함
- AWS Account ID가 민감 정보인지에 대해서는 이미 많은 논의가 있었고, 예시 CloudTrail 이벤트에서는 서드파티 Account ID가
HIDDEN_DUE_TO_SECURITY_REASONS로 가려져 있음 - 같은 기법은 버킷과 관련된 다른 리소스 조건 키에도 적용될 수 있음
- 예:
aws:ResourceOrgID - 예:
aws:ResourceOrgPaths - 예:
aws:ResourceTag
- 예:
- S3 외에 이 기법을 적용할 수 있는 다른 서비스에도 응용될 수 있음
- 모든 리전에 상호 피어링된 VPC와 VPC Endpoint를 만들면 대상 버킷의 리전에 관계없이 작동하는 구성을 만들 수 있을 가능성이 있음
- 이 기법은
s3:ResourceAccount조건에 대해 StringLike 부분 일치를 사용할 수 있기 때문에 가능함 - VPC Endpoint 정책에 의해 거부된 이벤트도 CloudTrail에 기록된다면 유익할 수 있음