Skip to main contentSkip to main content
Room Banner
Back to all walkthroughs
Room Icon

AWS API Gateway

An overview of security features and common attacks for the AWS API Gateway service.

medium

50 min

287

User profile photo.
User profile photo.

To access material, start machines and answer questions login.

It's hard to find a website in 2022 that doesn't make extensive use of Application Programming Interfaces, or APIs, to provide the various functionalities of the website to end users in their browsers. APIs have become a ubiquitous and critical part of the modern technology stack. As a quick overview for those unfamiliar, this task will discuss the basics of an .

Before explaining what an is, it is helpful to define key components of an /HTTPS :

Components

Endpoint: This is the URL location of the , e.g., the address where you can "call" an and the resources it can access on your behalf.

Method: This specifies the type of request being made to the , such as GET, POST, PUT, DELETE, etc.

Headers: These are a component of , but are used by APIs to contain additional information about the request, such as authentication details, content type, and other metadata.

Request body: This is the data sent to the as part of the request. GET requests won't typically have a request body, but POST, PUT, and DELETE requests almost always do.

Response: This is the data that the sends in response to the request. It may include a status code, headers, and a response body.

Purpose

APIs provide a granular mechanism for developers to allow user access to (potentially) sensitive "back-end" resources. Not only do APIs expose these capabilities for end users, but they also allow third-parties to build reliable ecosystems around a product that exposes an . Notably, this caused recent controversy as Twitter burned third-party client access (opens in new tab) to the Twitter . This controversy only reiterates the significance of APIs for organizations using modern technology.

Furthermore, as mentioned, modern APIs often expose a number of sensitive "back-end" resources hosted on behalf of the . These resources are often "micro-services" that the user request as a direct database write or query to the various systems that may be supporting the functionality. If security errors are made in the development of the capabilities, they may be exposed to any user who can authenticate to the or even to unauthenticated users who attempt to use the . These characteristics make Gateway a prime target for attackers.

Answer the questions below
What is the URL location of an API called?

What request type commonly doesn't include a request body?

Select the Cloud details button at the top of the room:

Where needed generate the environment required for the room. The "Generate Environment" button will appear if the room contains an environment that needs to be generated. 

For any issues with the environment, select the "Reset Environment" button. Review this article for more information.

To view the credentials required for the environment, select the credentials tab. You can use these credentials to access the environment in various ways. More information can be found here:

Answer the questions below
Generate environment or set up your credentials

Gateway 

Gateway is a service provided by to assist customers in deploying , /S, and WebSocket APIs using "serverless" infrastructure. While and /S APIs are similar (opens in new tab), WebSocket APIs are inherently different because the WebSocket protocol allows for bi-directional communication. This means that WebSocket APIs can push information to clients who have connected without the client sending an additional request.

and its "special" integration with Gateway

Gateway essentially provides an mechanism to attach to other resources. That means when someone on the internet queries an behind Gateway, they are commonly interacting with other services or resources. These capabilities are known as integrations (opens in new tab). Specifically, Gateways will most often integrate with functions, because is the default service for Gateway endpoints. If you have never worked with or other serverless functions, they allow you to write scripts and other small "programs" that can be executed on your behalf by without ever provisioning a server. 

Integrations Introduction

functions aren't the only service that you may integrate with, but they also serve a second special function in relation to Gateway - the authorizer. (opens in new tab) The authorizer, when configured, determines who can access the endpoints behind an Gateway and what resources they can request to access. These authorizers are custom code developed by the organization deploying the Gateway, and are arbitrarily configurable to make decisions based on any set of characteristics a developer may choose. When misconfigured, the code may allow unintended and unauthorized access to resources behind an Gateway. We'll take a closer look at this idea later on in this room.

Answer the questions below

What does the WebSocket API additionally allow, compared to REST or HTTP/S APIs?

What default function does Lambda perform for API Gateway endpoints?

What is a special secondary function of Lambda?

Common Services and Purposes

