Jika Anda memakai iTerm2, "cat readme.txt" pun tidak aman
(blog.calif.io)- Integrasi SSH menggunakan escape sequence terminal untuk berkomunikasi dengan shell jarak jauh, dan karena struktur ini, output terminal biasa pun bisa ditafsirkan seperti protokol conductor
- Masalah intinya adalah kegagalan kepercayaan: bukan hanya conductor jarak jauh yang sebenarnya, tetapi juga file berbahaya, banner, MOTD, dan respons server dapat bertindak seolah-olah conductor melalui
DCS 2000pdanOSC 135palsu - Hanya dengan menjalankan
cat readme.txt, jika transcript conductor palsu dirender maka iTerm2 akan melanjutkan sendiri alurgetshell·pythonversion·run(...), dan output serangan cukup menyamar sebagai respons - Eksploit ini memanfaatkan kebingungan ketika perintah base64 yang ditulis ke PTY, saat conductor SSH yang sebenarnya tidak ada, justru jatuh menjadi input plaintext ke shell lokal; eksekusi menjadi mungkin ketika chunk terakhir ditafsirkan sebagai jalur
ace/c+aliFIo - Perbaikannya sudah masuk dalam commit 31 Maret
a9e745993c2e2cbb30b884a16617cd5495899f86, tetapi pada saat dipublikasikan belum masuk stable release, sehingga muncul celah perlindungan sebelum patch tersebar
Latar belakang integrasi SSH di iTerm2
- iTerm2 SSH integration adalah fitur untuk memahami sesi jarak jauh dengan lebih kaya, dan bekerja dengan cara menaruh skrip helper kecil bernama conductor di shell jarak jauh
- Memulai integrasi SSH melalui
it2ssh - Mengirim conductor, skrip bootstrap jarak jauh, melalui sesi SSH yang sudah ada
- Skrip jarak jauh ini menjalankan peran lawan bicara untuk protokol iTerm2
- Memulai integrasi SSH melalui
- iTerm2 dan conductor jarak jauh tidak berkomunikasi sebagai layanan jaringan biasa, melainkan saling bertukar escape sequence di atas terminal I/O
- Deteksi login shell
- Memeriksa keberadaan Python
- Mengganti direktori
- Mengunggah file
- Menjalankan perintah
Cara kerja PTY
- Emulator terminal modern adalah versi perangkat lunak dari terminal hardware lama, dan bertugas menangani output layar, input keyboard, serta interpretasi sequence kontrol terminal
- Shell dan program command-line masih mengharapkan perangkat yang terlihat seperti terminal sungguhan, sehingga OS menyediakan PTY
- PTY adalah pseudoterminal yang berada di antara emulator terminal dan proses foreground
- Dalam sesi SSH biasa, iTerm2 menulis byte ke PTY, lalu proses foreground
sshmeneruskannya ke mesin jarak jauh, dan conductor jarak jauh membacanya dari stdin - Saat iTerm2 mengirim perintah ke conductor jarak jauh, di sisi lokal pada akhirnya ia menulis byte ke PTY
Protokol conductor
- Media transport untuk protokol integrasi SSH menggunakan terminal escape sequence
- Ada dua elemen inti
DCS 2000pdipakai untuk meng-hook SSH conductorOSC 135dipakai untuk pesan conductor pre-framer
- Di level source,
DCS 2000pmembuat iTerm2 membentuk conductor parser, lalu parser itu memproses pesanOSC 135sesudahnyabegin <id>- baris output perintah
end <id> <status> runhook
- Conductor jarak jauh yang normal bisa berkomunikasi dengan iTerm2 hanya melalui output terminal
Kerentanan inti
- Esensi kerentanannya adalah kegagalan kepercayaan: bahkan output terminal yang bukan sesi conductor tepercaya pun diterima iTerm2 sebagai protokol SSH conductor
- Akibatnya, output terminal yang tidak tepercaya bisa menyamar sebagai conductor jarak jauh
- file berbahaya
- respons server
- banner
- MOTD
- Input serangan dapat mencetak hook
DCS 2000ppalsu dan responsOSC 135palsu; bila ini terjadi, iTerm2 bertindak seolah pertukaran SSH integration yang sebenarnya sedang berlangsung
Cara kerja eksploit
- File eksploit berbentuk transcript conductor palsu
- Saat pengguna menjalankan
cat readme.txt, iTerm2 merender file tersebut, tetapi isinya bukan teks biasa melainkan mengandung elemen berikut- baris
DCS 2000ppalsu yang menandakan sesi conductor palsu - pesan
OSC 135palsu yang menjawab permintaan iTerm2
- baris
- Setelah hook diterima, iTerm2 memulai workflow conductor normal; pada source upstream,
Conductor.start()langsung mengirimgetshell(), lalu jika berhasil mengirimpythonversion() - Serangan tidak perlu menyuntikkan permintaan-permintaan itu; iTerm2 sendiri yang menerbitkan permintaan, dan output berbahaya cukup menyamar sebagai respons
Proses state machine
- Pesan
OSC 135palsu disusun minimal tetapi dalam urutan yang tepat- awal body perintah untuk
getshell - mengembalikan baris yang tampak seperti output deteksi shell
- mengakhiri perintah itu dengan status sukses
- awal body perintah untuk
pythonversion - mengakhiri perintah itu dengan status gagal
unhook
- awal body perintah untuk
- Hanya dengan alur ini, iTerm2 masuk ke jalur fallback normal, lalu menilai workflow SSH integration sudah cukup selesai dan melanjutkan ke tahap berikutnya
- Tahap berikutnya adalah menyusun dan mengirim perintah
run(...)
Peran sshargs
- Hook
DCS 2000ppalsu memuat beberapa field, dan salah satunya adalahsshargsyang dikendalikan penyerang - Nilai ini kemudian dipakai sebagai bahan penyusun perintah saat iTerm2 membangun permintaan
run ...untuk conductor - Eksploit memilih
sshargsagar ketika iTerm2 melakukan encoding base64 terhadap data berikutrun <padding><magic-bytes>
- chunk 128-byte terakhir menjadi
ace/c+aliFIo - String ini bukan nilai acak, tetapi dipilih agar sekaligus memenuhi dua syarat berikut
- output yang valid dari jalur encoding conductor
- nama path relatif yang valid
Kebingungan PTY yang memungkinkan eksploit
- Dalam sesi SSH integration normal, iTerm2 menulis perintah conductor yang telah di-encode base64 ke PTY, dan
sshmeneruskannya ke conductor jarak jauh - Dalam situasi eksploit, iTerm2 tetap menulis perintah ke PTY dengan cara yang sama, tetapi karena conductor SSH yang sebenarnya tidak ada, shell lokal justru menerimanya sebagai input plaintext
- Pada sesi yang direkam, terlihat bentuk berikut
getshellmuncul dalam bentuk base64pythonversionmuncul dalam bentuk base64- lalu payload
run ...panjang yang di-encode base64 muncul - chunk terakhir adalah
ace/c+aliFIo
- Chunk-chunk sebelumnya gagal sebagai perintah yang tidak bermakna, tetapi chunk terakhir akan berjalan bila path tersebut ada secara lokal dan dapat dieksekusi
Langkah reproduksi
- PoC asli berbasis file dapat direproduksi dengan
genpoc.pypython3 genpoc.pyunzip poc.zipcat readme.txt
- Prosedur ini menghasilkan dua file berikut
- skrip helper yang dapat dieksekusi bernama
ace/c+aliFIo readme.txtyang memuat sequenceDCS 2000pdanOSC 135berbahaya
- skrip helper yang dapat dieksekusi bernama
- File pertama memancing iTerm2 agar berkomunikasi dengan conductor palsu, dan file kedua menyediakan target yang benar-benar akan dijalankan shell saat chunk terakhir tiba
- Agar eksploit berhasil,
cat readme.txtharus dijalankan di direktori yang berisiace/c+aliFIo, sehingga chunk terakhir rancangan penyerang ditafsirkan sebagai path yang benar-benar bisa dieksekusi
Jadwal pengungkapan dan patch
- Bug dilaporkan ke iTerm2 pada 30 Maret
- Perbaikan selesai pada commit 31 Maret
a9e745993c2e2cbb30b884a16617cd5495899f86 - Pada saat penulisan, perbaikannya masih belum masuk stable release
- Setelah commit patch tersedia, dilakukan upaya untuk membangun ulang eksploit dari nol hanya berdasarkan patch itu
- Prompt untuk proses tersebut ada di
prompts.md - Hasilnya adalah
genpoc2.py - Cara kerjanya sangat mirip dengan
genpoc.py
- Prompt untuk proses tersebut ada di
Keberatan terhadap waktu pengungkapan
- Pengungkapan dilakukan sebelum perbaikan mencapai stable release, sehingga tercipta situasi di mana sebagian besar pengguna sulit benar-benar terlindungi saat kerentanan diumumkan
- Benturan soal waktu pengungkapan semacam ini memerlukan justifikasi yang jelas
- Dua minggu terlalu singkat untuk berharap distribusi yang bermakna, dan juga terlalu singkat untuk membenarkan bahwa pengungkapan dini perlu dilakukan demi memaksa respons
- Akibatnya, kerentanannya sudah diketahui luas, tetapi versi perbaikannya secara realistis masih belum tersedia bagi pengguna yang membutuhkannya, sehingga terbentuk masa jeda pengungkapan
- Pilihan yang lebih baik adalah menunggu sampai versi perbaikan benar-benar sampai ke tangan pengguna, atau setidaknya memberikan alasan yang jelas mengapa paparan dini diperlukan; namun keduanya tidak terpenuhi
1 komentar
Komentar Hacker News
Saya penasaran kenapa ini dipublikasikan sekarang padahal patch untuk rilis stabil belum keluar. Baru 18 hari sejak dilaporkan ke upstream, dan tulisan blognya jauh lebih rinci daripada commit yang dipublikasikan, jadi terasa meningkatkan kemungkinan eksploitasi nyata. Saya mengakui penulis memang bisa membuat exploit dengan bantuan LLM hanya dari commit upstream, tapi menurut saya tulisan ini tetap membuat kerentanan itu jauh lebih terlihat
Pekerjaan ini keren, tapi tidak terlalu mengejutkan. Ini masalah yang berulang pada aplikasi terminal yang kaya fitur, dan berbagai kerentanan serupa sudah diungkap berkali-kali selama 15 tahun terakhir. Alat seperti less atau vim juga bukan pengecualian, dan banyak masalah seperti ini lebih dekat ke bug logika daripada soal keamanan memori, jadi menulis ulang dengan Rust pun tidak otomatis menyelesaikannya. Di satu sisi kita ingin alat tingkat OS tetap sederhana dan bisa diprediksi, tetapi di sisi lain kita juga menginginkan warna yang cantik, animasi, dan kustomisasi tanpa akhir. Sekarang bahkan ada agen AI, jadi kita memasuki era ketika file teks berbahaya cukup berisi kalimat seperti "abaikan instruksi sebelumnya"
Ini mengingatkan saya pada era PDP-10. Seorang rekan menemukan bahwa jika backspace terus ditekan, handler terminal akan menghapus hingga karakter di depan buffer, lalu lebih jauh lagi dengan memakai karakter escape untuk menghapus satu baris penuh, sistem operasinya malah ikut hilang
Enam tahun lalu juga ada isu keamanan iTerm2 yang hampir sama
Saya adalah pembuat iTerm2. Masalah ini memang bisa dipakai sebagai salah satu mata rantai dalam rantai eksploitasi, tetapi menurut saya menyebutnya seolah-olah sangat berbahaya sendirian seperti di judul itu adalah berlebihan. Saya sedang liburan keluarga sekarang, dan setelah kembali saya akan merilis versi perbaikan
Saya tidak terlalu terkejut ada bug halus dalam sistem kompleks yang memanfaatkan bootstrap script, agen conductor jarak jauh, escape sequence, dan sebagainya. Saat komponen dipakai dengan cara yang tidak pernah dimaksudkan semula, masalah seperti ini mudah muncul. Saya memahaminya sebagai struktur yang memproses output tak tepercaya yang tampil di layar, seperti file teks atau banner server, tanpa memverifikasi asalnya meskipun output itu mengandung kode khusus
Ini terasa seperti cerita yang pernah saya lihat sebelumnya. SSH integration iTerm2 pernah menjadi penyebab CVE, dan saya juga teringat CVE-2025-22275. Sudah ada kasus-kasus sebelumnya, dan isu lama yang disebut di thread ini terkait integrasi tmux. Rasanya lebih baik fitur-fitur integrasi seperti ini tidak dimasukkan terlalu agresif
Judulnya terlalu sensasional. Masalahnya bukan pada cat, melainkan pada SSH integration iTerm, dan struktur saluran kontrol yang tidak dipisahkan dari aliran data tampak berbahaya. Kalau tidak memakai fitur ini dan hanya menggunakan SSH biasa, mestinya umumnya aman
Emulator terminal lama bahkan mengizinkan rebinding keyboard lewat escape code. Karena itu, untuk file yang tidak tepercaya, hampir menjadi pengetahuan umum bahwa Anda jangan
cat, melainkan buka dengan alat sepertilessUngkapan di artikelnya kurang akurat. Paragraf kedua terbaca seperti "kalau memakai iTerm2 maka tidak aman", padahal yang lebih tepat adalah masalah bisa muncul saat memakai fitur opsional Shell Integration. Jika fitur ini nonaktif secara default, saya memahami dampaknya akan terbatas. Kalau saya salah, saya ingin dikoreksi