Amazon S3는 데이터가 정지 상태일 때 보호를 달성하기 위한 여러 옵션을 제공합니다. 옵션에는 권한(정책), 암호화(클라이언트 및 서버 측), 버킷 버전 관리 및 MFA기반 삭제가 포함됩니다. 사용자는 데이터 보호를 달성하기 위해 이러한 옵션 중 어느 것이든 활성화할 수 있습니다. 데이터 복제는 AWS의 내부 기능으로, S3가 모든 가용 영역에 걸쳐 각 객체를 자동으로 복제하며, 이 경우 조직에서 이를 활성화할 필요가 없습니다.
리소스 기반 권한을 사용하면 버킷의 하위 디렉토리에 대한 권한을 별도로 정의할 수 있습니다.
버킷 버전 관리 및 MFA 기반 삭제
버킷 버전 관리가 활성화되면, 파일 내의 파일을 변경하려는 모든 작업은 파일의 새 버전을 생성하며, 이전 내용도 유지됩니다. 따라서 내용이 덮어쓰여지지 않습니다.
또한, MFA 기반 삭제는 S3 버킷의 파일 버전이 삭제되는 것을 방지하고 버킷 버전 관리가 비활성화되는 것을 방지하므로 공격자가 이러한 파일을 변경할 수 없습니다.
S3 액세스 로그
S3 액세스 로그를 활성화(기본적으로 비활성화됨)하여 특정 버킷에 대해 로그를 다른 버킷에 저장하여 누가 버킷에 접근하는지 알 수 있습니다(두 버킷은 동일한 리전에 있어야 함).
S3 사전 서명된 URL
사전 서명된 URL을 생성하여 일반적으로 버킷의 지정된 파일에 접근하는 데 사용할 수 있습니다. 사전 서명된 URL은 다음과 같습니다:
A presigned URL can be created from the cli using credentials of a principal with access to the object (계정에 접근 권한이 없는 경우, 더 짧은 presigned URL이 생성되지만 쓸모가 없습니다)
이 옵션은 최소한의 구성을 요구하며 사용되는 암호화 키의 모든 관리는 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에 전송합니다 (암호화된 데이터의 메타데이터로 저장됨)
복호화:
암호화된 데이터와 암호화된 DEK가 클라이언트에 전송됩니다
클라이언트는 CMK를 사용하여 암호화된 키를 복호화해 달라고 KMS에 요청하고 KMS는 평문 DEK를 다시 전송합니다
클라이언트는 이제 암호화된 데이터를 복호화할 수 있습니다
사용자 제공 키를 사용한 클라이언트 측 암호화, CSE-C
이 메커니즘을 사용하면 제공된 키를 활용하고 AWS-SDK 클라이언트를 사용하여 데이터를 S3에 저장하기 전에 암호화할 수 있습니다.
암호화:
클라이언트가 DEK를 생성하고 평문 데이터를 암호화합니다
그런 다음, 자신의 사용자 정의 CMK를 사용하여 DEK를 암호화합니다
암호화된 데이터 + 암호화된 DEK를 S3에 제출하여 저장합니다
복호화:
S3가 암호화된 데이터와 DEK를 전송합니다
클라이언트는 DEK를 암호화하는 데 사용된 CMK를 이미 가지고 있으므로 DEK를 복호화하고 평문 DEK를 사용하여 데이터를 복호화합니다
열거
AWS 조직을 타협하는 전통적인 주요 방법 중 하나는 공개적으로 접근 가능한 버킷을 타협하는 것에서 시작됩니다. 당신은 이 페이지에서공개 버킷 열거기를 찾을 수 있습니다.
# Get buckets ACLsawss3apiget-bucket-acl--bucket<bucket-name>awss3apiget-object-acl--bucket<bucket-name>--keyflag# Get policyawss3apiget-bucket-policy--bucket<bucket-name>awss3apiget-bucket-policy-status--bucket<bucket-name>#if it's public# list S3 buckets associated with a profileawss3lsawss3apilist-buckets# list content of bucket (no creds)awss3lss3://bucket-name--no-sign-requestawss3lss3://bucket-name--recursive# list content of bucket (with creds)awss3lss3://bucket-nameawss3apilist-objects-v2--bucket<bucket-name>awss3apilist-objects--bucket<bucket-name>awss3apilist-object-versions--bucket<bucket-name># copy local folder to S3awss3cpMyFolders3://bucket-name--recursive# deleteawss3rbs3://bucket-name–-force# download a whole S3 bucketawss3syncs3://<bucket>/.# move S3 bucket to different locationawss3syncs3://oldbuckets3://newbucket--source-regionus-west-1# list the sizes of an S3 bucket and its contentsawss3apilist-objects--bucketBUCKETNAME--outputjson--query"[sum(Contents[].Size), length(Contents[])]"# Update Bucket policyawss3apiput-bucket-policy--policyfile:///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 ACLawss3apiget-bucket-acl--bucket<bucket-name># Way 1 to get the ACLawss3apiput-bucket-acl--bucket<bucket-name>--access-control-policyfile://acl.jsonawss3apiget-object-acl--bucket<bucket-name>--keyflag#Way 2 to get the ACLawss3apiput-object-acl--bucket<bucket-name>--keyflag--access-control-policyfile://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에 접근하는 데 유용합니다.
이 연구에 따르면 임의의 버킷의 응답을 다른 버킷에 속하는 것처럼 캐시할 수 있었습니다. 이는 예를 들어 자바스크립트 파일 응답을 변경하고 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 catalogsawsathenalist-data-catalogs# Get databases inside catalogawsathenalist-databases--catalog-name<catalog-name>awsathenalist-table-metadata--catalog-name<catalog-name>--database-name<db-name># Get query executions, queries and resultsawsathenalist-query-executionsawsathenaget-query-execution--query-execution-id<id># Get query and meta of resultsawsathenaget-query-results--query-execution-id<id># This will rerun the query and get the results# Get workgroups & Prepared statementsawsathenalist-work-groupsawsathenalist-prepared-statements--work-group<wg-name>awsathenaget-prepared-statement--statement-name<name>--work-group<wg-name># Run queryawsathenastart-query-execution--query-string<query>