Gateways are a pillar of modern technology platforms. Whether using a managed Gateway such as the ones available at all major cloud providers, or a self-managed gateway that you might build yourself (opens in new tab), it's impossible to deploy a "micro-services" style architecture without something like an Gateway. 

offers first-class support for many of their services to integrate with Gateway (opens in new tab), providing a number of common capabilities that you would need for any Gateway and for a wide variety of use cases:

  • Serverless Architecture: Gateway can be integrated with to build serverless applications, where the function is triggered by Gateway to process incoming requests and return responses.
  • Microservices: Gateway can be used to create, deploy, and manage APIs for microservices, allowing for easier communication and integration between services. These "microservices" could be any server, , or serverless function - along with a variety of services for messaging (, SQS, , etc.)
  • Data storage and retrieval: Gateway integrates with Amazon DynamoDB and Amazon to provide seamless access to stored data.
  • Real-time communication: Gateway can be used with WebSockets to provide real-time, bidirectional communication between clients and servers.
  • Management: Gateway provides tools for monitoring, logging, and managing APIs, making it easier to understand and control usage.
  • Security: Gateway provides robust security features, including OAuth 2.0 and Identity and Access Management () integration for access control, and SSL/ encryption for data in transit.

These are some of the most common use cases for integrating services with Gateway, but there are many more possibilities as Gateway is a highly flexible and scalable service.

Answer the questions below

What are the two aspects that WebSockets for API Gateway provides? (Answer format: ANSWER1, ANSWER2)

Offensive Gateway

Gateway serves a nifty purpose when hacking. Namely, Gateway is a serverless "reverse ". A reverse  is a server that sits between clients and a web server, forwarding client requests to the web server and returning the server's responses back to the clients. Reverse proxies are commonly used for load balancing, caching, SSL termination, and hiding the identity of the underlying web server.

Hackers can use the as a way to hide their identity while launching attacks on the web server or other targets. In fact, when used as a "passthrough" (opens in new tab), with a pool of IP addresses, you can effectively make any given request appear to come from an IP address in the pool.

Reverse Proxies for Hackers

Rotating IP addresses when using a can be valuable for security testers for a variety of reasons:

Bypassing IP-based restrictions: Some web applications and systems may block requests from specific IP addresses if they detect unusual or suspicious activity. By rotating IP addresses, security testers can bypass these restrictions and continue testing.

Evading detection: Some systems may have security measures in place that detect and block requests from known IP addresses of security testers. By rotating IP addresses, security testers can evade detection and continue testing.

Simulating real-world scenarios: In real-world scenarios, users access websites and applications from different IP addresses. By rotating IP addresses, security testers can simulate real-world scenarios more accurately and identify potential security vulnerabilities that may arise.

To rotate IP addresses when using a , one option is to use a rotating service. This type of service automatically switches between a pool of servers, ensuring that each request is sent from a different IP address. Another option is to manually switch between different servers, either by manually configuring the settings in the browser or by using a tool that allows for automatic switching between servers. Enter Gateway and a tool called FireProx (opens in new tab) written by Mike Felch of Black Hills Information Security. Mike notes in the readme to the project that he wasn't the first person to discover this wonderful "feature".

FireProx 

For this next activity, you will need to log in and use your TryHackMe credentials, either by configuring them in the on the Attack Box or by using CloudShell.

FireProx is a tool designed to use Gateway for rotating your IP address when making web requests. It implements an Gateway endpoint that redirects all requests to a configured domain or IP address. This capability has proven particularly useful for password spraying and similar credential attacks (opens in new tab). It is also useful for making requests to /S or WebSocket endpoints that may implement IP-based restrictions or rate-limiting. This proves particularly useful when querying APIs that implement IP-based rate limiting.

It turns out our good friends at Best Cloud Company have their own endpoint. We can use FireProx to make requests to the Best Cloud Company by deploying a FireProx endpoint.

1. Using CloudShell:

Clone and install the repository using the following commands:

git clone https://github.com/ustayready/fireprox

cd fireprox

pip3 install -r requirements.txt

When you are in the appropriate directory for FireProx, you can run FireProx using the following command: python3 fire.py

