2 puan yazan GN⁺ 12 일 전 | 1 yorum | WhatsApp'ta paylaş
  • SSH integration, uzak kabukla iletişim kurmak için terminal escape sequence'lerini kullanır ve bu yapı nedeniyle sıradan terminal çıktısı da conductor protokolü gibi yorumlanabilir
  • Temel sorun güvenin başarısız olmasıdır; gerçek bir uzak conductor yerine kötü amaçlı dosya, banner, MOTD veya sunucu yanıtı da sahte DCS 2000p ve OSC 135 aracılığıyla conductor gibi davranabilir
  • Yalnızca cat readme.txt komutunu çalıştırmak bile sahte bir conductor transcript'i render edilirse iTerm2'nin getshell·pythonversion·run(...) akışını kendi kendine yürütmesine yol açar; saldırı çıktısının tek yapması gereken yanıt veriyormuş gibi görünmektir
  • Exploit, PTY'ye yazılan base64 komutların gerçek bir SSH conductor olmadığında yerel kabuğun düz metin girdisine dönüşmesiyle oluşan karışıklıktan yararlanır; son parça ace/c+aliFIo yolu olarak yorumlandığında çalıştırma mümkün olur
  • Düzeltme 31 Mart tarihli a9e745993c2e2cbb30b884a16617cd5495899f86 commit'ine eklendi, ancak açıklama anı itibarıyla stable release'e dahil edilmemişti ve yama yaygınlaşmadan yapılan açıklama bir koruma boşluğu yarattı

iTerm2'nin SSH entegrasyonunun arka planı

  • iTerm2 SSH integration, uzak oturumu daha zengin biçimde anlayabilmek için tasarlanmış bir özelliktir ve uzak kabuğa conductor adlı küçük bir yardımcı betik yüklenerek çalışır
    • it2ssh ile SSH entegrasyonu başlatılır
    • Mevcut SSH oturumu üzerinden conductor adlı uzak bootstrap betiği aktarılır
    • Bu uzak betik iTerm2 protokolünün karşı tarafı olarak görev yapar
  • iTerm2 ile uzak conductor, tipik bir ağ servisi gibi değil, terminal I/O üzerinde escape sequence alışverişi yaparak iletişim kurar
    • login shell tespiti
    • Python varlığını kontrol etme
    • dizin değiştirme
    • dosya yükleme
    • komut çalıştırma

PTY nasıl çalışır

  • Modern terminal emülatörleri, geçmişteki donanım terminallerinin yazılım sürümüdür ve ekran çıktısı, klavye girdisi ile terminal kontrol dizilerini yorumlamaktan sorumludur
  • Kabuklar ve komut satırı programları hâlâ gerçek bir terminal gibi görünen bir aygıt beklediğinden, işletim sistemi PTY yapısını sağlar
    • PTY, terminal emülatörü ile ön plandaki süreç arasında yer alan bir pseudoterminal'dir
  • Tipik bir SSH oturumunda iTerm2 baytları PTY'ye yazar, ön plandaki süreç olan ssh bunları uzak makineye iletir ve uzak conductor bunları stdin'den okur
  • iTerm2 uzak conductor'a komut gönderdiğinde, yerelde sonuçta yaptığı şey PTY'ye bayt yazmaktır

conductor protokolü

  • SSH entegrasyon protokolünün taşıma mekanizması olarak terminal escape sequence'leri kullanılır
  • İki temel öğe vardır
    • DCS 2000p, SSH conductor'ı hook etmek için kullanılır
    • OSC 135, pre-framer conductor mesajları için kullanılır
  • Kaynak kod seviyesinde DCS 2000p, iTerm2'nin bir conductor parser oluşturmasına neden olur; ardından parser OSC 135 mesajlarını işler
    • begin <id>
    • komut çıktı satırları
    • end <id> <status> r
    • unhook
  • Normal bir uzak conductor, yalnızca terminal çıktısıyla iTerm2 ile iletişim kurabilir durumdadır

