AWS - S3, Athena & Glacier Enum

Support HackTricks

S3

Amazon S3는 대량의 데이터를 저장할 수 있는 서비스입니다.

Amazon S3는 데이터가 정지 상태일 때 보호를 달성하기 위한 여러 옵션을 제공합니다. 옵션에는 권한(정책), 암호화(클라이언트 및 서버 측), 버킷 버전 관리MFA 기반 삭제가 포함됩니다. 사용자는 데이터 보호를 달성하기 위해 이러한 옵션 중 하나를 활성화할 수 있습니다. 데이터 복제는 AWS의 내부 기능으로, S3가 모든 가용 영역에 걸쳐 각 객체를 자동으로 복제하며, 이 경우 조직에서 이를 활성화할 필요가 없습니다.

리소스 기반 권한을 사용하면 버킷의 하위 디렉터리에 대한 권한을 별도로 정의할 수 있습니다.

버킷 버전 관리 및 MFA 기반 삭제

버킷 버전 관리가 활성화되면, 파일 내의 파일을 변경하려는 모든 작업은 파일의 새 버전을 생성하며, 이전 내용도 유지됩니다. 따라서 내용이 덮어쓰여지지 않습니다.

또한, MFA 기반 삭제는 S3 버킷의 파일 버전이 삭제되는 것을 방지하고 버킷 버전 관리가 비활성화되는 것을 방지하므로 공격자가 이러한 파일을 변경할 수 없습니다.

S3 액세스 로그

S3 액세스 로그를 활성화(기본적으로 비활성화됨)하여 특정 버킷에 대해 로그를 다른 버킷에 저장하여 누가 버킷에 접근하는지 알 수 있습니다(두 버킷은 동일한 리전에 있어야 함).

S3 사전 서명된 URL

사전 서명된 URL을 생성하여 일반적으로 버킷의 지정된 파일에 접근하는 데 사용할 수 있습니다. 사전 서명된 URL은 다음과 같습니다:

https://<bucket-name>.s3.us-east-1.amazonaws.com/asd.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAUUE8GZC4S5L3TY3P%2F20230227%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230227T142551Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjELf%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIBhQpdETJO3HKKDk2hjNIrPWwBE8gZaQccZFV3kCpPCWAiEAid3ueDtFFU%2FOQfUpvxYTGO%2BHoS4SWDMUrQAE0pIaB40qggMIYBAAGgwzMTgxNDIxMzg1NTMiDJLI5t7gr2EGxG1Y5CrfAioW0foHIQ074y4gvk0c%2B%2Fmqc7cNWb1njQslQkeePHkseJ3owzc%2FCwkgE0EuZTd4mw0aJciA2XIbJRCLPWTb%2FCBKPnIMJ5aBzIiA2ltsiUNQTTUxYmEgXZoJ6rFYgcodnmWW0Et4Xw59UlHnCDB2bLImxPprriyCzDDCD6nLyp3J8pFF1S8h3ZTJE7XguA8joMs4%2B2B1%2FeOZfuxXKyXPYSKQOOSbQiHUQc%2BFnOfwxleRL16prWk1t7TamvHR%2Bt3UgMn5QWzB3p8FgWwpJ6GjHLkYMJZ379tkimL1tJ7o%2BIod%2FMYrS7LDCifP9d%2FuYOhKWGhaakPuJKJh9fl%2B0vGl7kmApXigROxEWon6ms75laXebltsWwKcKuYca%2BUWu4jVJx%2BWUfI4ofoaGiCSaKALTqwu4QNBRT%2BMoK6h%2BQa7gN7JFGg322lkxRY53x27WMbUE4unn5EmI54T4dWt1%2Bg8ljDS%2BvKfBjqmAWRwuqyfwXa5YC3xxttOr3YVvR6%2BaXpzWtvNJQNnb6v0uI3%2BTtTexZkJpLQYqFcgZLQSxsXWSnf988qvASCIUhAzp2UnS1uqy7QjtD5T73zksYN2aesll7rvB80qIuujG6NOdHnRJ2M5%2FKXXNo1Yd15MtzPuSjRoSB9RSMon5jFu31OrQnA9eCUoawxbB0nHqwK8a43CKBZHhA8RoUAJW%2B48EuFsp3U%3D&X-Amz-Signature=3436e4139e84dbcf5e2e6086c0ebc92f4e1e9332b6fda24697bc339acbf2cdfa

