# AWS - Lambda Enum

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

## Lambda

Amazon Web Services (AWS) Lambda est décrit comme un **service de calcul** qui permet l'exécution de code sans la nécessité de provisionner ou de gérer des serveurs. Il se caractérise par sa capacité à **gérer automatiquement l'allocation des ressources** nécessaires à l'exécution du code, garantissant des fonctionnalités telles que haute disponibilité, évolutivité et sécurité. Un aspect significatif de Lambda est son modèle de tarification, où **les frais sont basés uniquement sur le temps de calcul utilisé**, éliminant ainsi le besoin d'investissements initiaux ou d'obligations à long terme.

Pour appeler une lambda, il est possible de l'appeler **aussi souvent que vous le souhaitez** (avec Cloudwatch), **d'exposer** un **point de terminaison URL** et de l'appeler, de l'appeler via **API Gateway** ou même en fonction des **événements** tels que les **changements** de données dans un **bucket S3** ou les mises à jour d'une table **DynamoDB**.

Le **code** d'une lambda est stocké dans **`/var/task`**.

### Poids des alias Lambda

Une Lambda peut avoir **plusieurs versions**.\
Et elle peut avoir **plus d'une** version exposée via des **alias**. Les **poids** de **chacune** des **versions** exposées dans un alias décideront **quel alias reçoit l'invocation** (cela peut être 90%-10% par exemple).\
Si le code de **l'un** des alias est **vulnérable**, vous pouvez envoyer **des requêtes jusqu'à ce que la version vulnérable reçoive l'exploit**.

![](<../../../images/image (223).png>)

### Politiques de ressources

Les politiques de ressources Lambda permettent de **donner accès à d'autres services/comptes pour invoquer** la lambda par exemple.\
Par exemple, voici la politique pour permettre à **quiconque d'accéder à une lambda exposée via URL** :

<figure><img src="https://lh4.googleusercontent.com/4PNFKBdzr3nMrPqeKkTslgwWDKxkXMdQ1SNdv7NPHykj3GX8wODrQyXOFbjk4fxHfZ8pDm5ijWgk2Vq2EGXiPRT3TQfZf1fHycvdEKBuDxJDYos1CJeMHXSeg86ZB-Ol7CNtten6xkVFQj6AhDUEWNQJrQ=s2048" alt=""><figcaption></figcaption></figure>

Ou celle-ci pour permettre à un API Gateway de l'invoquer :

<figure><img src="https://lh3.googleusercontent.com/Su0JlR0wBqb-99Z4N_2-_kMlX0Xzx2n_GpZuOPW5IeXR3FYbm8OHFDM3Ora1BpXiSjHpDVUlq4yEyXwaI3nBuze6DJ-wRf2ATsCuWbq0wuBCd34E9uIpqwheE6Cc_PopviI_93O_j2ZKXc1-AJtsBoLVUw=s2048" alt=""><figcaption></figcaption></figure>

### Proxies de base de données Lambda

Lorsqu'il y a **des centaines** de **requêtes lambda simultanées**, si chacune d'elles doit **se connecter et fermer une connexion à une base de données**, cela ne va tout simplement pas fonctionner (les lambdas sont sans état, ne peuvent pas maintenir des connexions ouvertes).\
Alors, si vos **fonctions Lambda interagissent avec RDS Proxy au lieu** de votre instance de base de données. Cela gère le pool de connexions nécessaire pour faire évoluer de nombreuses connexions simultanées créées par des fonctions Lambda concurrentes. Cela permet à vos applications Lambda de **réutiliser les connexions existantes**, plutôt que de créer de nouvelles connexions pour chaque invocation de fonction.

### Systèmes de fichiers EFS Lambda

Pour préserver et même partager des données, **les Lambdas peuvent accéder à EFS et les monter**, afin que Lambda puisse lire et écrire à partir de celui-ci.

### Couches Lambda

Une couche Lambda est une archive .zip qui **peut contenir du code supplémentaire** ou d'autres contenus. Une couche peut contenir des bibliothèques, un [runtime personnalisé](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html), des données ou des fichiers de configuration.

Il est possible d'inclure jusqu'à **cinq couches par fonction**. Lorsque vous incluez une couche dans une fonction, les **contenus sont extraits dans le répertoire `/opt`** dans l'environnement d'exécution.

Par **défaut**, les **couches** que vous créez sont **privées** à votre compte AWS. Vous pouvez choisir de **partager** une couche avec d'autres comptes ou de **rendre** la couche **publique**. Si vos fonctions consomment une couche qu'un autre compte a publiée, vos fonctions peuvent **continuer à utiliser la version de la couche après qu'elle a été supprimée, ou après que votre permission d'accéder à la couche a été révoquée**. Cependant, vous ne pouvez pas créer une nouvelle fonction ou mettre à jour des fonctions en utilisant une version de couche supprimée.

Les fonctions déployées en tant qu'image de conteneur n'utilisent pas de couches. Au lieu de cela, vous regroupez votre runtime préféré, vos bibliothèques et d'autres dépendances dans l'image de conteneur lorsque vous construisez l'image.