Temel zafiyet

  • Zafiyetin özü güvenin başarısız olmasıdır; iTerm2, güvenilir bir conductor oturumu olmayan terminal çıktısını da SSH conductor protokolü olarak kabul eder
  • Sonuç olarak güvenilmeyen terminal çıktısı uzak conductor kılığına girebilir
    • kötü amaçlı dosya
    • sunucu yanıtı
    • banner
    • MOTD
  • Saldırı girdisi sahte bir DCS 2000p hook'u ve sahte OSC 135 yanıtları üretebilir; bu durumda iTerm2 gerçek bir SSH integration alışverişi sürüyormuş gibi davranır

Exploit nasıl çalışıyor

  • Exploit dosyası, sahte bir conductor transcript'i içerir
  • Kullanıcı cat readme.txt çalıştırdığında iTerm2 dosyayı render eder, ancak dosya basit metin değil, şu öğeleri içerir
    • sahte bir conductor oturumunu bildiren sahte bir DCS 2000p satırı
    • iTerm2 isteklerine yanıt veren sahte OSC 135 mesajları
  • Hook kabul edildiğinde iTerm2 normal conductor iş akışını başlatır; yukarı akış kaynak kodunda Conductor.start() hemen getshell() gönderir ve başarılı olursa pythonversion() yollar
  • Saldırının bu istekleri enjekte etmesi gerekmez; iTerm2 istekleri kendisi üretir, kötü amaçlı çıktının ise yalnızca yanıtları taklit etmesi yeterlidir

Durum makinesinin ilerleyişi

  • Sahte OSC 135 mesajları asgari düzeydedir, ancak doğru sırada düzenlenmiştir
    • getshell için komut gövdesini başlatma
    • kabuk tespit çıktısı gibi görünen satırlar döndürme
    • ilgili komutu başarıyla sonlandırma
    • pythonversion için komut gövdesini başlatma
    • ilgili komutu başarısızlıkla sonlandırma
    • unhook
  • Yalnızca bu akış bile iTerm2'nin normal fallback yoluna girmesine neden olur; ardından SSH integration iş akışının yeterince tamamlandığı varsayılır ve sonraki adıma geçilir
  • Sonraki adım, run(...) komutunu oluşturup göndermektir

sshargs'ın rolü

  • Sahte DCS 2000p hook'u birden çok alan içerir ve bunlardan biri saldırganın kontrol ettiği sshargs değeridir
  • Bu değer daha sonra iTerm2 conductor için run ... isteğini oluştururken komut malzemesi olarak kullanılır
  • Exploit, iTerm2'nin şu veriyi base64 kodlaması için
    • run <padding><magic-bytes>
  • sshargs, son 128 baytlık parçanın ace/c+aliFIo olması sağlanacak şekilde seçilir
  • Bu dizge rastgele değildir; aynı anda şu iki koşulu karşılayacak şekilde seçilmiştir
    • conductor kodlama yolunun geçerli bir çıktısı olması
    • geçerli bir göreli yol adı olması

Exploit'i mümkün kılan PTY karışıklığı

  • Normal bir SSH integration oturumunda iTerm2, base64 kodlanmış conductor komutlarını PTY'ye yazar ve ssh bunları uzak conductor'a iletir
  • Exploit senaryosunda da iTerm2 aynı şekilde komutları PTY'ye yazar, ancak gerçek bir SSH conductor olmadığı için yerel kabuk bunları düz metin girdi olarak alır
  • Kaydedilmiş oturumda şu biçim gözlemlenir
    • getshell, base64 biçiminde görünür
    • pythonversion, base64 biçiminde görünür
    • ardından uzun, base64 kodlanmış bir run ... payload'u gelir
    • son parça ace/c+aliFIo olur
  • Önceki parçalar anlamsız komutlar olarak başarısız olur; son parça ise bu yol yerelde mevcut ve çalıştırılabilirse devreye girer