A presigned URL can be created from the cli using credentials of a principal with access to the object (계정에 접근 권한이 없는 경우, 짧은 presigned URL이 생성되지만 쓸모가 없습니다)

aws s3 presign --region <bucket-region> 's3://<bucket-name>/<file-name>'

presigned URL을 생성하는 데 필요한 유일한 권한은 부여된 권한이므로, 이전 명령의 경우 주체가 필요한 유일한 권한은 s3:GetObject입니다.

다른 권한으로도 presigned URL을 생성할 수 있습니다:

import boto3
url = boto3.client('s3').generate_presigned_url(
ClientMethod='put_object',
Params={'Bucket': 'BUCKET_NAME', 'Key': 'OBJECT_KEY'},
ExpiresIn=3600
)

S3 암호화 메커니즘

DEK는 데이터 암호화 키를 의미하며, 데이터 암호화에 항상 생성되고 사용되는 키입니다.

S3 관리 키를 사용한 서버 측 암호화, SSE-S3

이 옵션은 최소한의 구성을 요구하며 사용되는 암호화 키의 모든 관리는 AWS에 의해 관리됩니다. 당신이 해야 할 일은 데이터를 업로드하는 것이며, S3가 모든 다른 측면을 처리합니다. S3 계정의 각 버킷은 버킷 키가 할당됩니다.

  • 암호화:

  • 객체 데이터 + 생성된 평문 DEK --> 암호화된 데이터 (S3에 저장됨)

  • 생성된 평문 DEK + S3 마스터 키 --> 암호화된 DEK (S3에 저장됨) 및 평문은 메모리에서 삭제됨

  • 복호화:

  • 암호화된 DEK + S3 마스터 키 --> 평문 DEK

  • 평문 DEK + 암호화된 데이터 --> 객체 데이터

이 경우 키는 AWS에 의해 관리됩니다 (회전은 3년에 한 번만). 자신의 키를 사용하면 회전, 비활성화 및 접근 제어를 적용할 수 있습니다.

KMS 관리 키를 사용한 서버 측 암호화, SSE-KMS

이 방법은 S3가 키 관리 서비스를 사용하여 데이터 암호화 키를 생성할 수 있게 합니다. KMS는 키 관리에 대한 훨씬 더 큰 유연성을 제공합니다. 예를 들어, CMK에 대해 비활성화, 회전 및 접근 제어를 적용할 수 있으며, AWS Cloud Trail을 사용하여 사용에 대한 주문을 할 수 있습니다.

  • 암호화:

  • S3는 KMS CMK에서 데이터 키를 요청합니다

  • KMS는 CMK를 사용하여 평문 DEK와 암호화된 DEK 쌍을 생성하고 이를 S3에 전송합니다

  • S3는 평문 키를 사용하여 데이터를 암호화하고, 암호화된 데이터와 암호화된 키를 저장하며 평문 키는 메모리에서 삭제합니다

  • 복호화:

  • S3는 KMS에 객체의 암호화된 데이터 키를 복호화해 달라고 요청합니다

  • KMS는 CMK로 데이터 키를 복호화하고 이를 S3에 다시 전송합니다

  • S3는 객체 데이터를 복호화합니다

사용자 제공 키를 사용한 서버 측 암호화, SSE-C

이 옵션은 AWS 외부에서 이미 사용하고 있을 수 있는 자신의 마스터 키를 제공할 수 있는 기회를 제공합니다. 고객이 제공한 키는 데이터와 함께 S3로 전송되며, S3는 이를 암호화합니다.

  • 암호화:

  • 사용자가 객체 데이터 + 고객 키를 S3에 전송합니다

  • 고객 키는 데이터를 암호화하는 데 사용되며 암호화된 데이터가 저장됩니다

  • 고객 키의 소금이 추가된 HMAC 값도 향후 키 검증을 위해 저장됩니다

  • 고객 키는 메모리에서 삭제됩니다

  • 복호화:

  • 사용자가 고객 키를 전송합니다

  • 키는 저장된 HMAC 값에 대해 검증됩니다

  • 고객 제공 키가 데이터를 복호화하는 데 사용됩니다

