# AWS - Lambda Persistence

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

## Lambda

Per maggiori informazioni consulta:

{{#ref}}
../../aws-services/aws-lambda-enum.md
{{#endref}}

### Lambda Layer Persistence

È possibile **introduce/backdoor a layer to execute arbitrary code** quando la lambda viene eseguita in modo stealthy:

{{#ref}}
aws-lambda-layers-persistence.md
{{#endref}}

### Lambda Extension Persistence

Abusing Lambda Layers è anche possibile abusare delle extensions e persist in the lambda ma anche rubare e modificare le requests.

{{#ref}}
aws-abusing-lambda-extensions.md
{{#endref}}

### Via resource policies

È possibile concedere accesso a diverse lambda actions (such as invoke or update code) ad account esterni:

<figure><img src="../../../../images/image (255).png" alt=""><figcaption></figcaption></figure>

### Versions, Aliases & Weights

Una Lambda può avere **different versions** (con codice diverso in ogni versione).\
Poi, puoi creare **different aliases with different versions** della lambda e assegnare diversi weights a ciascuna.\
In questo modo un attacker potrebbe creare una **backdoored version 1** e una **version 2 with only the legit code** e **only execute the version 1 in 1%** delle richieste per rimanere stealth.

<figure><img src="../../../../images/image (120).png" alt=""><figcaption></figcaption></figure>

### Version Backdoor + API Gateway

1. Copia il codice originale della Lambda
2. **Create a new version backdooring** il codice originale (o solo con codice malevolo). Publish e **deploy that version** su $LATEST
1. Call the API gateway related to the lambda to execute the code
3. **Create a new version with the original code**, Publish e deploy that **version** su $LATEST.
1. Questo nasconderà il codice backdoored in una versione precedente
4. Vai all'API Gateway e **create a new POST method** (o scegli un altro metodo) che eseguirà la backdoored version della lambda: `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
1. Nota il finale :1 dell'arn **indicating the version of the function** (version 1 will be the backdoored one in this scenario).
5. Seleziona il metodo POST creato e in Actions seleziona **`Deploy API`**
6. Ora, quando **call the function via POST your Backdoor** verrà invocata

### Cron/Event actuator

Il fatto che puoi far **lambda functions run when something happen or when some time pass** rende Lambda un modo comune e utile per ottenere persistence e evitare il rilevamento.\
Qui hai alcune idee per rendere la tua **presence in AWS more stealth by creating lambdas**.

- Ogni volta che viene creato un nuovo user, lambda genera una nuova user key e la invia all'attacker.
- Ogni volta che viene creato un nuovo role, lambda concede assume role permissions agli users compromessi.
- Ogni volta che vengono generati nuovi cloudtrail logs, cancellali/modificali

### RCE abusing AWS_LAMBDA_EXEC_WRAPPER + Lambda Layers

Abusa della variabile d'ambiente `AWS_LAMBDA_EXEC_WRAPPER` per eseguire uno script wrapper controllato dall'attacker prima che il runtime/handler inizi. Distribuisci il wrapper tramite una Lambda Layer in `/opt/bin/htwrap`, imposta `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap`, e poi invoca la function. Il wrapper gira all'interno del processo runtime della function, eredita la function execution role e infine `exec`s il vero runtime in modo che l'handler originale venga comunque eseguito normalmente.

{{#ref}}
aws-lambda-exec-wrapper-persistence.md
{{#endref}}

### AWS - Lambda Function URL Public Exposure

Abuse Lambda asynchronous destinations insieme alla Recursion configuration per far sì che una function si richiami continuamente da sola senza uno scheduler esterno (no EventBridge, cron, etc.). Di default, Lambda termina i loop ricorsivi, ma impostando la recursion config su Allow li riabiliti. Le destinations consegnano lato servizio per gli invoke asincroni, quindi un singolo seed invoke crea un canale stealthy, code-free per heartbeat/backdoor. Opzionalmente limita con reserved concurrency per mantenere basso il rumore.

{{#ref}}
aws-lambda-async-self-loop-persistence.md
{{#endref}}

### AWS - Lambda Alias-Scoped Resource Policy Backdoor

Crea una Lambda version nascosta con la logica dell'attacker e scope una resource-based policy a quella specifica version (o alias) usando il parametro `--qualifier` in `lambda add-permission`. Concedi solo `lambda:InvokeFunction` su `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` a un attacker principal. Le invocazioni normali tramite il nome della function o l'alias primario restano inalterate, mentre l'attacker può invocare direttamente l'ARN della versione backdoored.

Questo è più stealthier che esporre una Function URL e non cambia l'alias del traffico primario.

{{#ref}}
aws-lambda-alias-version-policy-backdoor.md
{{#endref}}

### Freezing AWS Lambda Runtimes

Un attacker che possiede i permessi lambda:InvokeFunction, logs:FilterLogEvents, lambda:PutRuntimeManagementConfig, e lambda:GetRuntimeManagementConfig può modificare la runtime management configuration di una function. Questo attacco è particolarmente efficace quando l'obiettivo è mantenere una Lambda function su una runtime version vulnerabile o preservare la compatibilità con malicious layers che potrebbero essere incompatibili con runtime più recenti.

L'attacker modifica la runtime management configuration per pin the runtime version:
```bash
# Invoke the function to generate runtime logs
aws lambda invoke \
--function-name $TARGET_FN \
--payload '{}' \
--region us-east-1 /tmp/ping.json

sleep 5

# Freeze automatic runtime updates on function update
aws lambda put-runtime-management-config \
--function-name $TARGET_FN \
--update-runtime-on FunctionUpdate \
--region us-east-1
```
Verificare la configurazione applicata:
```bash
aws lambda get-runtime-management-config \
--function-name $TARGET_FN \
--region us-east-1
```
Opzionale: fissare a una versione specifica del runtime
```bash
# Extract Runtime Version ARN from INIT_START logs
RUNTIME_ARN=$(aws logs filter-log-events \
--log-group-name /aws/lambda/$TARGET_FN \
--filter-pattern "INIT_START" \
--query 'events[0].message' \
--output text | grep -o 'Runtime Version ARN: [^,]*' | cut -d' ' -f4)
```
Fissare una versione specifica del runtime:
```bash
aws lambda put-runtime-management-config \
--function-name $TARGET_FN \
--update-runtime-on Manual \
--runtime-version-arn $RUNTIME_ARN \
--region us-east-1
```
{{#include ../../../../banners/hacktricks-training.md}}
