Fuzz banner

Last week I read the blogpost “From Akamai to F5 to NTLM… with love.” by d3d, it is a great read and you should check it out. In the post d3d drops the hammer on Akamai, via a CL.0 request smuggling technique.

“I initially thought… this can’t be true. Does this specific gadget work on all these companies?! Am I doing something wrong, or am I looking at this all wrong?! I was not.” - d3d

While reading the post I realised that I may have missed quite a few opportunities in my own scanning and neglecting the HTTP/1.1 CL.0 technique entirely. And James Kettle has added some new attack techniques since his initial discovery of the vulnerability. I was also reminded of a python based tool for fuzzing TE.CL and CL.TE requests called Smuggler by Defparam. Odds are, you have used smuggler yourself while hunting for TE.CL/CL.TE request smuggling vulnerabilities. It is really nifty and allows for a lot of request customization via it’s configuration files and works really well.

Smuggler uses a single http request, containing the smuggle gadget for detection both TE.CL and CL.TE vulnerabilities. Confirmation also takes place with a slightly modified request, however we will just focus on the initial detection. If the smuggle was successful the response should timeout. This technique works well, however when identifying CL.0 attacks, detection will require two separate HTTP/1.1 requests sent over two separate tcp connections - at least the way with least FPs it seems. This has resulted in me creating a tool called CLZero. Combining the power of Smuggler and CL.0 with an entirely different detection method.

CLZero

Firstly I would just like to thank @defparam for making such an awesome tool like Smuggler, and @albinowax for all the work he has done in this space. And @d3d for the great research and articles. Without them this tool would not be possible. I have tried to keep the running / configuration of CLZero as similar to Smuggler as possible. I have included all the current smuggler attacks for CL.TE attacks and changed them to CL.0 I have also included some of the new techniques from @albinowax. As far as i know Burp’s HTTP Request Smuggler covers all these cases.

Grab a copy here https://github.com/Moopinger/CLZero/

CL.0 Identification method

The first request will be the “base” request. This is just for retrieving a successful response to compare probes against. All sequential requests will be the smuggle and probe pairs for each technique provided. The smuggle request contains the smuggle gadget and the probe is the request we will hopefully404 or hopefully405 status response - indicating a successful smuggle. Using a single TCP connection and pipelining both the smuggle request and the probe, would be perfect, however it is difficult to tell whether the interesting/giveaway part of the response was generated by the frontend or the backend - resulting in a lot of false positives. Using separate TCP connections to send the smuggle request and the probe, skips this. And ensures far fewer false positives. However there is a new problem.

The problem

Ensuring that the smuggle request and probe are processed sequentially can be tricky, especially when dealing with a high traffic site. To combat this CLZero can use the -skipread flag to skip reading the response of the smuggle request and instead immediately send the probe request. This saves a lot of time between requests and should be your most used technique as there is no real reason to wait for the response, we are just interested in the response to the probe request.

Regular (smug.py is clzero.py with some debugging enabled):

regular request

Skipping read on the Smuggle request ensures less time between requests:

skip request

More Speed with last-byte sync

What’s that… you need more speed? “She’s at max captain!” Just kidding. If the website has high amounts of traffic this will be your best bet. I have adapted the HTTP/1.1 last-byte sync race condition (No, not the cool one you heard about at Defcon this year, that requires HTTP/2). This saves even more time between the smuggle request and probe. However, there is a catch… We cannot guarantee which will be processed first by the server (The smuggle-gadget or the probe). Such is the nature of race conditions I guess. However if you don’t mind testing the same technique more than once on a high traffic site, this will be your best bet. And it should trigger within two or three requests. Strangely I have had better success with this than the skip-read technique.

lastbyte sync request

Usage

Usage is similar to Smuggler, whereby the user specifies a config file containing the requests and gadgets. All attacks by @defparam and @albinowax The following are:

  • default.py - Covers most standard attacks methods and charachters
  • exhaustive.py - Covers a lot of different attacks
  • quick.py - Only 10 of the more common attacks.
usage: clzero.py [-h] [-url URL] [-file FILE] [-index INDEX] [-verbose] [-no-color] [-resume] [-skipread] [-quiet] [-lb] [-config CONFIG] [-method METHOD]

CLZero by Moopinger - Thanks: Smuggler - @Defparam. @Albinowax. D3d - @deadvolvo

optional arguments:
  -h, --help      show this help message and exit
  -url URL        (-u), Single target URL.
  -file FILE      (-f), Files containing multiple targets.
  -index INDEX    (-i), Index start point when using a file list. Default is first line.
  -verbose        (-v), Enable verbose output.
  -no-color       Disable colors in HTTP Status
  -resume         Resume scan from last index place.
  -skipread       Skip the read response on smuggle requests, recommended. This will save a lot of time between requests. Ideal for targets with standard HTTP traffic.
  -quiet          (-q), Disable output. Only successful payloads will be written to ./payloads/
  -lb             Last byte sync method for least request latency. Due to the nature of the request, it cannot guarantee that the smuggle request will be processed first. Ideal for targets with a high
                  amount of traffic, and you do not mind sending multiple requests.
  -config CONFIG  (-c) Config file to load, see ./configs/ to create custom payloads
  -method METHOD  (-m) Method to use when sending the smuggle request. Default: POST

Single target attack:

  • python3 clzero.py -u https://www.target.com/ -c configs/default.py -skipread
  • python3 clzero.py -u https://www.target.com/ -c configs/default.py -lb

Multi target attack:

  • python3 clzero.py -l urls.txt -c configs/default.py -skipread
  • python3 clzero.py -l urls.txt -c configs/default.py -lb

When a succesfuly smuggled request is detected, the payload is written to ./payloads/