AWS 보안 스터디 그룹 ( 23.08.27 ~
1주차 : S3 취약점 및 보안
- AWS CloudFormation 스택 배포
▶ AWS CloudFormation : AWS의 대표적인 IaC 기반의 구성 조정 도구
스택을 생성할 때 마다 AWS CloudFormation에서 템플릿에 설명된 리소스를 프로비저닝과 구성을 담당
AWS 리소스를 수동으로 생성하거나 구성할 필요가 없고 어떤 것이 무엇에 의존하는지 파악할 필요 X
▶ 장점 : 인프라 관리 간소화, 신속하게 인프라 복제, 인프라 변경 사항을 쉽게 제어 및 추적
▶ 템플릿 및 스택으로 작업
- 템플릿을 생성하여 AWS 리소스와 해당 속성에 대해 설명
- 스택을 생성할 때마다 AWS CloudFormation에서 템플릿에 설명된 리소스를 프로비저
KeyName에서 사용하는 Key 선택 필요
2. IAM 자격증명 설정 및 CloudFormation 스택 배포 (cli에서)
# aws configure
초기화 방법 : .aws 폴더 삭제
# 변수 지정
KEYNAME=<각자 자신의 SSH Keypair Name>
# YAML 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/security/ahss-ec2.yaml
# CloudFormation 스택 배포
aws cloudformation deploy --template-file ahss-ec2.yaml --stack-name myec2 --parameter-overrides KeyName=$KEYNAME --region ap-northeast-2
# CloudFormation 스택 배포 완료 후 작업용 EC2 IP 출력
aws cloudformation describe-stacks --stack-name myec2 --query 'Stacks[*].Outputs[0].OutputValue' --output text
# 작업용 EC2 SSH 접속 : 아래 키파일 경로는 자신의 환경에 맞게 변경하자!
ssh -i ~/.ssh/kp-gasida.pem ec2-user@$(aws cloudformation describe-stacks --stack-name myec2 --query 'Stacks[*].Outputs[0].OutputValue' --output text)
3. [AWS 콘솔] AWS S3 버킷 생성
- (옵션) AWS CLI로 실행 : IAM 자격증명 설정되어 있는 상태 / 자격증명 설정이 없을 경우 AWS CloudShell에서 사용 가능
# S3 버킷 생성
# aws s3 mb s3://버킷(유일한 이름) --region ap-northeast-2
NICKNAME=phj
aws s3 mb s3://ahss-$NICKNAME --region ap-northeast-2
# S3 버킷 조회
aws s3 ls
aws s3api get-public-access-block --bucket ahss-$NICKNAME
4. S3 권한 설정 실습 & IAM Access Analyzer
- [AWS 콘솔] 퍼블릭 액세스 차단 편집 : (Uncheck) 모든 퍼블릭 액세스 차단 -> '변경 사항 저장' 클릭
- [AWS 콘솔] 버킷에 텍스트 파일 3개 객체 파일 업로드 (AWS CLI로 실행)
# 파일 생성
echo "memo1" > memo1.txt
echo "memo2" > memo2.txt
echo "memo3" > memo3.txt
# S3로 업로드
aws s3 cp memo1.txt s3://ahss-$NICKNAME
aws s3 cp memo2.txt s3://ahss-$NICKNAME
aws s3 cp memo3.txt s3://ahss-$NICKNAME
# 파일 확인
aws s3 ls s3://ahss-$NICKNAME --recursive --human-readable --summarize
aws s3api list-objects --bucket ahss-$NICKNAME | jq
- [EC2] 자신의 버킷 탐색
# 출력 결과의 원인을 유추해보자!
NICKNAME=phj
aws s3 ls s3://ahss-$NICKNAME --human-readable
aws s3 ls s3://ahss-$NICKNAME --human-readable --no-sign-request
- [AWS 콘솔] 권한 -> 객체 소유권 편집 : 'ACL 활성화','버킷 소유자 선호'
- [AWS 콘솔] 권한 -> ACL(액세스 제어 목록) 편집 : 모든 사람(퍼블릭 액세스) - 객체(Check 나열) -> '변경 사항 저장'
- [EC2] 자신의 버킷 탐색
# 탐색 실행
aws s3 ls s3://ahss-$NICKNAME --human-readable --no-sign-request
# 파일 복사 실행 : 출력 결과의 원인을 유추해보자!
aws s3 cp s3://ahss-$NICKNAME/memo1.txt . --no-sign-request
- [AWS 콘솔] 객체 별 권한 설정
- memo1.txt : 모든사람(퍼블릭 액세스) - 객체 (Check 읽기) -> '변경 사항 저장'
- memo2.txt : 인증된 사용자 그룹(AWS 계정이 있는 모든 사용자) - 객체 (Check 읽기) -> '변경 사항 저장' - 버킷 새로고침 후 확인
- [EC2] 자신의 버킷 탐색
# 파일 복사 실행 : 출력 결과의 원인을 유추해보자!
aws s3 cp s3://ahss-$NICKNAME/memo1.txt . --no-sign-request
# 파일 복사 실행 : 출력 결과의 원인을 유추해보자!
aws s3 cp s3://ahss-$NICKNAME/memo2.txt . --no-sign-request
# 파일 복사 실행 : 출력 결과의 원인을 유추해보자!
aws s3 cp s3://ahss-$NICKNAME/memo3.txt . --no-sign-request
- [AWS 콘솔] 리소스 정책 : 버킷 정책 설정 - 편집 클릭 후 아래 내용 입력 후 ‘변경 사항 저장’
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::ahss-phj/*"
}
]
}
- (옵션) IAM Access Analyzer 액세스 분석기
# 액세스 분석기 생성
#aws accessanalyzer create-analyzer --analyzer-name firstanalyzer --type ACCOUNT --output text --query arn
ANA_ARN=$(aws accessanalyzer create-analyzer --analyzer-name firstanalyzer --type ACCOUNT --output text --query arn)
echo $ANA_ARN
# S3 버킷 스캔 수행
aws accessanalyzer start-resource-scan --analyzer-arn $ANA_ARN --resource-arn arn:aws:s3:::ahss-$NICKNAME
# S3 버킷 스캔 결과 확인
aws accessanalyzer get-analyzed-resource --analyzer-arn $ANA_ARN --resource-arn arn:aws:s3:::ahss-$NICKNAME | jq
{
"resource": {
"resourceArn": "arn:aws:s3:::ahss-phj",
"resourceType": "AWS::S3::Bucket",
"createdAt": "2023-08-29T06:37:48.147000+00:00",
"analyzedAt": "2023-08-29T06:38:07.985000+00:00",
"updatedAt": "2023-08-29T06:37:48.147000+00:00",
"isPublic": true,
"actions": [
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions"
],
"sharedVia": [
"BUCKET_ACL",
"POLICY"
],
"status": "ACTIVE",
"resourceOwnerAccount": "414152998425"
}
}
- 버킷에 대한 퍼블릭 액세스 차단 설정
aws s3api put-public-access-block --bucket ahss-$NICKNAME --public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
[ S3 보안 강화 ]
1. Pre-signed URL & 버킷 생성
- S3 버킷 생성 후 파일 다운로드 S3 업로드 - IAM 자격증명 설정 되어 있는 상태
# S3 버킷 생성
NICKNAME=phj
aws s3 mb s3://ahss-$NICKNAME-presign --region ap-northeast-2
# 확인
aws s3 ls
aws s3api get-public-access-block --bucket ahss-$NICKNAME-presign | jq
# 그림파일 다운로드
curl https://www.nasa.gov/sites/default/files/thumbnails/image/main_image_star-forming_region_carina_nircam_final-5mb.jpg -o jameswebb.jpg
# S3로 업로드
aws s3 cp jameswebb.jpg s3://ahss-$NICKNAME-presign
# 파일 확인
aws s3 ls s3://ahss-$NICKNAME-presign --human-readable
aws s3api list-objects --bucket ahss-$NICKNAME-presign | jq
- 객체URL 접근 시도 - 자격증명 없는 상태
NICKNAME=phj
aws s3 ls s3://ahss-$NICKNAME-presign --human-readable --no-sign-request
# 객체URL로 웹 접근 시도
lynx --dump https://ahss-$NICKNAME-presign.s3.ap-northeast-2.amazonaws.com/jameswebb.jpg
- 사전 서명된 URL 생성 - IAM 자격증명 설정 되어 있는 상태
# 사전 서명된 URL 생성 : 600초(10분)
aws s3 presign s3://ahss-$NICKNAME-presign/jameswebb.jpg --expires-in 600
https://cass-s3bucket4-gasida.s3.ap-northeast-2.amazonaws.com/jameswebb.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA5ILF2FJIZTA7DFWL%2F20220820%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Date=20220820T014507Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=9237238b5c0a54210c116b4003f3aa89e984069a8f8fa116fea3f111d3c4a252
- 서명된 URL 접속 확인 - 자격증명 없는 상태
# 변수 지정
URL='https://ahss-phj-presign.s3.ap-northeast-2.amazonaws.com/memo1.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA5ILF2FJIZHUVSWIW%2F20230826%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Date=20230826T163750Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=cdc3587b9accd90a98fd558e104c5f6466b335d0978d3c8cb072064cee9b432'
# 서명된 URL 접속 확인
curl -O $URL
ls -al *.jpg
2. Require HTTPS
- IAM 자격증명 설정 되어 있는 상태
# object's metadata 정보 확인 : ServerSideEncryption 확인
aws s3api head-object help
aws s3api head-object --bucket ahss-$NICKNAME-presign --key jameswebb.jpg | jq
# object's metadata 정보 확인 : endpoint-url 옵션 설정
aws s3api head-object --bucket ahss-$NICKNAME-presign --key jameswebb.jpg --endpoint-url http://s3.ap-northeast-2.amazonaws.com
aws s3api head-object --bucket ahss-$NICKNAME-presign --key jameswebb.jpg --endpoint-url https://s3.ap-northeast-2.amazonaws.com
- [AWS 콘솔] 버킷 정책 설정 - 편집 클릭 후 아래 내용 입력 후 '변경 사항 저장'
{
"Id": "S3-Security-Deny-unless-HTTPS",
"Version": "2012-10-17",
"Statement": [{
"Action": "s3:*",
"Effect": "Deny",
"Principal": "*",
"Resource": "arn:aws:s3:::ahss-phj-presign/*",
"Condition": {
"Bool": {
"aws:SecureTransport": false
}
}
}]
}
# object's metadata 정보 확인 : endpoint-url 옵션 설정 >> http? https? 확인
aws s3api head-object --bucket ahss-$NICKNAME-presign --key jameswebb.jpg --endpoint-url http://s3.ap-northeast-2.amazonaws.com
aws s3api head-object --bucket ahss-$NICKNAME-presign --key jameswebb.jpg --endpoint-url https://s3.ap-northeast-2.amazonaws.com
3. Require SSE-KMS Encryption
- 객체 버킷 업로드
# 캑체 버킷에 업로드
# default bucket encryption to SSE-KMS(AES256) to encrypt your data at rest and enforce encryption with a bucket policy.
echo "123456789abcdefg" > textfile
aws s3api put-object --key text01 --body textfile --bucket ahss-$NICKNAME-presign
{
"ETag": "\"3ca451faac980583cffaadf8b63e6820\"",
"ServerSideEncryption": "AES256"
}
#
aws s3api head-object --bucket ahss-$NICKNAME-presign --key text01 | jq
- [AWS 콘솔] 버킷 속성 > 기본 암호화 (편집) : AWS KMS(SSE-KMS), AWS KMS 키 중 선택(s3), 버킷 키 (활성화)
- IAM 자격증명 설정 되어 있는 상태
4. IAM 정책 실습
- IAM 자격증명 설정 되어 있는 상태 : IAM User 생성 및 S3 권한 부여
# s3user 사용자 생성
aws iam create-user --user-name s3user
# iam 사용자 리스트 확인
aws iam list-users | jq
# 사용자에게 프로그래밍 방식 액세스 권한 부여
aws iam create-access-key --user-name s3user
{
"AccessKey": {
"UserName": "s3user",
"AccessKeyId": "AKIA5ILF2FJIWN7VTY6X",
"Status": "Active",
"SecretAccessKey": "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",
"CreateDate": "2023-08-27T04:32:47+00:00"
}
}
# s3user 사용자에 AWS관리형정책(AmazonS3FullAccess)을 추가
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --user-name s3user
- 자격증명 없는 상태 : s3user 사용자 자격증명 설정 후 확인
# aws cli 명령 시도
aws s3 ls
aws ec2 describe-vpcs
# s3user 자격증명 profile
aws configure
AWS Access Key ID [None]: AKIA5ILF2FJIQAIEV7UB
AWS Secret Access Key [None]: 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
Default region name [None]: ap-northeast-2
Default output format [None]:
# 자격 증명 정보 저장되는 파일 확인
cat ~/.aws/credentials
# aws cli 명령 시도
aws s3 ls
aws ec2 describe-vpcs
# 퍼블릭 액세스 차단 비활성 설정
aws s3api put-public-access-block --bucket ahss-$NICKNAME-presign --public-access-block-configuration \
"BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"
4. 퍼블릭 버킷 설정 후 IP 기반 통제
- 리소스 정책 : 버킷 정책 설정 - 편집 클릭 후 아래 내용 입력 후 ‘변경 사항 저장’
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::ahss-phj-presign/*"
}
]
}
- 객체 다운로드 시도
# 파일 복사 실행
aws s3 cp s3://ahss-$NICKNAME-presign/jameswebb.jpg .
# [EC2] 미리 자신의 공인 IP 확인 메모해두기
curl ipinfo.io
curl ipinfo.io/ip ;echo
- 리소스 정책 : 버킷 정책 설정 - 편집 클릭 후 아래 내용 입력 후 ‘변경 사항 저장’ ← IP주소는 EC2의 공인 IP 입력
# [자신의 PC] 파일 생성
echo "memo1" > memo1.txt
# [자신의 PC] S3로 업로드
aws s3 cp memo1.txt s3://ahss-$NICKNAME-presign
# [자신의 PC] 버킷 조회
aws s3 ls s3://ahss-$NICKNAME-presign
aws s3api list-objects --bucket ahss-$NICKNAME-presign | jq
# [EC2] 파일 생성
echo "memo2" > memo2.txt
# [EC2] S3로 업로드
aws s3 cp memo2.txt s3://ahss-$NICKNAME-presign
# [EC2] 버킷 조회
aws s3 ls s3://ahss-$NICKNAME-presign
aws s3api list-objects --bucket ahss-$NICKNAME-presign | jq
5. Auditing Amazon S3's Default Encryption Configurations at Scale & AWS SDK(boto3)
# boto3 설치
sudo python3 -m pip install boto3
# 버킷 리스트 조회
cat <<EOT > bucket-all.py
import boto3
s3 = boto3.resource('s3')
for bucket in s3.buckets.all():
print(bucket.name)
EOT
python3 bucket-all.py
#
git clone https://github.com/aws-samples/amazon-s3-default-encryption-audit
cd amazon-s3-default-encryption-audit/
tree
#
python3 amazon-s3-default-encryption-audit.py
...
Output Location: /home/ec2-user/
You can now access the report in the following location:
/home/ec2-user/bucketEncryptionReport_20230827-054611.csv
#
cat /home/ec2-user/bucketEncryptionReport_20230827-054611.csv
6. Use AWS Config Rules to Detect a Public Bucket
- config 서비스 → 시작하기 → 단계1~3 설정 : 결과 저장용 신규 버킷(유일 이름)을 생성!
[ 참고 영상 ]
- AWS IAM과 친해지기 (레벨 200) – 조이정:: AWS Builders Online Series
- https://youtu.be/zIZ6_tYujts