Table of contents
Open Table of contents
H2C Smuggling
HTTP2 Over Cleartext (H2C)
H2C, atau http2 over cleartext, menyimpang dari norma koneksi HTTP sementara dengan meng-upgrade koneksi HTTP standar menjadi koneksi yang persisten. Koneksi yang di-upgrade ini menggunakan protokol biner http2 untuk komunikasi yang berkelanjutan, berbeda dengan sifat permintaan tunggal dari HTTP teks biasa.
Inti dari masalah smuggling muncul dengan penggunaan reverse proxy. Biasanya, reverse proxy memproses dan meneruskan permintaan HTTP ke backend, lalu mengembalikan respons dari backend setelah itu. Namun, ketika header Connection: Upgrade
ada dalam permintaan HTTP (biasanya terlihat pada koneksi websocket), reverse proxy mempertahankan koneksi persisten antara klien dan server, memfasilitasi pertukaran yang berkelanjutan yang diperlukan oleh beberapa protokol. Untuk koneksi H2C, ketaatan terhadap RFC memerlukan keberadaan tiga header spesifik:
Upgrade: h2c
HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
Connection: Upgrade, HTTP2-Settings
Kerentanannya muncul ketika, setelah meng-upgrade koneksi, reverse proxy berhenti mengelola permintaan individu, menganggap tugasnya dalam merutekan sudah selesai setelah koneksi terbentuk. Mengeksploitasi H2C Smuggling memungkinkan untuk menghindari aturan-aturan reverse proxy yang diterapkan selama pemrosesan permintaan, seperti routing berbasis path, otentikasi, dan pemrosesan WAF, dengan asumsi koneksi H2C berhasil diinisiasi.
Vulnerable Proxies
Kerentanannya bergantung pada cara reverse proxy menangani header Upgrade
dan kadang Connection
. Proxy berikut secara inheren meneruskan header-header ini selama proxy-pass, sehingga memungkinkan H2C smuggling secara inheren:
- HAProxy
- Traefik
- Nuster
Sebaliknya, layanan-layanan ini tidak secara inheren meneruskan kedua header tersebut selama proxy-pass. Namun, mereka dapat dikonfigurasi dengan tidak aman, memungkinkan penerusan header Upgrade
dan Connection
yang tidak difilter:
- AWS ALB/CLB
- NGINX
- Apache
- Squid
- Varnish
- Kong
- Envoy
- Apache Traffic Server
Exploitation
Penting untuk dicatat bahwa tidak semua server secara inheren meneruskan header yang diperlukan untuk upgrade koneksi H2C yang sesuai. Oleh karena itu, server seperti AWS ALB/CLB, NGINX, dan Apache Traffic Server, di antara lainnya, secara alami memblokir koneksi H2C. Namun, perlu dicoba dengan varian Connection: Upgrade
yang tidak sesuai, yang mengesampingkan nilai HTTP2-Settings
dari header Connection
, karena beberapa backend mungkin tidak mematuhi standar.
Terlepas dari path spesifik yang ditentukan dalam URL proxy_pass
(misalnya, http://backend:9999/socket.io
), koneksi yang terbentuk akan default ke http://backend:9999
. Ini memungkinkan interaksi dengan path apapun dalam endpoint internal tersebut, memanfaatkan teknik ini. Akibatnya, penentuan path dalam URL proxy_pass
tidak membatasi akses.
Alat h2csmuggler oleh BishopFox dan h2csmuggler oleh assetnote memfasilitasi upaya untuk menghindari perlindungan yang diterapkan oleh proxy dengan membentuk koneksi H2C, sehingga memungkinkan akses ke sumber daya yang dilindungi oleh proxy.
Websocket Smuggling
Websocket smuggling, tidak seperti membuat terowongan HTTP2 ke endpoint yang dapat diakses melalui proxy, membentuk terowongan Websocket untuk menghindari pembatasan proxy potensial dan memfasilitasi komunikasi langsung dengan endpoint.
Scenario 1
Dalam skenario ini, sebuah backend yang menawarkan API WebSocket publik bersamaan dengan API REST internal yang tidak dapat diakses menjadi sasaran klien jahat yang ingin mengakses API REST internal. Serangan ini terjadi dalam beberapa langkah:
- Klien memulai dengan mengirimkan permintaan Upgrade ke reverse proxy dengan versi protokol
Sec-WebSocket-Version
yang salah di header. Proxy, yang gagal memvalidasi headerSec-WebSocket-Version
, menganggap permintaan Upgrade valid dan meneruskannya ke backend. - Backend merespons dengan kode status
426
, yang menunjukkan versi protokol yang salah di headerSec-WebSocket-Version
. Reverse proxy, yang mengabaikan status respons dari backend, menganggap siap untuk komunikasi WebSocket dan meneruskan respons tersebut ke klien. - Akibatnya, reverse proxy tertipu untuk menganggap bahwa koneksi WebSocket telah terjalin antara klien dan backend, padahal sebenarnya backend telah menolak permintaan Upgrade. Meskipun demikian, proxy mempertahankan koneksi TCP atau TLS yang terbuka antara klien dan backend, memungkinkan klien mengakses API REST pribadi tanpa batasan melalui koneksi ini.
Reverse proxy yang terpengaruh termasuk Varnish, yang menolak untuk menangani masalah ini, dan Envoy proxy versi 1.8.0 atau yang lebih lama, dengan versi yang lebih baru telah mengubah mekanisme upgrade. Proxy lainnya juga bisa rentan.
Scenario 2
Skenario ini melibatkan sebuah backend dengan API WebSocket publik dan API REST publik untuk pemeriksaan kesehatan, bersama dengan API REST internal yang tidak dapat diakses. Serangan ini, yang lebih kompleks, melibatkan langkah-langkah berikut:
- Klien mengirimkan permintaan POST untuk memicu API pemeriksaan kesehatan, termasuk header HTTP tambahan
Upgrade: websocket
. NGINX, yang bertindak sebagai reverse proxy, menafsirkan ini sebagai permintaan Upgrade standar hanya berdasarkan headerUpgrade
, mengabaikan aspek lainnya dari permintaan tersebut, dan meneruskannya ke backend. - Backend mengeksekusi API pemeriksaan kesehatan, menghubungi sumber daya eksternal yang dikendalikan oleh penyerang yang mengembalikan respons HTTP dengan kode status
101
. Respons ini, setelah diterima oleh backend dan diteruskan ke NGINX, menipu proxy untuk berpikir bahwa koneksi WebSocket telah terjalin karena hanya memvalidasi kode status tersebut.
Peringatan: Kompleksitas teknik ini meningkat karena memerlukan kemampuan untuk berinteraksi dengan endpoint yang dapat mengembalikan kode status 101.
Akhirnya, NGINX tertipu untuk percaya bahwa koneksi WebSocket ada antara klien dan backend. Padahal, tidak ada koneksi semacam itu; API REST pemeriksaan kesehatan adalah targetnya. Meskipun demikian, reverse proxy tetap mempertahankan koneksi terbuka, memungkinkan klien mengakses API REST pribadi melalui koneksi tersebut.
Sebagian besar reverse proxy rentan terhadap skenario ini, namun eksploitasi bergantung pada keberadaan kerentanannya di SSRF eksternal, yang biasanya dianggap sebagai masalah dengan tingkat keparahan rendah.
Labs
Cek lab untuk menguji kedua skenario di https://github.com/0ang3el/websocket-smuggle.git