AWS - Lambda Layers Persistence
Lambda Layers
Un layer di Lambda è un archivio file .zip che può contenere codice aggiuntivo o altro contenuto. Un layer può contenere librerie, un runtime personalizzato, dati o file di configurazione.
È possibile includere fino a cinque layers per funzione. Quando si include un layer in una funzione, i contenuti vengono estratti nella directory /opt
nell'ambiente di esecuzione.
Per default, i layers che crei sono privati per il tuo account AWS. Puoi scegliere di condividere un layer con altri account o di rendere il layer pubblico. Se le tue funzioni consumano un layer pubblicato da un account diverso, le tue funzioni possono continuare a utilizzare la versione del layer anche dopo che è stato eliminato, o dopo che il permesso di accesso al layer è stato revocato. Tuttavia, non puoi creare una nuova funzione o aggiornare funzioni utilizzando una versione di layer eliminata.
Le funzioni distribuite come immagine del contenitore non utilizzano layers. Invece, si impacchetta il runtime preferito, le librerie e le altre dipendenze nell'immagine del contenitore durante la creazione dell'immagine.
Percorso di caricamento Python
Il percorso di caricamento che Python utilizzerà in lambda è il seguente:
Verifica come il secondo e il terzo posizioni sono occupate dalle directory in cui i lambda layers decomprimono i loro file: /opt/python/lib/python3.9/site-packages
e /opt/python
Se un attaccante riuscisse a inserire un backdoor in un lambda layer utilizzato o aggiungerne uno che eseguirà codice arbitrario quando viene caricata una libreria comune, sarà in grado di eseguire codice dannoso ad ogni invocazione del lambda.
Pertanto, i requisiti sono:
Controllare le librerie caricate dal codice delle vittime
Creare una libreria proxy con i lambda layers che eseguirà codice personalizzato e caricherà la libreria originale.
Librerie precaricate
Nel momento in cui ho abusato di questa tecnica, ho riscontrato una difficoltà: Alcune librerie sono già caricate nell'ambiente di runtime di Python quando il tuo codice viene eseguito. Mi aspettavo di trovare cose come os
o sys
, ma anche la libreria json
era caricata.
Per abusare di questa tecnica di persistenza, il codice deve caricare una nuova libreria che non è già stata caricata quando il codice viene eseguito.
Con un codice Python come questo è possibile ottenere l'elenco delle librerie precaricate all'interno dell'ambiente di runtime di Python nel lambda:
E questa è la lista (controlla che le librerie come os
o json
siano già presenti)
E questa è la lista delle librerie che lambda include installate di default: [https://gist.github.com/gene1wood/4a052f39490fae00e0c3]
Backdooring del Lambda Layer
In questo esempio supponiamo che il codice mirato stia importando csv
. Andremo a inserire un backdoor nell'import della libreria csv
.
Per farlo, creeremo la directory csv con il file __init__.py
al suo interno in un percorso che viene caricato da lambda: /opt/python/lib/python3.9/site-packages
Quindi, quando il lambda viene eseguito e cerca di caricare csv, il nostro file __init__.py
verrà caricato ed eseguito.
Questo file deve:
Eseguire il nostro payload
Caricare la libreria csv originale
Possiamo fare entrambe le cose con:
Quindi, crea un file zip con questo codice nel percorso python/lib/python3.9/site-packages/__init__.py
e aggiungilo come un layer lambda.
Puoi trovare questo codice su https://github.com/carlospolop/LambdaLayerBackdoor
Il payload integrato invierà le credenziali IAM a un server LA PRIMA VOLTA che viene invocato o DOPO un reset del container lambda (cambio di codice o lambda fredda), ma altre tecniche come le seguenti potrebbero anche essere integrate:
AWS - Steal Lambda RequestsLivelli Esterni
Si noti che è possibile utilizzare livelli lambda da account esterni. Inoltre, una lambda può utilizzare un layer da un account esterno anche se non ha le autorizzazioni. Si noti inoltre che il numero massimo di livelli che una lambda può avere è 5.
Pertanto, per migliorare la versatilità di questa tecnica un attaccante potrebbe:
Inserire un backdoor in un layer esistente dell'utente (nulla è esterno)
Creare un layer nel suo account, dare all'account della vittima l'accesso per utilizzare il layer, configurare il layer nella Lambda della vittima e rimuovere l'autorizzazione.
La Lambda sarà comunque in grado di utilizzare il layer e la vittima non avrà un modo semplice per scaricare il codice dei livelli (a parte ottenere una reverse shell all'interno della lambda)
La vittima non vedrà livelli esterni utilizzati con
aws lambda list-layers
Last updated