### Extensions Lambda

Les extensions Lambda améliorent les fonctions en s'intégrant à divers **outils de surveillance, d'observabilité, de sécurité et de gouvernance**. Ces extensions, ajoutées via des [.zip archives utilisant des couches Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) ou incluses dans [les déploiements d'images de conteneur](https://aws.amazon.com/blogs/compute/working-with-lambda-layers-and-extensions-in-container-images/), fonctionnent en deux modes : **interne** et **externe**.

- Les **extensions internes** fusionnent avec le processus d'exécution, manipulant son démarrage à l'aide de **variables d'environnement spécifiques au langage** et de **scripts d'enveloppe**. Cette personnalisation s'applique à une gamme de runtimes, y compris **Java Correto 8 et 11, Node.js 10 et 12, et .NET Core 3.1**.
- Les **extensions externes** s'exécutent en tant que processus séparés, maintenant l'alignement opérationnel avec le cycle de vie de la fonction Lambda. Elles sont compatibles avec divers runtimes comme **Node.js 10 et 12, Python 3.7 et 3.8, Ruby 2.5 et 2.7, Java Corretto 8 et 11, .NET Core 3.1**, et **runtimes personnalisés**.

### Énumération
```bash
aws lambda get-account-settings

# List functions and get extra config info
aws lambda list-functions
aws lambda get-function --function-name <function_name>
aws lambda get-function-configuration --function-name <function_name>
aws lambda list-function-event-invoke-configs --function-name <function_name>
## Check for creds in env vars
aws lambda list-functions | jq '.Functions[].Environment'
## Download & check the source code
aws lambda get-function --function-name "<func_name>" --query 'Code.Location'
wget -O lambda-function.zip <url-from-previous-query>

# Get Lambda URL (if any)
aws lambda list-function-url-configs --function-name <function_name>
aws lambda get-function-url-config --function-name <function_name>

# Get who has permissions to invoke the Lambda
aws lambda get-policy --function-name <function_name>

# Versions and Aliases
aws lambda list-versions-by-function --function-name <func_name>
aws lambda list-aliases --function-name <func_name>

# List layers
aws lambda list-layers
aws lambda list-layer-versions --layer-name <name>
aws lambda get-layer-version --layer-name <name> --version-number <ver>
aws lambda get-layer-version-by-arn --arn <name> #Get external ARNs

# List other metadata
aws lambda list-event-source-mappings
aws lambda list-code-signing-configs
aws lambda list-functions-by-code-signing-config --code-signing-config-arn <arn>
```
### Invoker une lambda

#### Manuel
```bash
# Invoke function
aws lambda invoke --function-name FUNCTION_NAME /tmp/out
## Some functions will expect parameters, they will access them with something like:
## target_policys = event['policy_names']
## user_name = event['user_name']
aws lambda invoke --function-name <name> --cli-binary-format raw-in-base64-out --payload '{"policy_names": ["AdministratorAccess], "user_name": "sdf"}' out.txt
```
#### Via URL exposée
```bash
aws lambda list-function-url-configs --function-name <function_name> #Get lambda URL
aws lambda get-function-url-config   --function-name <function_name> #Get lambda URL
```
#### Appeler la fonction Lambda via URL

Maintenant, il est temps de découvrir les fonctions lambda possibles à exécuter :
```
aws --region us-west-2 --profile level6 lambda list-functions
```
![](<../../../images/image (262).png>)

Une fonction lambda appelée "Level6" est disponible. Voyons comment l'appeler :
```bash
aws --region us-west-2 --profile level6 lambda get-policy --function-name Level6
```
![](<../../../images/image (102).png>)

Maintenant que vous connaissez le nom et l'ID, vous pouvez obtenir le Nom :
```bash
aws --profile level6 --region us-west-2 apigateway get-stages --rest-api-id "s33ppypa75"
```
![](<../../../images/image (237).png>)

Et enfin, appelez la fonction en accédant (notez que l'ID, le nom et le nom de la fonction apparaissent dans l'URL) : [https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6](https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6)

`URL:`**`https://<rest-api-id>.execute-api.<region>.amazonaws.com/<stageName>/<funcName>`**

#### Autres Déclencheurs

Il existe de nombreuses autres sources qui peuvent déclencher une lambda

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

### Privesc

Sur la page suivante, vous pouvez vérifier comment **abuser des permissions Lambda pour escalader les privilèges** :

{{#ref}}
../aws-privilege-escalation/aws-lambda-privesc.md
{{#endref}}

### Accès Non Authentifié

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

### Post Exploitation

{{#ref}}
../aws-post-exploitation/aws-lambda-post-exploitation/
{{#endref}}

### Persistance

{{#ref}}
../aws-persistence/aws-lambda-persistence/
{{#endref}}

## Références

- [https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-concepts.html#gettingstarted-concepts-layer](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-concepts.html#gettingstarted-concepts-layer)
- [https://aws.amazon.com/blogs/compute/building-extensions-for-aws-lambda-in-preview/](https://aws.amazon.com/blogs/compute/building-extensions-for-aws-lambda-in-preview/)

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