2. Using the THM AttackBox:

FireProx is already installed in the /opt/fireprox/ directory. Before continuing, configure your AWS credentials using the aws configure command.

When you are in the appropriate directory for FireProx, you can run FireProx using the following command:

python3.9 fire.py

For those using a CloudShell - you will need to clone the repository using the link above.  It is already installed on the attack box in the fireprox/ directory. When you are in the appropriate directory for FireProx and have configured AWS credentials (on Attack Box), you can run FireProx using the following command:

FireProx
           root@ip-10-10-89-159:~#  python fire.py
        

This command will simply output the help information regarding FireProx.

FireProx Create
           root@ip-10-10-89-159:~#  python fire.py --command create --url https://api.bestcloudcompany.org
Creating => https://api.bestcloudcompany.org...
[2023-01-18 12:54:07-06:00] (bnyqzbg5pc) fireprox_bestcloudcompany => https://bnyqzbg5pc.execute-api.us-east-1.amazonaws.com/fireprox/ (https://api.bestcloudcompany.org)
        

Next, you can go into your browser (or Burp Suite/another proxy/curl commands in CloudShell) and use https://bnyqzbg5pc.execute-.us-east-1.amazonaws.com/fireprox/ (in my case - you'll want to use your endpoint) to access https://.bestcloudcompany.org/. If you were to look at the "server" logs for the Gateway instance hosting .bestcloudcompany.org - you would see each request coming through the FireProx endpoint comes from a separate IP address. Once you are finished with FireProx, you will want to delete endpoints you are no longer using. You can do this with the following commands.

FireProx List
           root@ip-10-10-89-159:~#  python fire.py --command list
Listing API's...
[2023-01-31 12:26:46-06:00] (bnyqzbg5pc) fireprox_bestcloudcompany: https://bnyqzbg5pc.execute-api.us-east-1.amazonaws.com/fireprox/ => https://api.bestcloudcompany.org/

        

You will then use the returned api_id to delete the endpoint.

FireProx Delete
           root@ip-10-10-89-159:~#  python3 fire.py --command delete --api_id bnyqzbg5pc                                      
Deleting bnyqzbg5pc => Success!
        
Answer the questions below
What is the serverless capability that AWS API Gateway represents?

What does rotating IP addresses allow you to bypass?

Authorizers Introduction

Authorizers in Gateway are functions that provide authorization for requests. They are used to control access to specific resources fronted by Gateway, ensuring that only authorized users are able to access these resources. A Authorizer function is executed before an request is processed, and it returns a policy document that specifies whether the request is authorized or not.

Authorizers are useful because they allow you to perform complex authorization logic without having to manage infrastructure or write custom authorization code. This makes it easier to manage access control for your APIs, and it also enables you to offload resource-intensive authorization tasks to .

Greedy Expansion

While using wildcards in paths with Authorizers in Gateway can be convenient, it is important to be mindful of the potential consequences of greedy expansion.

The * wildcard in regex is a greedy operator that matches zero or more characters in a string. When used in matching URL paths, this can lead to unexpected matches if not used carefully. For example, a regex pattern with a greedy * might match more characters than intended, potentially matching parts of multiple URL paths. To avoid this, it's important to use grouping and lazy operators to control the match and ensure it only matches the intended portion of the URL path.

For example, if an path with a wildcard is created to allow access to a specific resource, but an unintended path that includes the approved path name is also created, it may lead to unexpected authorization for that resource. This could result in security vulnerabilities, as users may be able to access restricted resources without proper authorization. For a closer examination of this security weakness in relation to Gateway - please see "The Fault In Our Stars" by Tenchi Security (opens in new tab).

Abusing Greedy Expansion of Authorizer Policies

It is important to carefully consider the implications of using wildcards in paths, and to implement proper testing and validation to ensure that unintended consequences do not occur. Unfortunately, our friends at Best Cloud Company dropped the ball...can you find a way in?

