# AWS - API Gateway Enum {{#include ../../../banners/hacktricks-training.md}} ## API Gateway ### Podstawowe informacje AWS API Gateway to kompleksowa usługa oferowana przez Amazon Web Services (AWS), zaprojektowana dla programistów do **tworzenia, publikowania i nadzorowania API na dużą skalę**. Działa jako punkt wejścia do aplikacji, pozwalając programistom na ustanowienie ram zasad i procedur. Ta struktura reguluje dostęp zewnętrznych użytkowników do określonych danych lub funkcjonalności w aplikacji. API Gateway umożliwia zdefiniowanie **jak żądania do twoich API powinny być obsługiwane**, i może tworzyć niestandardowe punkty końcowe API z określonymi metodami (np. GET, POST, PUT, DELETE) i zasobami. Może również generować zestawy SDK (Software Development Kits) dla klientów, aby ułatwić programistom wywoływanie twoich API z ich aplikacji. ### Typy bramek API - **HTTP API**: Twórz niskolatencyjne i opłacalne REST API z wbudowanymi funkcjami takimi jak OIDC i OAuth2 oraz natywnym wsparciem CORS. Działa z następującymi: Lambda, HTTP backends. - **WebSocket API**: Twórz API WebSocket z użyciem stałych połączeń do zastosowań w czasie rzeczywistym, takich jak aplikacje czatowe lub pulpity nawigacyjne. Działa z następującymi: Lambda, HTTP, AWS Services. - **REST API**: Rozwijaj REST API, w którym zyskujesz pełną kontrolę nad żądaniem i odpowiedzią oraz możliwościami zarządzania API. Działa z następującymi: Lambda, HTTP, AWS Services. - **REST API Prywatne**: Twórz REST API, które jest dostępne tylko z wewnątrz VPC. ### Główne komponenty API Gateway 1. **Zasoby**: W API Gateway zasoby to komponenty, które **tworzą strukturę twojego API**. Reprezentują **różne ścieżki lub punkty końcowe** twojego API i odpowiadają różnym akcjom, które twoje API obsługuje. Zasobem jest każda metoda (np. GET, POST, PUT, DELETE) **w każdej ścieżce** (/, lub /users, lub /user/{id}). 2. **Etapy**: Etapy w API Gateway reprezentują **różne wersje lub środowiska** twojego API, takie jak rozwój, testowanie lub produkcja. Możesz używać etapów do zarządzania i wdrażania **wielu wersji twojego API jednocześnie**, co pozwala na testowanie nowych funkcji lub poprawek błędów bez wpływu na środowisko produkcyjne. Etapy również **obsługują zmienne etapu**, które są parami klucz-wartość, które mogą być używane do konfigurowania zachowania twojego API w zależności od aktualnego etapu. Na przykład, możesz użyć zmiennych etapu do kierowania żądań API do różnych funkcji Lambda lub innych usług backendowych w zależności od etapu. - Etap jest wskazywany na początku URL punktu końcowego API Gateway. 3. **Autoryzatory**: Autoryzatory w API Gateway są odpowiedzialne za **kontrolowanie dostępu do twojego API** poprzez weryfikację tożsamości wywołującego przed pozwoleniem na kontynuację żądania. Możesz używać **funkcji AWS Lambda** jako niestandardowych autoryzatorów, co pozwala na wdrożenie własnej logiki uwierzytelniania i autoryzacji. Gdy żądanie przychodzi, API Gateway przekazuje token autoryzacji żądania do autoryzatora Lambda, który przetwarza token i zwraca politykę IAM, która określa, jakie działania wywołujący może wykonać. API Gateway obsługuje również **wbudowane autoryzatory**, takie jak **AWS Identity and Access Management (IAM)** i **Amazon Cognito**. 4. **Polityka zasobów**: Polityka zasobów w API Gateway to dokument JSON, który **definiuje uprawnienia do dostępu do twojego API**. Jest podobna do polityki IAM, ale specjalnie dostosowana do API Gateway. Możesz użyć polityki zasobów, aby kontrolować, kto może uzyskać dostęp do twojego API, które metody mogą wywoływać i z jakich adresów IP lub VPC mogą się łączyć. **Polityki zasobów mogą być używane w połączeniu z autoryzatorami**, aby zapewnić szczegółową kontrolę dostępu do twojego API. - Aby wprowadzić zmiany, API musi być **ponownie wdrożone po** modyfikacji polityki zasobów. ### Logowanie Domyślnie **CloudWatch Logs** są **wyłączone**, **logowanie dostępu** jest **wyłączone**, a **śledzenie X-Ray** również jest **wyłączone**. ### Enumeracja > [!TIP] > Zauważ, że w obu API AWS do enumeracji zasobów (**`apigateway`** i **`apigatewayv2`**) jedynym uprawnieniem, którego potrzebujesz i jedynym przyznawanym uprawnieniem do odczytu jest **`apigateway:GET`**, dzięki czemu możesz **enumerować wszystko.** {{#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 ## Get resources aws apigateway get-resources --rest-api-id ## Get API resource action per HTTP verb (check authorizers and api key required) aws apigateway get-method --http-method GET --rest-api-id --resource-id ## Call API https://.execute-api..amazonaws.com// ## API authorizers aws apigateway get-authorizers --rest-api-id ## Models aws apigateway get-models --rest-api-id ## More info aws apigateway get-gateway-responses --rest-api-id aws apigateway get-request-validators --rest-api-id aws apigateway get-deployments --rest-api-id # Get api keys generated aws apigateway get-api-keys --include-value aws apigateway get-api-key --api-key --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 #Get clear text values of api keys aws apigateway get-usage-plan-key --usage-plan-id --key-id ###Already consumed aws apigateway get-usage --usage-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 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 ## Get all the info from an api at once aws apigatewayv2 export-api --api-id --output-type YAML --specification OAS30 /tmp/api.yaml ## Get stages aws apigatewayv2 get-stages --api-id ## Get routes aws apigatewayv2 get-routes --api-id aws apigatewayv2 get-route --api-id --route-id ## Get deployments aws apigatewayv2 get-deployments --api-id aws apigatewayv2 get-deployment --api-id --deployment-id ## Get integrations aws apigatewayv2 get-integrations --api-id ## Get authorizers aws apigatewayv2 get-authorizers --api-id aws apigatewayv2 get-authorizer --api-id --authorizer-id ## Get domain mappings aws apigatewayv2 get-api-mappings --api-id --domain-name aws apigatewayv2 get-api-mapping --api-id --api-mapping-id --domain-name ## Get models aws apigatewayv2 get-models --api-id ## Call API https://.execute-api..amazonaws.com// ``` {{#endtab }} {{#endtabs }} ## Różne autoryzacje do uzyskania dostępu do punktów końcowych API Gateway ### Polityka zasobów Możliwe jest użycie polityk zasobów do zdefiniowania, kto może wywołać punkty końcowe API.\ W poniższym przykładzie widać, że **wskazany adres IP nie może wywołać** punktu końcowego `/resource_policy` za pomocą GET.
### Autoryzator IAM Możliwe jest ustawienie, że metody w obrębie ścieżki (zasobu) wymagają uwierzytelnienia IAM do ich wywołania.
Gdy to jest ustawione, otrzymasz błąd `{"message":"Missing Authentication Token"}` gdy spróbujesz uzyskać dostęp do punktu końcowego bez jakiejkolwiek autoryzacji. Jednym z łatwych sposobów na wygenerowanie oczekiwanego tokena przez aplikację jest użycie **curl**. ```bash $ curl -X https://.execute-api..amazonaws.com// --user : --aws-sigv4 "aws:amz::execute-api" ``` Innym sposobem jest użycie typu **`Authorization`** **`AWS Signature`** w **Postman**.
Ustaw accessKey i SecretKey konta, którego chcesz użyć, a będziesz mógł uwierzytelnić się w punkcie końcowym API. Obie metody wygenerują nagłówek **Authorization** taki jak: ``` AWS4-HMAC-SHA256 Credential=AKIAYY7XU6ECUDOTWB7W/20220726/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=9f35579fa85c0d089c5a939e3d711362e92641e8c14cc571df8c71b4bc62a5c2 ``` Zauważ, że w innych przypadkach **Authorizer** mógł być **źle zakodowany** i wysłanie **czegokolwiek** w **nagłówku Authorization** **pozwoli zobaczyć ukrytą zawartość**. ### Podpisywanie żądań za pomocą Pythona ```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://.execute-api.us-east-1.amazonaws.com//' 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) ``` ### Niestandardowy autoryzator Lambda Możliwe jest użycie lambdy, która na podstawie danego tokena **zwróci politykę IAM**, wskazując, czy użytkownik jest **uprawniony do wywołania punktu końcowego API**.\ Możesz ustawić każdą metodę zasobu, która będzie korzystać z autoryzatora.
Przykład kodu autoryzatora Lambda ```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 ```
Wywołaj to za pomocą czegoś takiego:
curl "https://jhhqafgh6f.execute-api.eu-west-1.amazonaws.com/prod/custom_auth" -H 'Authorization: your-secret-token'
> [!WARNING] > W zależności od kodu Lambda, ta autoryzacja może być podatna Zauważ, że jeśli **polityka odmowy jest generowana i zwracana**, błąd zwrócony przez API Gateway to: `{"Message":"User is not authorized to access this resource with an explicit deny"}` W ten sposób możesz **zidentyfikować tę autoryzację**. ### Wymagany klucz API Możliwe jest ustawienie punktów końcowych API, które **wymagają ważnego klucza API** do kontaktu.
Możliwe jest generowanie kluczy API w portalu API Gateway, a nawet ustawienie, jak często mogą być używane (w kategoriach żądań na sekundę i w kategoriach żądań na miesiąc). Aby klucz API działał, musisz dodać go do **Planu Użytkowania**, ten plan użytkowania musi być dodany do **Etapu API**, a powiązany etap API musi mieć skonfigurowane **ograniczenie metod** dla **punktu końcowego** wymagającego klucza API:
## Dostęp nieautoryzowany {{#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}} ## Persistence {{#ref}} ../aws-persistence/aws-api-gateway-persistence/README.md {{#endref}} {{#include ../../../banners/hacktricks-training.md}}