# AWS - Enumération de l'API Gateway

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

## API Gateway

### Informations de base

AWS API Gateway est un service complet proposé par Amazon Web Services (AWS) conçu pour les développeurs afin de **créer, publier et superviser des API à grande échelle**. Il fonctionne comme un point d'entrée pour une application, permettant aux développeurs d'établir un cadre de règles et de procédures. Ce cadre régit l'accès des utilisateurs externes à certaines données ou fonctionnalités au sein de l'application.

API Gateway vous permet de définir **comment les requêtes à vos API doivent être traitées**, et il peut créer des points de terminaison API personnalisés avec des méthodes spécifiques (par exemple, GET, POST, PUT, DELETE) et des ressources. Il peut également générer des SDK clients (kits de développement logiciel) pour faciliter l'appel de vos API depuis leurs applications.

### Types d'API Gateways

- **HTTP API** : Créez des API REST à faible latence et rentables avec des fonctionnalités intégrées telles que OIDC et OAuth2, et un support natif CORS. Fonctionne avec les éléments suivants : Lambda, backends HTTP.
- **WebSocket API** : Créez une API WebSocket utilisant des connexions persistantes pour des cas d'utilisation en temps réel tels que des applications de chat ou des tableaux de bord. Fonctionne avec les éléments suivants : Lambda, HTTP, services AWS.
- **REST API** : Développez une API REST où vous avez un contrôle total sur la requête et la réponse ainsi que sur les capacités de gestion de l'API. Fonctionne avec les éléments suivants : Lambda, HTTP, services AWS.
- **REST API Privée** : Créez une API REST qui n'est accessible que depuis l'intérieur d'un VPC.

### Composants principaux de l'API Gateway

1. **Ressources** : Dans API Gateway, les ressources sont les composants qui **constituent la structure de votre API**. Elles représentent **les différents chemins ou points de terminaison** de votre API et correspondent aux différentes actions que votre API prend en charge. Une ressource est chaque méthode (par exemple, GET, POST, PUT, DELETE) **à l'intérieur de chaque chemin** (/, ou /users, ou /user/{id}).
2. **Étapes** : Les étapes dans API Gateway représentent **différentes versions ou environnements** de votre API, tels que développement, staging ou production. Vous pouvez utiliser des étapes pour gérer et déployer **plusieurs versions de votre API simultanément**, vous permettant de tester de nouvelles fonctionnalités ou des corrections de bogues sans affecter l'environnement de production. Les étapes **supportent également les variables d'étape**, qui sont des paires clé-valeur pouvant être utilisées pour configurer le comportement de votre API en fonction de l'étape actuelle. Par exemple, vous pourriez utiliser des variables d'étape pour diriger les requêtes API vers différentes fonctions Lambda ou d'autres services backend en fonction de l'étape.
- L'étape est indiquée au début de l'URL du point de terminaison de l'API Gateway.
3. **Autoriseurs** : Les autoriseurs dans API Gateway sont responsables de **contrôler l'accès à votre API** en vérifiant l'identité de l'appelant avant de permettre à la requête de se poursuivre. Vous pouvez utiliser **des fonctions AWS Lambda** comme autoriseurs personnalisés, ce qui vous permet de mettre en œuvre votre propre logique d'authentification et d'autorisation. Lorsqu'une requête arrive, API Gateway passe le jeton d'autorisation de la requête à l'autoriseur Lambda, qui traite le jeton et renvoie une politique IAM qui détermine quelles actions l'appelant est autorisé à effectuer. API Gateway prend également en charge **des autoriseurs intégrés**, tels que **AWS Identity and Access Management (IAM)** et **Amazon Cognito**.
4. **Politique de ressource** : Une politique de ressource dans API Gateway est un document JSON qui **définit les autorisations pour accéder à votre API**. Elle est similaire à une politique IAM mais spécifiquement adaptée à API Gateway. Vous pouvez utiliser une politique de ressource pour contrôler qui peut accéder à votre API, quelles méthodes elles peuvent appeler, et depuis quelles adresses IP ou VPC elles peuvent se connecter. **Les politiques de ressource peuvent être utilisées en combinaison avec des autoriseurs** pour fournir un contrôle d'accès granulaire pour votre API.
- Afin de rendre l'effet, l'API doit être **déployée à nouveau après** que la politique de ressource a été modifiée.

### Journalisation

Par défaut, **CloudWatch Logs** sont **désactivés**, **l'enregistrement d'accès** est **désactivé**, et **le traçage X-Ray** est également **désactivé**.

### Énumération

