Fuzzing with CLZero
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):
Skipping read on the Smuggle request ensures less time between requests:
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.
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.
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/