KMS를 사용한 클라이언트 측 암호화, CSE-KMS

SSE-KMS와 유사하게, 이 방법도 데이터 암호화 키를 생성하기 위해 키 관리 서비스를 사용합니다. 그러나 이번에는 S3가 아닌 클라이언트를 통해 KMS가 호출됩니다. 암호화는 클라이언트 측에서 이루어지며, 암호화된 데이터는 S3에 저장됩니다.

  • 암호화:

  • 클라이언트가 KMS에 데이터 키를 요청합니다

  • KMS는 평문 DEK와 CMK로 암호화된 DEK를 반환합니다

  • 두 키가 다시 전송됩니다

  • 클라이언트는 평문 DEK로 데이터를 암호화하고 암호화된 데이터 + 암호화된 DEK를 S3에 전송합니다 (S3 내부의 암호화된 데이터의 메타데이터로 저장됨)

  • 복호화:

  • 암호화된 데이터와 암호화된 DEK가 클라이언트에 전송됩니다

  • 클라이언트는 CMK를 사용하여 암호화된 키를 복호화해 달라고 KMS에 요청하고 KMS는 평문 DEK를 다시 전송합니다

  • 클라이언트는 이제 암호화된 데이터를 복호화할 수 있습니다

사용자 제공 키를 사용한 클라이언트 측 암호화, CSE-C

이 메커니즘을 사용하면 제공된 키를 활용하고 AWS-SDK 클라이언트를 사용하여 데이터를 S3에 전송하기 전에 암호화할 수 있습니다.

  • 암호화:

  • 클라이언트가 DEK를 생성하고 평문 데이터를 암호화합니다

  • 그런 다음, 자신의 사용자 정의 CMK를 사용하여 DEK를 암호화합니다

  • 암호화된 데이터 + 암호화된 DEK를 S3에 제출하여 저장합니다

  • 복호화:

  • S3가 암호화된 데이터와 DEK를 전송합니다

  • 클라이언트는 DEK를 암호화하는 데 사용된 CMK를 이미 가지고 있으므로 DEK를 복호화하고 평문 DEK를 사용하여 데이터를 복호화합니다

열거

AWS 조직을 타협하는 전통적인 주요 방법 중 하나는 공개적으로 접근 가능한 버킷을 타협하는 것에서 시작됩니다. 당신은 이 페이지에서 공개 버킷 열거기를 찾을 수 있습니다.

# Get buckets ACLs
aws s3api get-bucket-acl --bucket <bucket-name>
aws s3api get-object-acl --bucket <bucket-name> --key flag

# Get policy
aws s3api get-bucket-policy --bucket <bucket-name>
aws s3api get-bucket-policy-status --bucket <bucket-name> #if it's public

# list S3 buckets associated with a profile
aws s3 ls
aws s3api list-buckets

# list content of bucket (no creds)
aws s3 ls s3://bucket-name --no-sign-request
aws s3 ls s3://bucket-name --recursive

# list content of bucket (with creds)
aws s3 ls s3://bucket-name
aws s3api list-objects-v2 --bucket <bucket-name>
aws s3api list-objects --bucket <bucket-name>
aws s3api list-object-versions --bucket <bucket-name>

# copy local folder to S3
aws s3 cp MyFolder s3://bucket-name --recursive

# delete
aws s3 rb s3://bucket-name –-force

# download a whole S3 bucket
aws s3 sync s3://<bucket>/ .

# move S3 bucket to different location
aws s3 sync s3://oldbucket s3://newbucket --source-region us-west-1

# list the sizes of an S3 bucket and its contents
aws s3api list-objects --bucket BUCKETNAME --output json --query "[sum(Contents[].Size), length(Contents[])]"

