The lab
here is how portswigger describes it
This lab involves a front-end and back-end server, and the back-end server doesn't support chunked encoding. The front-end server rejects requests that aren't using the GET or POST method.
To solve the lab, smuggle a request to the back-end server, so that the next request processed by the back-end server appears to use the method GPOST.
this is the te.cl twin of the basic cl.te lab. the goal is the same, get the back end to process a request with the made up method GPOST. only the direction of the disagreement flips, this is te.cl the front end trusts Transfer-Encoding and the back end trusts Content-Length, so the smuggle is shaped with a chunk size rather than a zero chunk up front.
The idea#
in the last lab we left a single leftover G for the next request to inherit. here we do something slightly fuller, we smuggle a whole request line that already starts with GPOST, and use the te.cl length disagreement to leave it sitting at the front of the connection
the front end reads chunks, so we open the body with a chunk size big enough to swallow our smuggled block as chunk data. the back end reads only a tiny Content-Length and stops almost immediately, so everything past those few bytes, our GPOST request line and its headers, is left over as the start of the next request.
Step 1 - Send the smuggle request#
we intercept a request and change it to this.
POST / HTTP/1.1
Host: your-lab-id.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
one detail that matters, there must be a trailing \r\n\r\n, an extra blank line, after the final 0, or the chunked body is not properly terminated and the attack fails.

walking through it the front end obeys Transfer-Encoding: chunked, reads 5c as a chunk size of 92 and takes the next 92 bytes, the whole GPOST block, as one chunk, then meets the 0 chunk and forwards the complete request. the back end obeys Content-Length: 4, reads only the first 4 bytes of the body, 5c and its line break, decides the request ends there, and leaves the rest, beginning at GPOST / HTTP/1.1, as the smuggled start of the next request
Step 2 - Send it again to make gpost#
we send the same request a second time on the same connection

this time our request meets the smuggled GPOST line already waiting on the connection, so the back end processes a request whose method is GPOST. that unknown method is what solves the lab, it shows our smuggled request line was handed to the back end as the next request.
with this, we solved the lab!
