본문 바로가기

CloudGoat

iam_privesc_by_attachment(Medium) Write up



문제에서 제공받은 Access Key와 Secret Key를 통해 Profile을 생성하고, sts get-caller-identity 명령을 사용하여 User에 대한 정보를 확인한다.

kerrigan라는 이름의 User임을 확인할 수 있었으며 해당 User의 Group, Policy, Role 등을 조회하여 부여된 권한을 확인해 보기로 했다. 우선 list-groups-for-user 명령을 통해 kerrigan이라는 User가 소속된 Group를 확인했고, 

AccessDenied가 뜨며 권한이 존재하지 않아 조회할 수 없었다. 
policy에 대한 정보를 조회해보기 위해 list-user-policieslist-attached-user-policies 명령을 통해 User에게 연결된 관리형 정책과 인라인 정책을 확인해 보았다.

하지만 두 명령도 AccessDenied가 뜨며 조회할 수 없었다.
User의 Group, Policy 모두 권한이 없어 조회에 실패했기에 해당 AWS 계정에 존재하는 Role를 모두 불러와보자.

list-roles 명령으로 Role을 조회하는 것에 성공했다.

cg-ec2-mighty-role-cgidb5enpv0y4c, cg-ec2-meek-role-cgidb5enpv0y4c라는 2개의 Role이 발견되었고, 두 Role 모두 EC2에 Assuem 할 수 있었다.
즉, 각 Role을 특정 EC2 인스턴스에 연결하면 해당 인스턴스가 Role의 권한으로 AWS 리소스에 접근할 수 있다는 것이다.

get-role 명령을 통해 각 Role의 자세한 권한을 살펴보자.

하지만 AccessDenied가 뜨며 조회에 실패하였다.
IAM에 대한 권한 정보 수집이 힘들기 때문에 발견한 Role를 연결시킬 수 있는 EC2가 존재하는지 확인해 보기로 했다. 

describe-instances 명령을 통해 지정된 us-east-1 리전에 존재하는 EC2 인스턴스에 대한 정보를 조회했다.

하나의 인스턴스가 발견되었고, Tag에 작성된 "CloudGoat cgidb5enpv0y4c super-critical-security-server EC2 Instance"를 통해 해당 시나리오에서 삭제해야 하는 인스턴스임을 알게 되었다.

그러나 EC2 인스턴스에 Role을 연결하는 Instance Profile이 존재하지 않았기에 list-instance-profiles 명령을 통해 따로 조회해 보았다.

cg-ec2-meek-instance-profile-cgidb5enpv0y4c라는 이름의 Profile이 하나 존재했으며, 앞서 발견한 cg-ec2-meek-role-cgidb5enpv0y4c라는 Role이 연결되어 있었다.

2개의 Role 중에서 meek보다 mighty에 더 많은 권한이 부여되어 있을 것이라 예상하였기에 Profile에 연결된 Role을 바꿔주기로 했다.
그러기 위해 기존의 Role을 remove-role-from-instance-profile 명령으로 삭제시켜 주었다.

정상적으로 meek Role을 Profile에서 삭제하였고, 이제 add-role-to-instance-profile 명령을 통해 mighty Role을 Profile에 연결시켜 주었다.

정상적으로 동작하였고, list-instance-profiles 명령으로 다시 Profile을 조회했더니 mighty Role로 연결되어 있었다.

EC2 인스턴스에 연결할 수 있는 Profile에 높은 권한이 존재한다면, 해당 인스턴스에 SSH로 접속하여 연결된 Role의 권한을 이용할 수 있게 된다.
EC2의 서브넷과 보안 그룹을 조회하여 외부에서 SSH 접근이 가능한지 확인해 보자.
우선 describe-subnets 명령을 통해 EC2가 배치된 서브넷이 Public Subnet 이라는 것을 알게 되었다.

보안 그룹도 describe-security-groups 명령을 통해 조회해 보았고, SSH 22번 포트가 현재 내 IP 대역에서 허용되어 있었다. (허용된 IP가 현재 내 IP로 되어있는 이유는, CloudGoat를 처음 설정할 때 cloudgoat config whitelist --auto 명령을 통해 환경 구축 시 허용된 IP를 자신의 IP로 설정해 주어 안전하게 실습이 가능하도록 지원해 주기 때문이다.)

이제 EC2에 접속하기 위해 Instance Profile을 연결시키려 했는데, 생각해 보니 SSH 접속 시에는 키페어 파일이 필요하다. 하지만 이미 생성된 EC2 인스턴스에 대한 키페어 파일은 얻을 방법이 없다.
그래서 생각해 낸 방법은 새로운 인스턴스를 만들고 해당 인스턴스에 권한이 높은 Profile을 연결하여 목표 EC2 인스턴스에 접속하지 않고 삭제를 하는 방법을 진행해 보기로 했다.
새로운 인스턴스를 생성하기 전, 키페어 파일을 create-key-pair 명령을 통해 생성해 주었다.

KeyMaterial의 값을 pem 파일로 만들어서 추후에 생성될 EC2 인스턴스에 접속할 때 사용하면 된다.

이제 필요한 것들을 모두 만들었으니, 새 인스턴스 생성을 시도해 보자.
run-instances 명령에 ami image id, instance type, key pair name, subnet id, security group id, instance profile, region을 옵션으로 명시하여 성공적으로 생성할 수 있었다.

이후 describe-instances 명령을 통해 생성한 인스턴스의 Public IP를 확인해 주자.

이제 앞서 생성해 둔 로컬의 pem 파일에 chmod 400으로 적절한 권한을 부여하고, SSH 접속을 시도해 보자.

ssh -i iam_key.pem ubuntu@3.90.141.38 명령을 통해 성공적으로 인스턴스 내부에 접근했다.

이제 AWS 명령어를 이용하기 위해 아래 명령으로 aws cli를 설치해 주자.

sudo apt update
sudo apt install awscli

설치가 완료되었고, 이제 현재 Instance Profile에 어떤 권한이 부여되어 있는지 확인해 보자. list-attached-role-policies 명령을 통해 Profile에 연결된 mighty Role의 인라인 Policy Name을 알게 되었다.

cg-ec2-mighty-policy라는 정책이 연결되어 있었고, 해당 정책의 권한을 조회하기 위해 Default Version 정보를 get-policy 명령으로 확인했다.

DefaultVersionId가 v1인 것을 확인하고 get-policy-version 명령의 옵션으로 추가하여 정책의 권한을 자세히 확인할 수 있었다.

그 결과 모든 Action이 Allow로 설정된 Admin 권한으로 설정된 정책임을 확인했다.

즉, 해당 인스턴스에서 Target 인스턴스를 삭제할 수 있다는 것이다.

instance id를 옵션으로 주고 terminate-instances 명령을 실행시켜 인스턴스를 삭제 켰다.

이제 인스턴스를 describe-instances 명령으로 조회해 보면, 정상적으로 종료된 것을 확인할 수 있다.

 

'CloudGoat' 카테고리의 다른 글

codebuild_secrets (Hard) Write up  (0) 2026.01.18
vulnerable_lambda(Medium) Write up  (0) 2025.10.31
RDS_snapshot(Medium) Write up  (0) 2025.05.01
iam_privesc_by_rollback(Easy) Write Up  (0) 2025.04.27
SQS_FLAG_Shop(Easy) Write-up  (0) 2025.04.23