Yeniden üretim adımları

  • Orijinal dosya tabanlı PoC, genpoc.py ile yeniden üretilebilir
    • python3 genpoc.py
    • unzip poc.zip
    • cat readme.txt
  • Bu adımlar sonunda şu iki dosya oluşur
    • ace/c+aliFIo adlı çalıştırılabilir bir yardımcı betik
    • kötü amaçlı DCS 2000p ve OSC 135 dizilerini içeren readme.txt
  • İlk dosya iTerm2'yi sahte conductor ile iletişim kurmaya yönlendirir; ikinci dosya ise son parça ulaştığında kabuğun gerçekten çalıştıracağı hedefi sağlar
  • Exploit'in başarılı olması için cat readme.txt komutunun ace/c+aliFIo dosyasının bulunduğu dizinde çalıştırılması gerekir; ancak bu sayede son saldırgan kontrollü parça gerçek bir çalıştırılabilir yol olarak yorumlanabilir

Açıklama ve yama takvimi

  • 30 Mart'ta hata iTerm2'ye bildirildi
  • 31 Mart'ta düzeltme a9e745993c2e2cbb30b884a16617cd5495899f86 commit'inde tamamlandı
  • Yazım anı itibarıyla düzeltme henüz stable release'e dahil edilmemişti
  • Yama commit'i yayımlandıktan sonra, yalnızca yamaya dayanarak exploit'i sıfırdan yeniden kurma denemesi yapıldı
    • bu sürecin prompt'ları prompts.md içinde
    • sonuç genpoc2.py
    • genpoc.py ile çok benzer şekilde çalışır

Açıklama zamanlamasına yönelik eleştiri

  • Düzeltme stable release'e ulaşmadan yapılan açıklama, kullanıcıların büyük çoğunluğunun fiilen korunmasının zor olduğu bir durumda zafiyetin duyurulmasına yol açtı
  • Böyle bir açıklama zamanlaması için açık bir gerekçe gerekir
  • İki hafta, anlamlı bir yaygınlaştırma beklemek için de kısa; erken açıklamayı savunup müdahaleyi zorunlu kılmak için de kısa bir süredir
  • Sonuçta zafiyet geniş ölçüde bilinir hale gelirken, düzeltme pratikte ona ihtiyaç duyan kullanıcılara henüz ulaşmamış bir açıklama boşluğu dönemi oluştu
  • Daha iyi bir seçenek, düzeltmenin gerçekten kullanıcıların eline ulaşmasını beklemek ya da neden erken açıklamanın gerekli olduğunu net biçimde ortaya koymaktı; ancak ikisi de sağlanmadı