We start by looking for web properties associated with Best Cloud Company - and we stumble upon their . It wasn't really hard, I mean - .bestcloudcompany.org seems pretty obvious in hindsight. Once we identify an , we would typically use a tool such as ffuf (opens in new tab) or kiterunner (opens in new tab) to perform the discovery of endpoints through fuzzing. These techniques and tools can help identify potentially interesting endpoints and opportunities to expose data or gain additional access. These tools are really outside the scope of our hacking, because the Best Cloud Company really isn't good at security. You can start by checking out their "documentation" in a web browser at https://.bestcloudcompany.org/ (opens in new tab)

requests commonly require some sort of request header to validate the requesting party. In our case, Best Cloud Company indicates a need to use an "authorizationToken" header and gives us suggestions on a couple of endpoints to try. Let's give it a shot!

Curl Best Cloud Company
           root@ip-10-10-89-159:~#  curl https://api.bestcloudcompany.org/
        

We are going to use curl - a command line HTTP utility - to perform our requests. You may want to use a tool like Postman or Burp Suite to perform your own testing of endpoints. Those tools can be particularly useful when making complex PUT/POST requests. Using the curl request above, you should see the same information in an HTML format when you run the command.

Next, let's try requesting one of the endpoints that the 'documentation' author suggests. We will make our request to the test stage and the test endpoint.

Curl Best Cloud Company /test/test/
           root@ip-10-10-89-159:~#  curl https://api.bestcloudcompany.org/test/test/
{"message":"Unauthorized"}%   

        

Unauthorized! Huh - well, the docs did say we need a header...let's try the one they gave us:

Curl Best Cloud Company /test/test/ with header
           root@ip-10-10-89-159:~#  curl --header "authorizationToken:{provided_header_value}" https://api.bestcloudcompany.org/test/test/
        

Alright - now we're cooking. Why don't you try the admin endpoint...I bet you might come up with some ideas of how to access prod from there?

Curl Best Cloud Company Prod
           root@ip-10-10-89-159:~#  curl --header "header_value" https://api.bestcloudcompany.org/test/admin/
        

Ok - so it's left as an exercise to you to find the authorization token you might use to access the prod stage admin endpoint - but can't you request https://.bestcloudcompany.org/prod/test/ now, with just your "Testing123" token?

Why is that possible? I mean - "John" needed to give you the password, right? Well - it turns out that best cloud company fell victim to exactly the attack Tenchi Security raised regarding greedy expansion. Here's an example of what their lambda authorizer policy looks like:

Python Lambda Authorizer Example
           root@ip-10-10-89-159:~#  
    if event['authorizationToken'] == 'testing123':
        auth = 'Allow'
        authResponse = {"principalId": "testing123", "policyDocument": {"Version": "2012-10-17", "Statement": [
            {"Action": "execute-api:Invoke",
             "Resource": "arn:aws:execute-api:us-east-1:{ACCOUNT_ID}:*/*/test/*",
             "Effect": auth}]}}
        return authResponse
    elif event['authorizationToken'] == ‘{PROD_AUTH_TOKEN}’:
        auth = 'Allow'
        authResponse = {"principalId": "testing123", "policyDocument": {"Version": "2012-10-17", "Statement": [
            {"Action": "execute-api:Invoke",
             "Resource": "arn:aws:execute-api:us-east-1:{ACCOUNT_ID}:*/*/prod/*",
             "Effect": auth}]}}
        return authResponse

        

In fact, to demonstrate what is happening here - try to request the https://.bestcloudcompany.org/prod/test endpoint; it should be the same, right?

Well, look at that. It turns out that having /test as a value means the resource isn't accessible using your api_key, but having /test/ in the endpoint path does. I mean, while I don't want to give Best Cloud Company too much credit - I could have reasonably made the same mistake...and many people do.

Answer the questions below
What is the api_key for the /test/test user?

What is the api_key value for the /test/admin user?

What is the api_key value for the /prod/admin user?

Ready to learn Cyber Security?

TryHackMe provides free online cyber security training to secure jobs & upskill through a fun, interactive learning environment.

Already have an account? Log in

We use cookies to ensure you get the best user experience. For more information see our cookie policy.