# Update Bucket policy
aws s3api put-bucket-policy --policy file:///root/policy.json --bucket <bucket-name>
##JSON policy example
{
"Id": "Policy1568185116930",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1568184932403",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::welcome",
"Principal": "*"
},
{
"Sid": "Stmt1568185007451",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::welcome/*",
"Principal": "*"
}
]
}

# Update bucket ACL
aws s3api get-bucket-acl --bucket <bucket-name> # Way 1 to get the ACL
aws s3api put-bucket-acl --bucket <bucket-name> --access-control-policy file://acl.json

aws s3api get-object-acl --bucket <bucket-name> --key flag #Way 2 to get the ACL
aws s3api put-object-acl --bucket <bucket-name> --key flag --access-control-policy file://objacl.json

##JSON ACL example
## Make sure to modify the Owner’s displayName and ID according to the Object ACL you retrieved.
{
"Owner": {
"DisplayName": "<DisplayName>",
"ID": "<ID>"
},
"Grants": [
{
"Grantee": {
"Type": "Group",
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
},
"Permission": "FULL_CONTROL"
}
]
}
## An ACL should give you the permission WRITE_ACP to be able to put a new ACL

dual-stack

S3 버킷에 접근하려면 가상 호스팅 스타일 또는 경로 스타일 엔드포인트 이름을 사용하여 이중 스택 엔드포인트를 통해 접근할 수 있습니다. 이는 IPv6를 통해 S3에 접근하는 데 유용합니다.

이중 스택 엔드포인트는 다음 구문을 사용합니다:

  • bucketname.s3.dualstack.aws-region.amazonaws.com

  • s3.dualstack.aws-region.amazonaws.com/bucketname

Privesc

다음 페이지에서 S3 권한을 악용하여 권한 상승하는 방법을 확인할 수 있습니다:

Unauthenticated Access

S3 Post Exploitation

Persistence

Other S3 vulns

S3 HTTP Cache Poisoning Issue

이 연구에 따르면 임의의 버킷의 응답을 다른 버킷의 것처럼 캐시하는 것이 가능했습니다. 이는 예를 들어 자바스크립트 파일 응답을 변경하고 S3를 사용하여 정적 코드를 저장하는 임의의 페이지를 손상시키는 데 악용될 수 있습니다.

Amazon Athena

Amazon Athena는 Amazon Simple Storage Service(Amazon S3)에서 표준 SQL을 사용하여 데이터를 직접 분석하기 쉽게 해주는 대화형 쿼리 서비스입니다.

모니터링되는 S3 버킷에 나타날 콘텐츠 형식으로 관계형 DB 테이블을 준비해야 합니다. 그런 다음 Amazon Athena는 로그에서 DB를 채울 수 있으므로 쿼리할 수 있습니다.

Amazon Athena는 이미 암호화된 S3 데이터를 쿼리할 수 있는 기능을 지원하며, 그렇게 구성된 경우 Athena는 쿼리 결과를 암호화할 수 있으며, 이는 S3에 저장될 수 있습니다.

이 결과의 암호화는 기본 쿼리된 S3 데이터와 독립적이며, S3 데이터가 암호화되지 않은 경우에도 쿼리된 결과는 암호화될 수 있습니다. 알아야 할 몇 가지 사항은 Amazon Athena가 다음 S3 암호화 방법SSE-S3, SSE-KMS, CSE-KMS암호화된 데이터만 지원한다는 것입니다.

SSE-C 및 CSE-E는 지원되지 않습니다. 이 외에도 Amazon Athena는 쿼리 자체와 동일한 지역에 있는 암호화된 객체에 대해서만 쿼리를 실행한다는 점을 이해하는 것이 중요합니다. KMS를 사용하여 암호화된 S3 데이터를 쿼리해야 하는 경우, Athena 사용자가 쿼리를 수행할 수 있도록 특정 권한이 필요합니다.

Enumeration

# Get catalogs
aws athena list-data-catalogs

# Get databases inside catalog
aws athena list-databases --catalog-name <catalog-name>
aws athena list-table-metadata --catalog-name <catalog-name> --database-name <db-name>

# Get query executions, queries and results
aws athena list-query-executions
aws athena get-query-execution --query-execution-id <id> # Get query and meta of results
aws athena get-query-results --query-execution-id <id> # This will rerun the query and get the results

# Get workgroups & Prepared statements
aws athena list-work-groups
aws athena list-prepared-statements --work-group <wg-name>
aws athena get-prepared-statement --statement-name <name> --work-group <wg-name>

# Run query
aws athena start-query-execution --query-string <query>

References

HackTricks 지원하기

Last updated