1 yorum

 
GN⁺ 12 일 전
Hacker News yorumları
  • Kararlı sürüm için yama henüz çıkmamışken bunun neden şimdi açıklandığını merak ettim. Upstream’e bildirilmesinin üzerinden yalnızca 18 gün geçmiş ve blog yazısı, yayımlanan commit’ten çok daha ayrıntılı olduğu için gerçek dünyada istismar olasılığını artırıyor gibi geldi. Yazarın, yalnızca upstream commit’e bakıp LLM kullanarak exploit üretebildiğini doğruladıktan sonra bile, bu yazının zafiyetin görünürlüğünü daha da artırdığını düşünüyorum

    • Ben zafiyeti bulan kişi değilim, blog yazarıyım. Yalnızca upstream commit ile de exploit üretilebiliyordu ve iTerm2 commit’lerini izleyen herkesin benzerini yapabileceğini düşünüyorum. Bu zafiyetin görünürlüğünü artırma niyetim vardı ve gerçekten de öyle oldu. iTerm2 yazarı başlangıçta bunun acil sürüm gerektirecek kadar ciddi olduğunu düşünmedi, ama şimdi yeniden değerlendirdiği bir hava var
    • Gerçek aktif istismar şüphesi varsa ya da düzeltme içeriği git commit’i gibi zaten açıksa ve bu da hızlı exploit geliştirmeyi mümkün kılıyorsa, açıklamayı ertelemenin istisnaları olmalı diye düşünüyorum. Böyle durumlarda topluluk çoğu zaman zafiyetin açıklanmasını tercih ediyor
    • Commit yayımlandığı anda sır artık bitmiş sayılır diye düşünüyorum. Gereksiz yere suskun kalmak sadece saldırganlara yardım eder ve savunma tarafının güvenliğini zayıflatır
    • Geleneksel açıklamayı erteleme süresi, yapay zeka yüzünden giderek anlamını yitirecek gibi görünüyor. Ucuz açık modeller bile zafiyet bulabiliyorsa, saldırganların da bunu zaten aynı şekilde bulduğunu varsaymak doğal olur
    • Bu bug’ın, benim güncelleme penceresini kısaltma savımı güçlendirdiğini hissediyorum. Çok karmaşık bug’ları önce Claude gibi güçlü modeller bulsa bile, yama git’e düştüğü anda daha küçük modeller de onları kolayca yeniden keşfedebiliyor. Önümüzdeki 1-2 yıl içinde commit’in yayımlanmasıyla gerçek port taraması arasındaki sürenin saatlere, hatta dakikalara inmesine şaşırmam. Bu açıdan kapalı SaaS daha avantajlı; çünkü değişiklikler görünmüyor ve dağıtımdan sonra fark edilse bile bunun pek pratik getirisi olmuyor
  • Bu çalışma etkileyici ama çok da şaşırtıcı değildi. Özellik açısından zengin terminal uygulamalarında tekrar tekrar görülen bir sorundu ve son 15 yılda benzer zafiyetler defalarca açıklandı. less ya da vim gibi araçlar da istisna değildi; bu tür sorunların önemli bir kısmı bellek güvenliğinden çok mantık hatasına daha yakın, yani Rust ile yeniden yazmak da bunları otomatik olarak çözmez. Bir yandan işletim sistemi düzeyindeki araçların sade ve öngörülebilir olmasını istiyoruz, ama öte yandan güzel renkler, animasyonlar ve bitmeyen özelleştirme de talep ediyoruz; burada bir gerilim var. Şimdi buna AI agent’lar da eklenince, kötü niyetli bir metin dosyasının sadece "önceki talimatları yok say" gibi bir ifade içermesinin yettiği bir döneme gelmiş olduk

    • iTerm2 sorunu, prompt injection, SQL injection ve XSS’in sonuçta aynı tür hata olduğunu düşünüyorum. Esas mesele, in-band veri ile out-of-band kontrol verisini aynı akışta birbirine karıştırmak. Bu örüntüyü bir tehlike işareti olarak görmeye başlarsak, kullanıcı içeriğinin yanına farkında olmadan kontrol komutları koyma ihtimalimiz azalır
    • Sorunun bir kısmı eski arayüzlerde olabilir diye düşünüyorum. In-band komut dizilerine dayanmayan modern bir terminal API’sine ihtiyaç var; GUI gibi programlanabilir ama eski usul basit uzak terminal kullanılabilirliğini de koruyan bir yön daha doğru geliyor
    • Claude Code gibi zengin terminal arayüzlerinde de benzer zafiyetler olup olmadığını merak ettim. Metin tabanlı terminal protokolünün üstüne özellikleri zorla yığmak yerine, baştan tipi ve semantiği net bir GUI protokolü olarak tasarlamak çözüm olabilir diye düşünüyorum. Böylece kullanıcı verisiyle çekirdek UI kodunun karışık biçimde yorumlanmasının önüne geçilebilir. Ama pratikte ekonomi nedeniyle yeni bir protokol getirmek yerine var olanı iyileştirmek daha sık tercih ediliyor
    • "Üzgünüm Dave, bunu yapmama izin veremem" türü bir HAL 9000 şakası aklıma geldi
    • Eskiden xterm’de de pencere başlığı escape code’unu kötüye kullanarak benzer saldırılar yapılabildiğini hatırlıyorum
  • PDP-10 döneminden bir hikâye aklıma geldi. Bir iş arkadaşı, backspace’e sürekli basıldığında terminal işleyicisinin tamponun baş tarafındaki karakterleri bile sildiğini keşfetmişti; sonra da bir satırın tamamını silen bir escape karakteri kullanınca işletim sistemi çöküyordu

    • Bunu duyunca Real Life Tron on an Apple IIgs aklıma geldi; sistem belleği yanlış yorumlandığında ortaya çıkan tuhaf bir çekiciliği var gibi geliyor
    • line-kill için control+u kullanmak nispeten yeni bir alışkanlık olabilir. Eskiden line-kill için @, erase için # kullanılırdı; bugün de sistemden sisteme tuş davranışları epey farklı hissediliyor
  • 6 yıl önce de neredeyse aynı iTerm2 güvenlik sorunu yaşanmıştı

    • O yüzden hiçbir şey öğrenilmemiş gibi görünüyor
  • Ben iTerm2’nin yazarıyım. Bu sorun bir exploit zincirinin halkalarından biri olarak kullanılabilir ama başlıktaki gibi tek başına çok büyük bir riskmiş gibi sunulmasını abartılı buluyorum. Şu an aile tatilindeyim; döndüğümde düzeltilmiş sürümü yayımlayacağım

    • Ben zafiyeti bulan kişi değil, blog yazarıyım. Düzeltilmiş sürüm çıkaracağınız için teşekkürler. Bu bug’ın sıradan ve zararsız görünen iş akışlarını bile etkileyebilmesine rağmen resmî bir sürüm olmamasına şaşırmıştım; ayrıca yama commit’i sorunu varsayımsal gibi anlattığı için durumun öyle olmadığını göstermek istemiştim. Düzeltilmiş sürüm çıkarılacak olması sevindirici
    • iTerm2’yi minnetle kullanıyorum. Yanıt verdiğiniz için teşekkürler ve iyi tatiller dilerim
    • iTerm2’yi gerçekten çok seviyorum, teşekkürler
  • bootstrap script’ler, uzak conductor agent’lar, escape sequence’ler gibi unsurları kullanan karmaşık sistemlerde ince hataların çıkması şaşırtıcı değil. Bileşenler aslında amaçlanmayan biçimlerde bir araya getirildiğinde bu tür sorunlar kolay doğuyor. Metin dosyası ya da sunucu banner’ı gibi ekrana yazdırılan güvenilmeyen çıktı içinde özel kodlar varsa ve sistem bunları kaynağını doğrulamadan işliyorsa, yapı kabaca böyle görünüyor

  • Bu bana daha önce duyduğum bir hikâye gibi geldi. iTerm2’nin SSH integration özelliği daha önce de bir CVE’ye neden olmuştu; CVE-2025-22275 de akla geliyor. Daha önce örnekler vardı ve bu başlıkta anılan eski sorun da tmux integration tarafındaydı. Bu tür entegrasyon özelliklerini biraz daha az agresif eklemek daha iyi olmaz mı diye düşünüyorum

    • ghostty’nin SSH integration yaklaşımı da benzer endişeler doğuruyor. Belki de upstream ncurses ile birlikte çalışıp terminfo’yu iyileştirmek daha doğru olur
    • Bu tür şeyler defalarca tekrarlandı
  • Başlık fazla sansasyonel. Sorun cat değil, iTerm’in SSH integration özelliği; ayrıca veri akışından ayrılmamış bir kontrol kanalı yapısı da riskli görünüyor. Bu özelliği kullanmayıp normal SSH kullanırsanız büyük ölçüde sorun yaşamazsınız diye düşünüyorum

    • Bu yüzden HN başlığını biraz daha yumuşak bir ifadeyle değiştirdim
  • Eski terminal emülatörleri escape code ile klavye yeniden eşlemeye kadar izin veriyordu. Bu yüzden güvenilmeyen dosyaları cat ile göstermemek, onun yerine less gibi araçlarla açmak neredeyse genel kabul görmüş bir kuraldı

    • Bazı terminallerde yalnızca escape sequence ile dosya yazmak ya da program çalıştırmak bile mümkündü diye hatırlıyorum. Bugün bile rastgele baytları terminal akışına doğrudan vermemek gayet makul bir tavsiye
  • Yazının ifadeleri tam doğru değil. İkinci paragraf, "iTerm2 kullanıyorsan güvenli değilsin" gibi okunuyor; oysa daha doğrusu, isteğe bağlı Shell Integration özelliğini kullanırken sorun çıkabileceği söylenebilir. Bu özellik varsayılan olarak kapalıysa etki alanının sınırlı olduğunu anlıyorum. Yanlışsam düzeltilmek isterim

    • Tek bir cümledeki abartı yüzünden tüm yazıya berbat demek bence fazla
    • O özellik varsayılan olarak açıktı ve bunu bizzat doğrulayabilirsiniz