> [!TIP]
> Notez que dans les deux APIs AWS pour énumérer les ressources (**`apigateway`** et **`apigatewayv2`**), la seule autorisation dont vous avez besoin et la seule autorisation de lecture accordable est **`apigateway:GET`**, avec cela vous pouvez **énumérer tout.**

{{#tabs }}
{{#tab name="apigateway" }}
```bash
# Generic info
aws apigateway get-account
aws apigateway get-domain-names
aws apigateway get-usage-plans
aws apigateway get-vpc-links
aws apigateway get-client-certificates

# Enumerate APIs
aws apigateway get-rest-apis # This will also show the resource policy (if any)
## Get stages
aws apigateway get-stages --rest-api-id <id>
## Get resources
aws apigateway get-resources --rest-api-id <id>
## Get API resource action per HTTP verb (check authorizers and api key required)
aws apigateway get-method --http-method GET --rest-api-id <api-id> --resource-id <resource-id>

## Call API
https://<api-id>.execute-api.<region>.amazonaws.com/<stage>/<resource>
## API authorizers
aws apigateway get-authorizers --rest-api-id <id>
## Models
aws apigateway get-models --rest-api-id <id>
## More info
aws apigateway get-gateway-responses --rest-api-id <id>
aws apigateway get-request-validators --rest-api-id <id>
aws apigateway get-deployments --rest-api-id <id>

# Get api keys generated
aws apigateway get-api-keys --include-value
aws apigateway get-api-key --api-key <id> --include-value # Get just 1
## Example use API key
curl -X GET -H "x-api-key: AJE&Ygenu4[..]" https://e83uuftdi8.execute-api.us-east-1.amazonaws.com/dev/test
## Usage plans
aws apigateway get-usage-plans #Get limit use info
aws apigateway get-usage-plan-keys --usage-plan-id <plan_id> #Get clear text values of api keys
aws apigateway get-usage-plan-key --usage-plan-id <plan_id> --key-id <key_id>
###Already consumed
aws apigateway get-usage --usage-plan-id <plan_id> --start-date 2023-07-01 --end-date 2023-07-12
```
{{#endtab }}

{{#tab name="apigatewayv2" }}
```bash
# Generic info
aws apigatewayv2 get-domain-names
aws apigatewayv2 get-domain-name --domain-name <name>
aws apigatewayv2 get-vpc-links

# Enumerate APIs
aws apigatewayv2 get-apis # This will also show the resource policy (if any)
aws apigatewayv2 get-api --api-id <id>

## Get all the info from an api at once
aws apigatewayv2 export-api --api-id <id> --output-type YAML --specification OAS30 /tmp/api.yaml

## Get stages
aws apigatewayv2 get-stages --api-id <id>

## Get routes
aws apigatewayv2 get-routes --api-id <id>
aws apigatewayv2 get-route --api-id <id> --route-id <route-id>

## Get deployments
aws apigatewayv2 get-deployments --api-id <id>
aws apigatewayv2 get-deployment --api-id <id> --deployment-id <dep-id>

## Get integrations
aws apigatewayv2 get-integrations --api-id <id>

## Get authorizers
aws apigatewayv2 get-authorizers --api-id <id>
aws apigatewayv2 get-authorizer --api-id <id> --authorizer-id <uth-id>

## Get domain mappings
aws apigatewayv2 get-api-mappings --api-id <id> --domain-name <dom-name>
aws apigatewayv2 get-api-mapping --api-id <id> --api-mapping-id <map-id> --domain-name <dom-name>

## Get models
aws apigatewayv2 get-models --api-id <id>

## Call API
https://<api-id>.execute-api.<region>.amazonaws.com/<stage>/<resource>
```
{{#endtab }}
{{#endtabs }}

## Différentes autorisations pour accéder aux points de terminaison de l'API Gateway

### Politique de ressource

Il est possible d'utiliser des politiques de ressource pour définir qui peut appeler les points de terminaison de l'API.\
Dans l'exemple suivant, vous pouvez voir que **l'IP indiquée ne peut pas appeler** le point de terminaison `/resource_policy` via GET.

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

### Autorisateur IAM

Il est possible de définir qu'une méthode à l'intérieur d'un chemin (une ressource) nécessite une authentification IAM pour être appelée.

<figure><img src="https://lh3.googleusercontent.com/GGx-kfqNXu6zMqGidnO8_eR88fYPpJG-wNuBBnedAJntiRUEPTEScl7OvWthGYRiI_msYCdC6oBFvJc827Tb4-4UogxpOyrEXyst-8IDzP9DC2NOtXSY7w58L0baCAcBQjSyvBhJREvWWCtiboNYPSKuEw=s2048" alt=""><figcaption></figcaption></figure>

Lorsque cela est défini, vous recevrez l'erreur `{"message":"Missing Authentication Token"}` lorsque vous essayez d'atteindre le point de terminaison sans aucune autorisation.

Une façon simple de générer le jeton attendu par l'application est d'utiliser **curl**.
```bash
$ curl -X <method> https://<api-id>.execute-api.<region>.amazonaws.com/<stage>/<resource> --user <AWS_ACCESS_KEY>:<AWS_SECRET_KEY> --aws-sigv4 "aws:amz:<region>:execute-api"
```
Une autre façon est d'utiliser le type **`Authorization`** **`AWS Signature`** à l'intérieur de **Postman**.

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

Définissez l'accessKey et le SecretKey du compte que vous souhaitez utiliser et vous pouvez maintenant vous authentifier contre le point de terminaison de l'API.

Les deux méthodes généreront un **Authorization** **header** tel que :
```
AWS4-HMAC-SHA256 Credential=AKIAYY7XU6ECUDOTWB7W/20220726/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=9f35579fa85c0d089c5a939e3d711362e92641e8c14cc571df8c71b4bc62a5c2
```
Notez que dans d'autres cas, l'**Authorizer** pourrait avoir été **mal codé** et envoyer simplement **n'importe quoi** dans l'**Authorization header** permettra **de voir le contenu caché**.

### Signature de la requête en utilisant Python
```python

pip install requests
pip install requests-aws4auth
pip install boto3

import boto3
import requests
from requests_aws4auth import AWS4Auth

region = 'us-east-1'  # Region
service = 'execute-api'
access_key = 'YOUR_ACCESS_KEY'
secret_key = 'YOUR_SECRET_KEY'

url = 'https://<apiid>.execute-api.us-east-1.amazonaws.com/<stage>/<resource>'

session = boto3.Session(aws_access_key_id=access_key, aws_secret_access_key=secret_key)
credentials = session.get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)

response = requests.get(url, auth=awsauth)

print(response.text)

```
### Authorisateur Lambda Personnalisé

Il est possible d'utiliser une lambda qui, en fonction d'un token donné, **retournera une politique IAM** indiquant si l'utilisateur est **autorisé à appeler le point de terminaison de l'API**.\
Vous pouvez définir chaque méthode de ressource qui utilisera l'auteur.

<details>

<summary>Exemple de Code d'Authorisateur Lambda</summary>
```python
import json

def lambda_handler(event, context):
token = event['authorizationToken']
method_arn = event['methodArn']

if not token:
return {
'statusCode': 401,
'body': 'Unauthorized'
}

try:
# Replace this with your own token validation logic
if token == "your-secret-token":
return generate_policy('user', 'Allow', method_arn)
else:
return generate_policy('user', 'Deny', method_arn)
except Exception as e:
print(e)
return {
'statusCode': 500,
'body': 'Internal Server Error'
}

def generate_policy(principal_id, effect, resource):
policy = {
'principalId': principal_id,
'policyDocument': {
'Version': '2012-10-17',
'Statement': [
{
'Action': 'execute-api:Invoke',
'Effect': effect,
'Resource': resource
}
]
}
}
return policy
```
</details>

Appelez-le avec quelque chose comme :

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash"><strong>curl "https://jhhqafgh6f.execute-api.eu-west-1.amazonaws.com/prod/custom_auth" -H 'Authorization: your-secret-token'
</strong></code></pre>

> [!WARNING]
> Selon le code Lambda, cette autorisation pourrait être vulnérable

Notez que si une **politique de refus est générée et renvoyée**, l'erreur renvoyée par API Gateway est : `{"Message":"User is not authorized to access this resource with an explicit deny"}`

De cette manière, vous pourriez **identifier cette autorisation** en place.

### Clé API requise

Il est possible de définir des points de terminaison API qui **nécessitent une clé API valide** pour y accéder.

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

Il est possible de générer des clés API dans le portail API Gateway et même de définir combien elles peuvent être utilisées (en termes de requêtes par seconde et en termes de requêtes par mois).

Pour faire fonctionner une clé API, vous devez l'ajouter à un **Plan d'utilisation**, ce plan d'utilisation doit être ajouté à l'**Étape API** et l'étape API associée doit avoir une **limitation de méthode** configurée pour le **point de terminaison** nécessitant la clé API :

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

## Accès non authentifié

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

## Privesc

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

## Post Exploitation

{{#ref}}
../aws-post-exploitation/aws-api-gateway-post-exploitation.md
{{#endref}}

## Persistance

{{#ref}}
../aws-persistence/aws-api-gateway-persistence.md
{{#endref}}

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