# AWS - API Gateway Enum

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

## API Gateway

### Informazioni di base

AWS API Gateway è un servizio completo offerto da Amazon Web Services (AWS) progettato per gli sviluppatori per **creare, pubblicare e gestire API su larga scala**. Funziona come un punto di accesso a un'applicazione, consentendo agli sviluppatori di stabilire un insieme di regole e procedure. Questo insieme governa l'accesso che gli utenti esterni hanno a determinati dati o funzionalità all'interno dell'applicazione.

API Gateway consente di definire **come le richieste alle tue API devono essere gestite**, e può creare endpoint API personalizzati con metodi specifici (ad es., GET, POST, PUT, DELETE) e risorse. Può anche generare SDK client (Software Development Kits) per facilitare agli sviluppatori la chiamata delle tue API dalle loro applicazioni.

### Tipi di API Gateway

- **HTTP API**: Crea API REST a bassa latenza e costo efficace con funzionalità integrate come OIDC e OAuth2, e supporto nativo per CORS. Funziona con: Lambda, backend HTTP.
- **WebSocket API**: Crea un'API WebSocket utilizzando connessioni persistenti per casi d'uso in tempo reale come applicazioni di chat o dashboard. Funziona con: Lambda, HTTP, AWS Services.
- **REST API**: Sviluppa un'API REST in cui hai il completo controllo sulla richiesta e sulla risposta insieme alle capacità di gestione delle API. Funziona con: Lambda, HTTP, AWS Services.
- **REST API Privata**: Crea un'API REST accessibile solo dall'interno di una VPC.

### Componenti principali di API Gateway

1. **Risorse**: In API Gateway, le risorse sono i componenti che **costituiscono la struttura della tua API**. Rappresentano **i diversi percorsi o endpoint** della tua API e corrispondono alle varie azioni che la tua API supporta. Una risorsa è ogni metodo (ad es., GET, POST, PUT, DELETE) **all'interno di ciascun percorso** (/, o /users, o /user/{id}).
2. **Fasi**: Le fasi in API Gateway rappresentano **diverse versioni o ambienti** della tua API, come sviluppo, staging o produzione. Puoi utilizzare le fasi per gestire e distribuire **più versioni della tua API simultaneamente**, consentendoti di testare nuove funzionalità o correzioni di bug senza influenzare l'ambiente di produzione. Le fasi supportano anche **variabili di fase**, che sono coppie chiave-valore che possono essere utilizzate per configurare il comportamento della tua API in base alla fase attuale. Ad esempio, potresti utilizzare variabili di fase per indirizzare le richieste API a diverse funzioni Lambda o altri servizi backend a seconda della fase.
- La fase è indicata all'inizio dell'URL dell'endpoint di API Gateway.
3. **Autenticatori**: Gli autenticatori in API Gateway sono responsabili di **controllare l'accesso alla tua API** verificando l'identità del chiamante prima di consentire la continuazione della richiesta. Puoi utilizzare **funzioni AWS Lambda** come autenticatori personalizzati, il che ti consente di implementare la tua logica di autenticazione e autorizzazione. Quando arriva una richiesta, API Gateway passa il token di autorizzazione della richiesta all'autenticatore Lambda, che elabora il token e restituisce una policy IAM che determina quali azioni il chiamante è autorizzato a eseguire. API Gateway supporta anche **autenticatori integrati**, come **AWS Identity and Access Management (IAM)** e **Amazon Cognito**.
4. **Policy delle risorse**: Una policy delle risorse in API Gateway è un documento JSON che **definisce i permessi per accedere alla tua API**. È simile a una policy IAM ma specificamente adattata per API Gateway. Puoi utilizzare una policy delle risorse per controllare chi può accedere alla tua API, quali metodi possono chiamare e da quali indirizzi IP o VPC possono connettersi. **Le policy delle risorse possono essere utilizzate in combinazione con gli autenticatori** per fornire un controllo degli accessi dettagliato per la tua API.
- Per avere effetto, l'API deve essere **ridistribuita dopo** che la policy delle risorse è stata modificata.

### Registrazione

Per impostazione predefinita, **CloudWatch Logs** sono **disattivati**, **Access Logging** è **disattivato**, e **X-Ray tracing** è anch'esso **disattivato**.

### Enumerazione

> [!TIP]
> Nota che in entrambe le API AWS per enumerare le risorse (**`apigateway`** e **`apigatewayv2`**) l'unico permesso di cui hai bisogno e l'unico permesso di lettura concessibile è **`apigateway:GET`**, con quello puoi **enumerare tutto.**

{{#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 }}

## Diverse autorizzazioni per accedere agli endpoint di API Gateway

### Politica delle risorse

È possibile utilizzare le politiche delle risorse per definire chi può chiamare gli endpoint API.\
Nell'esempio seguente puoi vedere che l'**IP indicato non può chiamare** l'endpoint `/resource_policy` tramite GET.

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

### Autenticatore IAM

È possibile impostare che un metodo all'interno di un percorso (una risorsa) richieda l'autenticazione IAM per essere chiamato.

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

Quando questo è impostato, riceverai l'errore `{"message":"Missing Authentication Token"}` quando provi a raggiungere l'endpoint senza alcuna autorizzazione.

Un modo semplice per generare il token atteso dall'applicazione è utilizzare **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"
```
Un altro modo è utilizzare il tipo **`Authorization`** **`AWS Signature`** all'interno di **Postman**.

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

Imposta l'accessKey e il SecretKey dell'account che desideri utilizzare e puoi autenticarti contro l'endpoint API.

Entrambi i metodi genereranno un **Authorization** **header** come:
```
AWS4-HMAC-SHA256 Credential=AKIAYY7XU6ECUDOTWB7W/20220726/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=9f35579fa85c0d089c5a939e3d711362e92641e8c14cc571df8c71b4bc62a5c2
```
Nota che in altri casi l'**Authorizer** potrebbe essere stato **mal codificato** e inviare **qualsiasi cosa** all'interno dell'**Authorization header** **permetterà di vedere il contenuto nascosto**.

### Richiesta di Firma Utilizzando 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)

```
### Autenticatore Lambda Personalizzato

È possibile utilizzare un lambda che, basato su un dato token, **restituirà una policy IAM** che indica se l'utente è **autorizzato a chiamare l'endpoint API**.\
Puoi impostare ogni metodo di risorsa che utilizzerà l'autenticatore.

<details>

<summary>Esempio di Codice dell'Autenticatore 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>

Chiamalo con qualcosa come:

<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]
> A seconda del codice Lambda, questa autorizzazione potrebbe essere vulnerabile

Nota che se viene **generata e restituita una policy di negazione**, l'errore restituito da API Gateway è: `{"Message":"User is not authorized to access this resource with an explicit deny"}`

In questo modo potresti **identificare questa autorizzazione** in atto.

### Chiave API richiesta

È possibile impostare endpoint API che **richiedono una chiave API valida** per contattarlo.

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

È possibile generare chiavi API nel portale API Gateway e persino impostare quanto possono essere utilizzate (in termini di richieste al secondo e in termini di richieste al mese).

Per far funzionare una chiave API, è necessario aggiungerla a un **Piano di Utilizzo**, questo piano di utilizzo deve essere aggiunto allo **Stadio API** e lo stadio API associato deve avere configurato un **throttling del metodo** per l'**endpoint** che richiede la chiave API:

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

## Accesso non autenticato

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

## Privesc

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

## Post Exploitation

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

## Persistenza

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

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