AWS - API Gateway Enum

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

API Gateway

Basic Information

AWS API Gateway is a comprehensive service offered by Amazon Web Services (AWS) designed for developers to create, publish, and oversee APIs on a large scale. It functions as an entry point to an application, permitting developers to establish a framework of rules and procedures. This framework governs the access external users have to certain data or functionalities within the application.

API Gateway enables you to define how requests to your APIs should be handled, and it can create custom API endpoints with specific methods (e.g., GET, POST, PUT, DELETE) and resources. It can also generate client SDKs (Software Development Kits) to make it easier for developers to call your APIs from their applications.

API Gateways Types

  • HTTP API: Build low-latency and cost-effective REST APIs with built-in features such as OIDC and OAuth2, and native CORS support. Works with the following: Lambda, HTTP backends.

  • WebSocket API: Build a WebSocket API using persistent connections for real-time use cases such as chat applications or dashboards. Works with the following: Lambda, HTTP, AWS Services.

  • REST API: Develop a REST API where you gain complete control over the request and response along with API management capabilities. Works with the following: Lambda, HTTP, AWS Services.

  • REST API Private: Create a REST API that is only accessible from within a VPC.

API Gateway Main Components

  1. Resources: In API Gateway, resources are the components that make up the structure of your API. They represent the different paths or endpoints of your API and correspond to the various actions that your API supports. A resource is each method (e.g., GET, POST, PUT, DELETE) inside each path (/, or /users, or /user/{id}.

  2. Stages: Stages in API Gateway represent different versions or environments of your API, such as development, staging, or production. You can use stages to manage and deploy multiple versions of your API simultaneously, allowing you to test new features or bug fixes without affecting the production environment. Stages also support stage variables, which are key-value pairs that can be used to configure the behavior of your API based on the current stage. For example, you could use stage variables to direct API requests to different Lambda functions or other backend services depending on the stage.

    • The stage is indicated at the beggining of the URL of the API Gateway endpoint.

  3. Authorizers: Authorizers in API Gateway are responsible for controlling access to your API by verifying the identity of the caller before allowing the request to proceed. You can use AWS Lambda functions as custom authorizers, which allows you to implement your own authentication and authorization logic. When a request comes in, API Gateway passes the request's authorization token to the Lambda authorizer, which processes the token and returns an IAM policy that determines what actions the caller is allowed to perform. API Gateway also supports built-in authorizers, such as AWS Identity and Access Management (IAM) and Amazon Cognito.

  4. Resource Policy: A resource policy in API Gateway is a JSON document that defines the permissions for accessing your API. It is similar to an IAM policy but specifically tailored for API Gateway. You can use a resource policy to control who can access your API, which methods they can call, and from which IP addresses or VPCs they can connect. Resource policies can be used in combination with authorizers to provide fine-grained access control for your API.

    • In order to make effect the API needs to be deployed again after the resource policy is modified.

Logging

By default, CloudWatch Logs are off, Access Logging is off, and X-Ray tracing is also off.

Enumeration

Note that in both AWS apis to enumerate resources (apigateway and apigatewayv2) the only permission you need and the only read permission grantable is apigateway:GET, with that you can enumerate everything.

# 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

Different Authorizations to access API Gateway endpoints

Resource Policy

It's possible to use resource policies to define who could call the API endpoints. In the following example you can see that the indicated IP cannot call the endpoint /resource_policy via GET.

IAM Authorizer

It's possible to set that a methods inside a path (a resource) requires IAM authentication to call it.

When this is set you will receive the error {"message":"Missing Authentication Token"} when you try to reach the endpoint without any authorization.

One easy way to generate the expected token by the application is to use the Authorization type AWS Signature inside Postman.

Set the accessKey and the SecretKey of the account you want to use and you can know authenticate against the API endpoint.

It will generate an Authorization header such as:

AWS4-HMAC-SHA256 Credential=AKIAYY7XU6ECUDOTWB7W/20220726/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=9f35579fa85c0d089c5a939e3d711362e92641e8c14cc571df8c71b4bc62a5c2

Note that in other cases the Authorizer might have been bad coded and just sending anything inside the Authorization header will allow to see the hidden content.

Request Signing Using 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)

Custom Lambda Authorizer

It's possible to use a lambda that based in a given token will return an IAM policy indicating if the user is authorized to call the API endpoint. You can set each resource method that will be using the authoriser.

Lambda Authorizer Code Example
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

Call it with something like:

curl "https://jhhqafgh6f.execute-api.eu-west-1.amazonaws.com/prod/custom_auth" -H 'Authorization: your-secret-token'

Depending on the Lambda code, this authorization might be vulnerable

Note that if a deny policy is generated and returned the error returned by API Gateway is: {"Message":"User is not authorized to access this resource with an explicit deny"}

This way you could identify this authorization being in place.

Required API Key

It's possible to set API endpoints that require a valid API key to contact it.

It's possible to generate API keys in the API Gateway portal and even set how much it can be used (in terms of requests per second and in terms of requests per month).

To make an API key work, you need to add it to a Usage Plan, this usage plan mus be added to the API Stage and the associated API stage needs to have a configured a method throttling to the endpoint requiring the API key:

Unauthenticated Access

pageAWS - API Gateway Unauthenticated Enum

Privesc

pageAWS - Apigateway Privesc

Post Exploitation

pageAWS - API Gateway Post Exploitation

Persistence

pageAWS - API Gateway Persistence
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated