# Upgrade Header Smuggling {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** ЁЯТм [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** ЁЯРж [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %} ### H2C Smuggling #### HTTP2 Over Cleartext (H2C) H2C, рдпрд╛ **http2 over cleartext**, рдЕрд╕реНрдерд╛рдпреА HTTP рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреЗ рдорд╛рдирдХ рд╕реЗ рднрдЯрдХрддрд╛ рд╣реИ, рдПрдХ рдорд╛рдирдХ HTTP **рдХрдиреЗрдХреНрд╢рди рдХреЛ рд╕реНрдерд╛рдпреА рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдХреЗ**ред рдпрд╣ рдЕрдкрдЧреНрд░реЗрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХрдиреЗрдХреНрд╢рди ongoing рд╕рдВрдЪрд╛рд░ рдХреЗ рд▓рд┐рдП http2 рдмрд╛рдЗрдирд░реА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ plaintext HTTP рдХреА рдПрдХрд▓-рдирд┐рд╡реЗрджрди рдкреНрд░рдХреГрддрд┐ рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реИред рд╕реНрдордЧрд▓рд┐рдВрдЧ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░рдг **рд░рд┐рд╡рд░реНрд╕ рдкреНрд░реЙрдХреНрд╕реА** рдХреЗ рдЙрдкрдпреЛрдЧ рдореЗрдВ рд╣реИред рд╕рд╛рдорд╛рдиреНрдпрддрдГ, рд░рд┐рд╡рд░реНрд╕ рдкреНрд░реЙрдХреНрд╕реА HTTP рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдкреНрд░реЛрд╕реЗрд╕ рдФрд░ рдлреЙрд░рд╡рд░реНрдб рдХрд░рддрд╛ рд╣реИ, рдЙрд╕рдХреЗ рдмрд╛рдж рдмреИрдХрдПрдВрдб рдХрд╛ рдЙрддреНрддрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЬрдм HTTP рдЕрдиреБрд░реЛрдз рдореЗрдВ `Connection: Upgrade` рд╣реЗрдбрд░ рдореМрдЬреВрдж рд╣реЛрддрд╛ рд╣реИ (рдЬреЛ рд╕рд╛рдорд╛рдиреНрдпрддрдГ рд╡реЗрдмрд╕реНрдХреЗрдЯ рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреЗ рд╕рд╛рде рджреЗрдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ), рддреЛ рд░рд┐рд╡рд░реНрд╕ **рдкреНрд░реЙрдХреНрд╕реА рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЗ рдмреАрдЪ рдПрдХ рд╕реНрдерд╛рдпреА рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рдП рд░рдЦрддрд╛ рд╣реИ**, рдЬреЛ рдХреБрдЫ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд╢реНрдпрдХ рдирд┐рд░рдВрддрд░ рд╡рд┐рдирд┐рдордп рдХреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рддрд╛ рд╣реИред H2C рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреЗ рд▓рд┐рдП, RFC рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреАрди рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реЗрдбрд░реЛрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реИ: ``` Upgrade: h2c HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA Connection: Upgrade, HTTP2-Settings ``` The vulnerability arises when, after upgrading a connection, the reverse proxy ceases to manage individual requests, assuming its job of routing is complete post-connection establishment. Exploiting H2C Smuggling allows for circumvention of reverse proxy rules applied during request processing, such as path-based routing, authentication, and WAF processing, assuming an H2C connection is successfully initiated. #### Vulnerable Proxies The vulnerability is contingent on the reverse proxy's handling of `Upgrade` and sometimes `Connection` headers. The following proxies inherently forward these headers during proxy-pass, thereby inherently enabling H2C smuggling: * HAProxy * Traefik * Nuster Conversely, these services do not inherently forward both headers during proxy-pass. However, they may be configured insecurely, allowing unfiltered forwarding of `Upgrade` and `Connection` headers: * AWS ALB/CLB * NGINX * Apache * Squid * Varnish * Kong * Envoy * Apache Traffic Server #### Exploitation It's crucial to note that not all servers inherently forward the headers required for a compliant H2C connection upgrade. As such, servers like AWS ALB/CLB, NGINX, and Apache Traffic Server, among others, naturally block H2C connections. Nonetheless, it's worth testing with the non-compliant `Connection: Upgrade` variant, which excludes the `HTTP2-Settings` value from the `Connection` header, as some backends may not conform to the standards. {% hint style="danger" %} Irrespective of the specific **path** designated in the `proxy_pass` URL (e.g., `http://backend:9999/socket.io`), the established connection defaults to `http://backend:9999`. This allows for interaction with any path within that internal endpoint, leveraging this technique. Consequently, the specification of a path in the `proxy_pass` URL does not restrict access. {% endhint %} The tools [**h2csmuggler by BishopFox**](https://github.com/BishopFox/h2csmuggler) and [**h2csmuggler by assetnote**](https://github.com/assetnote/h2csmuggler) facilitate attempts to **circumvent proxy-imposed protections** by establishing an H2C connection, thereby enabling access to resources shielded by the proxy. For additional information on this vulnerability, particularly concerning NGINX, refer to [**this detailed resource**](../network-services-pentesting/pentesting-web/nginx.md#proxy\_set\_header-upgrade-and-connection). ## Websocket Smuggling Websocket smuggling, unlike creating a HTTP2 tunnel to an endpoint accessible via a proxy, establishes a Websocket tunnel to bypass potential proxy limitations and facilitate direct communication with the endpoint. ### Scenario 1 In this scenario, a backend that offers a public WebSocket API alongside an inaccessible internal REST API is targeted by a malicious client seeking access to the internal REST API. The attack unfolds in several steps: 1. The client initiates by sending an Upgrade request to the reverse proxy with an incorrect `Sec-WebSocket-Version` protocol version in the header. The proxy, failing to validate the `Sec-WebSocket-Version` header, believes the Upgrade request to be valid and forwards it to the backend. 2. The backend responds with a status code `426`, indicating the incorrect protocol version in the `Sec-WebSocket-Version` header. The reverse proxy, overlooking the backend's response status, assumes readiness for WebSocket communication and relays the response to the client. 3. Consequently, the reverse proxy is misled into believing a WebSocket connection has been established between the client and backend, while in reality, the backend had rejected the Upgrade request. Despite this, the proxy maintains an open TCP or TLS connection between the client and backend, allowing the client unrestricted access to the private REST API through this connection. Affected reverse proxies include Varnish, which declined to address the issue, and Envoy proxy version 1.8.0 or older, with later versions having altered the upgrade mechanism. Other proxies may also be susceptible. ![https://github.com/0ang3el/websocket-smuggle/raw/master/img/2-4.png](https://github.com/0ang3el/websocket-smuggle/raw/master/img/2-4.png) ### Scenario 2 This scenario involves a backend with both a public WebSocket API and a public REST API for health checking, along with an inaccessible internal REST API. The attack, more complex, involves the following steps: 1. The client sends a POST request to trigger the health check API, including an additional HTTP header `Upgrade: websocket`. NGINX, serving as the reverse proxy, interprets this as a standard Upgrade request based solely on the `Upgrade` header, neglecting the request's other aspects, and forwards it to the backend. 2. The backend executes the health check API, reaching out to an external resource controlled by the attacker that returns a HTTP response with status code `101`. This response, once received by the backend and forwarded to NGINX, deceives the proxy into thinking a WebSocket connection has been established due to its validation of only the status code. ![https://github.com/0ang3el/websocket-smuggle/raw/master/img/3-4.png](https://github.com/0ang3el/websocket-smuggle/raw/master/img/3-4.png) > **Warning:** This technique's complexity increases as it requires the ability to interact with an endpoint capable of returning a status code 101. Ultimately, NGINX is tricked into believing a WebSocket connection exists between the client and the backend. In reality, no such connection exists; the health check REST API was the target. Nevertheless, the reverse proxy maintains the connection open, enabling the client to access the private REST API through it. ![https://github.com/0ang3el/websocket-smuggle/raw/master/img/3-5.png](https://github.com/0ang3el/websocket-smuggle/raw/master/img/3-5.png) Most reverse proxies are vulnerable to this scenario, but exploitation is contingent upon the presence of an external SSRF vulnerability, typically regarded as a low-severity issue. #### Labs Check the labs to test both scenarios in [https://github.com/0ang3el/websocket-smuggle.git](https://github.com/0ang3el/websocket-smuggle.git) ### References * [https://blog.assetnote.io/2021/03/18/h2c-smuggling/](https://blog.assetnote.io/2021/03/18/h2c-smuggling/) * [https://bishopfox.com/blog/h2c-smuggling-request](https://bishopfox.com/blog/h2c-smuggling-request) * [https://github.com/0ang3el/websocket-smuggle.git](https://github.com/0ang3el/websocket-smuggle.git) {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** ЁЯТм [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** ЁЯРж [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}