- Batas hak istimewa WebUI Chromium, fitur pengujian kebijakan enterprise, dan cacat pada API ekstensi DevTools saling terhubung, sehingga ekstensi Chrome berbahaya dapat mencapai eksekusi perintah shell hanya dengan sedikit interaksi pengguna
- Jalur serangan memanggil API pengujian kebijakan yang tidak terdokumentasi di
chrome://policyuntuk mengubah kebijakan pengguna, lalu menyalahgunakan jalur dan argumen browser alternatif milik Browser Switcher sebagai perintah shell chrome.devtools.inspectedWindow.reload()mengizinkan eksekusiinjectedScript, dan karena keterlambatan pemblokiran akses saat navigasi WebUI atau permintaanPage.reloadyang tertinggal setelah crash, kode dapat dijalankan di WebUI yang memiliki hak istimewa- Google mengklasifikasikan kerentanan ini sebagai P1/S1 dan menambahkan validasi
loaderIdpadaPage.reload, pemeriksaan URL padainspectedWindow.reload(), serta pemeriksaan aktivasi pengujian kebijakan pada handler WebUI - Kerentanan terkait diberi CVE-2024-5836 dan CVE-2024-6778, keduanya mendapat CVSS 8.8 High, dan hadiah akhirnya adalah $20,000
Batas WebUI Chromium dan sandbox
- Chromium menjalankan kode yang tidak tepercaya di dalam sandbox, dan JavaScript dari ekstensi Chrome juga seharusnya hanya berjalan dalam izin yang diberikan dan API yang dapat diakses
- Hanya dengan izin ekstensi pun data login atau riwayat peramban bisa dicuri, tetapi secara prinsip dampaknya seharusnya tetap terbatas di dalam browser
- Sebagian GUI Chromium diimplementasikan sebagai WebUI seperti
chrome://settingsdanchrome://history- WebUI ditulis dengan HTML, CSS, dan JavaScript, tetapi karena harus menampilkan dan mengubah informasi internal browser, ia memiliki hak istimewa lebih tinggi daripada halaman web biasa
- JavaScript frontend WebUI dapat berkomunikasi dengan kode C++ native browser melalui API privat
- Jika eksekusi kode dimungkinkan di WebUI, itu dapat berujung pada bypass sandbox Chromium, sehingga penting mencegah penyerang menjalankan JavaScript tak tepercaya di halaman
chrome:// - Sebagai contoh, jika item unduhan
.exedichrome://downloadsdiklik, file executable bisa dibuka, sehingga Chromium memeriksa apakah tindakan membuka file benar-benar berasal dari input pengguna nyata
Bypass pada fitur pengujian kebijakan enterprise
- Penelusuran kerentanan dimulai dari enterprise policy system milik Chromium
- Sistem ini memungkinkan admin memaksakan pengaturan tertentu pada perangkat milik perusahaan atau sekolah
- Kebijakan biasanya terikat ke akun Google dan diunduh dari server administrasi Google
- Kebijakan dibagi menjadi device policies dan user policies
- device policies mengelola pengaturan seluruh perangkat Chrome OS
- user policies diterapkan pada pengguna tertentu atau instance browser tertentu dan tersedia di semua platform
- Di Linux, user policies dapat diterapkan ke instance Google Chrome dengan menaruh file JSON di
/etc/opt/chrome/policies, tetapi menulis ke direktori ini memerlukan hak root
- Kebijakan yang sedang diterapkan pada perangkat saat ini dapat dilihat di WebUI
chrome://policy- Halaman ini menyediakan daftar kebijakan yang diterapkan, log layanan kebijakan, dan fitur ekspor JSON
- Normalnya tidak ada cara mengedit kebijakan dari halaman ini
- Catatan rilis Chrome Enterprise untuk Chrome v117 menyebut bahwa halaman
chrome://policy/testmengizinkan pengujian kebijakan pada kanal Beta, Dev, dan Canary- Fitur ini tidak disebut di dokumentasi Chromium selain catatan rilis tersebut
- Agar aktif secara normal, diperlukan kebijakan tak terdokumentasi
PolicyTestPageEnabled - Tanpa kebijakan ini,
chrome://policy/testakan diarahkan ulang kechrome://policy
Kegagalan validasi setLocalTestPolicies
- Kode JavaScript di
chrome://policy/testmenggunakansendWithPromise('setLocalTestPolicies', ...)untuk menetapkan kebijakan ujisendWithPromise()adalah wrapper untukchrome.send(), API privat WebUI- Panggilan ini mengirim permintaan ke fungsi handler C++, dan handler tersebut dapat melakukan operasi internal browser
- Saat
setLocalTestPoliciesdipanggil langsung dari konsolchrome://policy, browser awalnya crash, dan log menunjukkan bahwa array kebijakan diperlukan - Setelah format array kebijakan disesuaikan dan user policy seperti
AllowDinosaurEasterEggdikirimkan, kebijakan arbitrer ternyata dapat ditetapkan meski fitur itu tidak diaktifkan secara eksplisit - Handler
HandleSetLocalTestPoliciesdi sisi C++ hanya memeriksa keberadaanlocal_test_provider, dan tidak memeriksa apakah fitur pengujian kebijakan benar-benar diizinkan LocalTestPolicyProvider::CreateIfAllowed()memanggilIsPolicyTestingEnabled(nullptr, channel)- Karena argumen pertama
pref_servicebernilainull, pemeriksaanPolicyTestPageEnableddilewati - Pemeriksaan yang tersisa hanya apakah release channel adalah
CANARYatauDEFAULT
- Karena argumen pertama
- Pada build Chromium tanpa branding, kode
GOOGLE_CHROME_BRANDINGtidak dikompilasi sehingga channel tetapUNKNOWN- Dalam enum,
UNKNOWN = 0danDEFAULT = UNKNOWN, sehingga pemeriksaan channel lolos pada Chromium dan build turunannya - Pada build stable Google Chrome yang diberi branding, release channel diatur dengan benar sehingga bug ini tidak bekerja di Google Chrome stable
- Dalam enum,
Eksekusi perintah shell lewat Browser Switcher
- Setelah kebijakan pengguna arbitrer dapat ditetapkan, modul kebijakan enterprise Chrome Legacy Browser Support menjadi jalur pelarian sandbox
- Legacy Browser Support juga dikenal sebagai Browser Switcher, dan dirancang untuk menjalankan browser alternatif ketika pengguna mengunjungi URL tertentu dari Chromium
- Fitur ini dibuat untuk mendukung pengguna Internet Explorer
- Perilakunya dikendalikan oleh kebijakan
- Dengan menggabungkan kebijakan
AlternativeBrowserPathdanAlternativeBrowserParameters, Chromium dapat menjalankan perintah shell arbitrer sebagai “browser alternatif”- Kebijakan Browser Switcher ini hanya ada di Linux, macOS, dan Windows
- Contoh alurnya sebagai berikut
- Setel
BrowserSwitcherEnabledketrue - Masukkan
example.comkeBrowserSwitcherUrlList - Setel
AlternativeBrowserPathke/bin/bashdi Linux - Setel
AlternativeBrowserParametersmenjadi seperti["-c", "xcalc # ${url}"]
- Setel
- Saat browser bernavigasi ke
example.com, Browser Switcher aktif dan perintah seperti/bin/bash -c 'xcalc # https://example.com'dijalankan- Nilai substitusi
${url}ditempatkan setelah#agar diperlakukan sebagai komentar shell
- Nilai substitusi
- Setelah menetapkan kebijakan di
chrome://policy, memanggilwindow.open("https://example.com")saja sudah cukup untuk berlanjut ke eksekusi perintah shell arbitrer lewat JavaScript
Jalur bypass melalui API ekstensi DevTools
- Dengan langkah sebelumnya saja, korban masih harus menempelkan kode berbahaya ke konsol browser di
chrome://policy, sehingga kurang praktis - Jalur eksekusi otomatis kemudian ditemukan melalui ekstensi Chrome berbahaya
- Ekstensi dapat menyisipkan JavaScript ke halaman, tetapi seharusnya tidak bisa menjalankan JavaScript di halaman WebUI yang memiliki hak istimewa
- Ada empat API utama yang dipakai ekstensi untuk menjalankan JavaScript di halaman
chrome.scriptingchrome.tabspada Manifest v2chrome.debuggerchrome.devtools.inspectedWindow
- Target penyelidikan adalah
chrome.devtools.inspectedWindow, yang diperkirakan relatif kurang diperkuat- Ekstensi yang menggunakan API
chrome.devtoolsharus memiliki fielddevtools_pagedi manifest - Saat pengguna membuka DevTools, halaman tersebut dimuat sebagai iframe dan API
chrome.devtoolsdapat digunakan di dalamnya
- Ekstensi yang menggunakan API
- Laporan bug sebelumnya dari David Erceg sudah menunjukkan kasus mencapai eksekusi kode di WebUI melalui
chrome.devtools.inspectedWindow.eval()- Normalnya, jika halaman yang diperiksa bernavigasi ke WebUI, penggunaan API DevTools harus dinonaktifkan
- Inti bypass-nya adalah mengirim permintaan eval sebelum Chrome menonaktifkan API, lalu membuat permintaan itu sampai ke halaman WebUI
inspectedWindow.reload() dan kekhususan about:blank
chrome.devtools.inspectedWindow.reload()juga dapat menjalankan JavaScript di halaman yang diperiksa jika argumeninjectedScriptdiberikan- Saat
inspectedWindow.reload()dipanggil pada halamanabout:blankyang dibuka oleh WebUI, JavaScript dapat dijalankan pada halaman yang memiliki hak istimewaabout:blanksendiri bukan URL yang istimewa, tetapi mewarisi hak istimewa dan origin dari halaman yang membukanyaabout:blankyang dibuka olehchrome://settingsmenjadi halaman ber-originchrome://settingsyang memiliki hak istimewa
- Kode penonaktifan API DevTools hanya memeriksa URL target inspeksi, bukan origin-nya
- Jadi meski URL terlihat biasa, origin-nya bisa saja origin yang memiliki hak istimewa
- Jalur
about:blanksaja sulit langsung dipakai dalam rantai exploit karenachrome://policytidak membuka popupabout:blank - Namun
inspectedWindow.reload()tetap bisa menjalankan JavaScript dichrome://settingsbahkan dalam situasi ketikainspectedWindow.eval()gagal- Ini menunjukkan
eval()punya pemeriksaan internal sendiri yang setara dengan pemeriksaan origin, sedangkanreload()tidak memiliki tingkat pemeriksaan yang sama
- Ini menunjukkan
Menstabilkan dari race condition ke metode berbasis crash
- Rantai exploit pertama mengulang panggilan
inspectedWindow.reload()untuk membidik jendela waktu singkat setelah halaman yang diperiksa bernavigasi ke WebUI tetapi sebelum halaman DevTools menonaktifkan API- Ini bergantung pada fakta bahwa halaman yang diperiksa dan halaman DevTools berada di proses yang berbeda
- Jika permintaan
reload()masuk di antara saat navigasi kechrome://policydan penonaktifan API DevTools, kode dapat dieksekusi di WebUI
- Metode ini berhasil, tetapi reliabilitasnya rendah
- Setelah penyesuaian, tingkat keberhasilannya sekitar 70%
- Meskipun kerentanannya serius, ketidakstabilan ini dapat menurunkan severity
- Selanjutnya diuji apakah, seperti pendekatan lama David Erceg, perilaku permintaan debugger yang tertinggal setelah tab crash juga bisa diterapkan ke
inspectedWindow.reload() - Jika pernyataan
debuggerdipicu dua kali berturut-turut, tab akan crash, dan permintaanPage.reloaddapat tertinggal di antrean lalu dieksekusi setelah berpindah ke WebUI- Cara ini menghilangkan kebutuhan race condition sehingga bekerja 100% reliable
- Pada patch bug sebelumnya, Google memperbaiki penghapusan pending debugger requests setelah crash, tetapi permintaan
Page.reloaddibiarkan sebagai pengecualianinspectedWindow.reload()secara internal mengirim permintaanPage.reload, sehingga terkena dampak pengecualian ini- Patch saat itu tidak mencegah fakta bahwa
Page.reloadbisa menjalankan skrip
- Crash tab juga bisa dipicu dengan metode kehabisan memori selain pendekatan
debugger, tetapi PoC akhir memakai crash viadebuggeryang lebih cepat
Rantai exploit akhir dan interaksi pengguna
- PoC akhir bekerja dengan urutan berikut
- Menggunakan kerentanan
chrome.devtools.inspectedWindow.reload()untuk menjalankan payload JavaScript dichrome://policy - Payload memanggil
sendWithPromise("setLocalTestPolicies", policy)untuk menetapkan kebijakan pengguna - Menetapkan
BrowserSwitcherEnabled,BrowserSwitcherUrlList,AlternativeBrowserPath, danAlternativeBrowserParameters - Memicu Browser Switcher melalui
window.open()atau navigasi halaman untuk menjalankan perintah shell
- Menggunakan kerentanan
- PoC menggunakan perintah menjalankan kalkulator sesuai OS
- Windows:
C:\Windows\System32\cmd.exedancalc.exe - Linux:
/bin/bashdanxcalc - macOS:
/bin/bashdanopen -na Calculator
- Windows:
- Interaksi pengguna yang diperlukan hanya sebatas membuat mereka membuka DevTools
- Tulisan “extension install error” pada layar contoh dipakai untuk menipu pengguna agar membuka DevTools
- Begitu DevTools dibuka, rantai yang mengarah ke sandbox escape dimulai
Perbaikan Google dan penetapan CVE
- Setelah laporan masuk, Google segera memverifikasi kerentanan ini dan mengklasifikasikannya sebagai P1/S1
- P1/S1 berarti prioritas tinggi dan severity tinggi
- Dalam beberapa minggu berikutnya, tiga perbaikan utama diterapkan
Menambahkan argumen loaderIdpada perintahPage.reloaddan pemeriksaanloaderIDdi sisi renderer- Ini memastikan perintah hanya berlaku untuk satu origin dan tidak tetap bekerja jika tanpa sengaja sampai ke halaman yang memiliki hak istimewa
- Pemeriksaan URL pada fungsi
inspectedWindow.reload()- Sehingga tidak lagi hanya bergantung pada pencabutan akses API ekstensi
- Pemeriksaan apakah pengujian kebijakan diaktifkan pada handler WebUI
- Ini memastikan kebijakan uji benar-benar diblokir
- Kerentanan terkait race condition diberi CVE-2024-5836
- Skor severity CVSS-nya adalah 8.8 High
- Kerentanan terkait crash pada halaman yang diperiksa diberi CVE-2024-6778
- Kerentanan ini juga mendapat skor CVSS 8.8
- Setelah perbaikan digabungkan ke branch rilis, panel Chrome VRP menentukan hadiah, dan hadiah akhirnya adalah $20,000
Jadwal publikasi dan materi
- Timeline-nya adalah sebagai berikut
- 16 April: bug test policies ditemukan
- 29 April: bug race condition
inspectedWindow.reload()ditemukan - 1 Mei: bug dilaporkan ke Google
- 4 Mei: Google mengklasifikasikannya sebagai P1/S1
- 5 Mei: bug terkait crash halaman yang diperiksa ditemukan dan laporan diperbarui
- 6 Mei: Google meminta laporan bug terpisah untuk tiap bagian dari chain
- 8 Juli: laporan bug ditandai fixed
- 13 Juli: diteruskan ke panel Chrome VRP untuk penentuan hadiah
- 17 Juli: panel VRP menetapkan hadiah $20,000
- 15 Oktober: seluruh laporan bug dipublikasikan
- Laporan bug asli terkait dapat dilihat di crbug.com/338248595
- PoC untuk tiap bagian kerentanan dipublikasikan di repositori GitHub
- Bug
inspectedWindow.reloadbekerja hingga Chrome v45 - Jika fitur yang tidak terdokumentasi, belum matang, dan tidak aman dirilis ke semua pengguna, kesalahan-kesalahan sederhana dapat saling berpadu dan berujung pada kerentanan dengan tingkat keparahan tinggi
1 komentar
Komentar di Hacker News
URL halaman diganti menjadi
${url}, dan disebutkan bahwa jika diletakkan setelah#agar tidak merusak perintah, itu akan menjadi komentar. Tapi apakah di kebijakan ini ada semacam logika validasi bahwa URL harus diteruskan ke suatu tempat diAlternativeBrowserParameters?Seorang siswa SMA yang tertarik pada pemrograman, pengembangan web, dan keamanan siber—benar-benar mengesankan
Etika profesionalnya juga hebat karena mengikuti proses pengungkapan yang bertanggung jawab, dan tampaknya akan menjadi orang besar ke depannya
Tulisan dan pekerjaannya luar biasa, dan rasanya seperti ikut mengikuti proses ketika kegembiraan makin menumpuk seiring berlanjutnya penemuan
Ia juga sangat pantas mendapatkan imbalan yang memadai
Rangkaian eksploitasi kerentanannya rapi dan tulisannya juga bagus. Saya juga suka bagaimana ia memecah dan menunjukkan cara kerja kode yang rentan
Trik sederhana seperti “tekan F12 untuk mencoba lagi” selalu membuat saya kagum setiap kali melihatnya, benar-benar penuh keisengan
Ini mengingatkan saya pada kejadian dulu ketika saya men-debug shell
croshdi Chrome OS dengan API yang sama untuk melewati perlindungan OS dan bahkan mendapatkan akses root pada perangkat developer. Itu adalah CVE-2014-3172Namun penulis artikel ini harus melewati rintangan yang jauh lebih sulit, dan ini benar-benar pekerjaan yang hebat
Karena sudah terlalu larut malam, sulit untuk menggali lebih dalam apa yang rusak pada validasi WebUI, tetapi saya suka bahwa ia mengusutnya sampai tuntas dan menemukan penyebabnya
Mencurigai dan tidak memercayai toolchain dari hal-hal yang kita deploy adalah sikap yang cukup standar, tetapi pada saat yang sama kita terlalu memercayai alat pengembangan yang nyaman bak sihir dari perusahaan besar seperti Google atau Microsoft. Pada akhirnya, itu karena saya ingin menulis dan menguji kode saya sendiri, alih-alih mengkhawatirkan apa yang tersembunyi di dalam Chromium atau VSCode
Ini salah satu tulisan terbaik yang pernah saya baca
Benar-benar pekerjaan pelacakan yang cerdik
Upaya menggali kode browser sampai menemukan hal ini luar biasa, dan tulisannya juga sangat menarik serta mendetail
Masih siswa SMA, wow, benar-benar hebat
Proyek Chromium menghapus
chrome://net-internalsdengan alasan terlalu rumit, lalu menambahkanchrome://policydengan dukungan pengeditan JSON yang setengah matang