HTTP Downgrade attacks with SmuggleFuzz
Better late than never
2021 was a weird year. As we started to socialy re-engage with our friends and peers, I found myself trying to grasp onto the remnants of my social skills and sanity. Amidst this, some individuals were diligently at work, getting out an important message. James Kettle and Emile Lerner, in their separate endeavors, explored the intricacies of HTTP/2 downgrade attacks, unveiling their findings at respective conferences. For those yet to delve into the subject of downgrade attacks, read on here:
Ever since encountering their research, I’ve been driven to deepen my understanding of HTTP/2 protocol specifications. Last year, having some extra time at my disposal, I decided to develop a command-line tool for identifying smuggling vulnerabilities, simultaneously enhancing my protocol expertise. Emile has already introduced a great tool, http2smugl (which also supports HTTP/3), and James has developed the amazing Burp plugin - HTTP Request Smuggler. Nevertheless, I was compelled to create an additional fuzzer, offering command-line interaction and customizable requests. The tool also integrates a time-based detection method, similar to that used in defparam’s Smuggler. Although arriving nearly three years late, I’m proud to introduce SmuggleFuzz.
SmuggleFuzz is designed to assist in identifying HTTP downgrade attack vectors. Its standout feature is not just the time-based detection or request handling, but the detailed response information it provides. This empowers users to define their own detection methods, including monitoring HTTP status codes and response sizes. It also handles RST_STREAM frames, including error codes to better pinpoint successful HTTP Smuggling requests or identify failed attacks. SmuggleFuzz adeptly manages GOAWAY frames and establishes new TCP connections without disrupting existing streams. Custom timeout values for confirmation requests can also be set by users.
Wordlist
SmuggleFuzz allows users complete control over requests through custom wordlists. These lists have a basic structure, which should be followed for optimal request handling. For instance, headers and their values are split using a semicolon and a space (; )
instead of the usual colon, facilitating the inclusion of colon values in smuggling requests. This also opens up possibilities for various mutations and creative approaches. For detailed guidance on creating your own payloads, refer to PortSwigger’s HTTP/2 Research above.
The tool includes a ready-to-use list of 125 smuggling gadgets, though there’s always scope for expansion. These gadgets can be displayed using the ‘output’ command, providing insights into query structuring. Users can run scans with custom wordlists using the ‘w’ flag. The list supports URL encoding %00
for non-printable byte values, such as carriage return and line feed represented as %0d%0a
or \r\n
. While the provided list is comprehensive, crafting your own gadgets can significantly enhance success rates.
Pseudo headers
Pseudo headers are fully supported and can be customized using the “:name” syntax:
:authority
:scheme
:method
These headers are particularly useful when testing for H2.0 attack vectors. For example, in testing H2.0 smuggling using OAST-based methods, wordlist entries like the following can be effective:
As of v0.1.8 [HOSTNAME] can be used as a placeholder. SmuggleFuzz will replace this with the hostname at runtime.
:authority; [HOSTNAME]\r\n\r\nGET / HTTP/1.1\r\nHost: uniqid.oastify.com\r\nX-HEADER:%20
or
:authority; [HOSTNAME]\r\n\r\nGET https://uniqid.oastify.com/ HTTP/1.1\r\nHost: [HOSTNAME]\r\nX-HEADER:%20
Detection
The detection method employed in SmuggleFuzz is akin to those used by Albinowax in his HTTP/1 smuggling research and defparam’s Smuggler, albeit with adaptations for HTTP/2. Fortunately, as these attacks involve downgrades, the same request body/DATA payload can be utilized for both H2.CL and H2.TE detection.
A crucial guideline for wordlists is that successfully smuggled headers should include the following values for a confirmatory attack:
CL: 13
TE: chunked
Each request incorporates a “Body”/DATA-Frame with the value “99”. If a TE header is smuggled, it is interpreted as a chunked content length of 153 (0x99) by the server if successfully smuggled, leading to a timeout. Similarly, smuggling a CL header with a content length of 13 also results in a timeout due to unfulfilled length.
The confirmatory request resubmits the same query that led to the timeout, but with Data: 3\r\nABC\r\n0\r\n\r\n
. This satisfies both a chunked TE and a CL of 13, eliciting a successful response and potentially indicating a smuggling vulnerability.
Install
Get a copy from https://github.com/Moopinger/smugglefuzz/releases.
Or, build yourself
go install github.com/moopinger/smugglefuzz@latest
Compile yourself:
git clone https://github.com/moopinger/smugglefuzz.git
cd smugglefuzz
go build .
./smugglefuzz
Go to https://github.com/moopinger/smugglefuzz/ for details.
Usage
There are three commands for SmuggleFuzz:
- scan
- request
- output
This will just output the default smuggle gadgets. Currently the build in comfirmation only for H2.CL and H2.TE. But it is still possible to detect H2.0 attacks via timeouts (–filter TIMEOUT) or OAST on a domain of yours.