1 puan yazan GN⁺ 2024-03-06 | 1 yorum | WhatsApp'ta paylaş
  • Texts.com ekibi, kendilerine benzer bir bağımsız masaüstü uygulaması olan macOS için Meta Messenger’ı analiz etmek istedi; ancak sertifika pinning’i nedeniyle proxy tabanlı MITM analizi engellendi
  • Meta’nın sertifika pinning’i, uygulamanın yalnızca izin verilen sertifikalara güvenmesini sağlayarak, kullanıcının oluşturduğu bir sertifika otoritesiyle istekleri yakalayıp şifresini çözme yöntemini engeller
  • Frida tabanlı dinamik enstrümantasyon Messenger’da çökme ve dağıtım karmaşıklığını artırdığı için ekip daha küçük ve yeniden üretilebilir bir binary patch seçti
  • Hopper analizi sonucunda IsUsingSandbox() fonksiyonunun true döndürmesi için 4 bayt değiştirildiğinde, custom sandbox kullanılırken SSL doğrulamasını kapatan kod yoluna girilebildiği görüldü
  • Patch uygulanmış yürütülebilir dosyayla özgün binary değiştirildiğinde ve imzalama işlemi halledildiğinde, proxy aracında header’lar, yanıt gövdesi ve istek bilgileri görülebilir hale geldi

Texts.com neden Messenger’ı analiz etti?

  • Texts.com’da Meta platform projelerinden sorumlu Batuhan İçöz, macOS için Messenger uygulamasının kendi modellerine yakın bağımsız bir masaüstü uygulaması olduğu için analiz edilmeye değer olduğuna karar verdi
  • Ağ isteklerini yakalamak, giriş eşiği düşük olduğundan uygulamanın davranışını anlamak için iyi bir ilk adım olarak kullanılabilir
  • Ancak Meta, güvenlik modelini güçlendirmek için uygulamaya sertifika pinning’i uygulayarak kullanıcının kendi üzerinde yaptığı MITM analizini bile engelledi

Sertifika pinning’i neyi engeller?

  • Bir proxy istemcisiyle istekleri yakalamak için kullanıcının oluşturduğu bir sertifika otoritesini ayarlaması ve ona güvenmesi gerekir
  • Bu sertifika otoritesinin verdiği sertifika üzerinden istek bilgileri yakalanıp şifresi çözülebilir
  • Bir servis sertifika pinning’i uygularsa uygulama yalnızca belirli sertifika otoritelerinin verdiği sertifikaları kabul eder
  • Bu durumda kullanıcının oluşturduğu sertifika geçerli olmadığı için istekler yakalanamaz

Patch öncesi durum ve hedef

  • Sertifika pinning’i kapatılmadığında tüm istekler “Internal Error” döndürür
  • Proxy yazılımında “SSL Handshake Failed” görünür ve istek yaşam döngüsü sonuna kadar ilerlemez
  • Bu durumda istek içeriğini çıkarsamak zordur
  • Hedef, ağ hata ayıklama araçlarında istekleri, yanıtları ve header’ları doğrudan okuyabilir hale gelmektir

Başarısız atlatma seçenekleri ve nihai tercih

  • Geçmişte çalışan yöntemlerden biri, binary içindeki URL dizelerini TLS uygulamayan kendi barındırılan bir endpoint ile değiştirmekti
    • Bu endpoint, istemci ile sunucu arasında istek ve yanıtları iletir
    • Messenger gibi büyük uygulamalardan çok küçük uygulamalar için daha uygundur
  • Frida gibi dinamik enstrümantasyon kütüphaneleri de adaydı, ancak Messenger’da kararlılık düşüktü
    • Hook uygulanırken sık sık çökme yaşandı
    • Overhead nedeniyle sorunun olduğu noktayı bulmak zorlaştı
    • Çalıştırmak için gereken ortam ve araç yapılandırması olduğundan ekip üyelerine dağıtımı karmaşıktı
  • Yıllardır sürdürülen bir Frida script’i de denendi
    • Bu script genel sertifika pinning kütüphaneleri ve atlatma yöntemleri için kullanılmıştı ve çoğu uygulamada çalışıyordu
    • Meta uygulama ailesi bu “çoğu”nun içinde yer almıyordu
  • Sonunda ekip üyelerine kolayca aktarılabilecek bir binary patch ile sertifika pinning’ini tamamen kapatma yöntemi seçildi

Hopper ile bulunan patch noktası

  • Messenger indirildikten sonra Applications klasörüne taşındı ve /Applications/Messenger.app/Content/MacOS/Messenger konumundaki derlenmiş ARM binary Hopper’a aktarıldı
  • Hopper, derlenmiş binary’leri disassemble, decompile, recompile, debug ve görselleştirme işlemleriyle analiz edebilir
  • Binary ve referanslar yüklendikten sonra certificate, ssl, pinning gibi terimler arandı
  • "SSL pinning verification failed for host:" dizesi analiz için başlangıç noktası oldu
  • Derlenmiş binary aşırı değiştirilirse çökebileceği için, mümkün olduğunca küçük değişiklikler uygulama stratejisi kullanıldı
    • İdeal değişiklik; boolean değerini tersine çevirmek, koşul ifadesini terslemek veya birkaç talimatı değiştirmek gibi etki alanı dar bir patch’tir

IsUsingSandbox() fonksiyonunu her zaman true yapmak

  • Kontrol akışı grafiğiyle yürütme akışı görselleştirildi ve bağlantılı referanslar yukarı doğru takip edildi
  • "Using custom sandbox -> turn off SSL verification" dizesi bulundu
  • Bu flag’i belirleyen fonksiyonun referansları dosyada arandı ve prosedürün üst kısmında ilgili referans doğrulandı
  • IsUsingSandbox() fonksiyonunda dönüş değerinin atandığı nokta izlendi
    • w0 register’ı w19dan taşındıktan sonra döndürülür
    • w19 başlangıçta load byte talimatıyla atanır
  • w19 yüklenmeden her zaman true olarak ayarlanırsa IsUsingSandbox() true döndürür
  • Daha önce bulunan dizeye göre custom sandbox kullanıldığında SSL doğrulaması kapandığından, bu değişiklikle sertifika pinning’i devre dışı bırakılır
Original
ARM: ldrb w19, [sp, #0x40 + var_20]
HEX: F3 83 40 39

Rewritten
ARM: mov w19, #1
HEX: 33 00 80 52
  • Bu değiştirme, hexadecimal mode’da uygulamanın bytecode’unu doğrudan düzenleyerek yapıldı

Çalıştırma sonucu ve yeniden imzalama

  • Hopper’ın “Produce New Executable” seçeneğiyle yeni yürütülebilir dosya dışa aktarıldı
  • Yürütülebilir dosyanın imzası kaldırıldıktan sonra, özgün Messenger binary’si yeni binary ile değiştirildi
  • Messenger yeniden çalıştırıldığında proxy aracında header’lar, yanıt gövdesi ve diğer istek bilgileri göründü
  • Toplam binary boyutu 97.477.728 bayt iken yalnızca 4 baytlık değişiklikle istek yakalama mümkün hale geldi
  • iOS’ta benzer bir yaklaşım görmek isterseniz Hassan Mostafa’nın 2020 tarihli Instagram sertifika pinning’i atlatma yazısına bakabilirsiniz
    • Bu yazı, jailbreak yapılmış bir iPhone’da koşullu dallanma talimatını ters çevirerek Instagram sertifika pinning’ini devre dışı bırakma örneğidir
  • Derlenen binary Batuhan’a iletildi
    • Batuhan imzalama sertifikasını temin edip kurduktan sonra uygulamayı imzaladı
    • Ardından kendi sisteminde bu binary’yi kullanarak kendi isteklerini görebildi
codesign --force --deep -s CERTNAME_OR_ID /Applications/Messenger.app

1 yorum

 
GN⁺ 2024-03-06
Hacker News yorumları
  • Benzer bir yoldan gidip decompile/modify/recompile aşamasına gelmek üzereyken vazgeçtim
    Bu kadarı bayağı azim işi; gerçekte kaç saat harcandığını merak ediyorum. Ben bir durma kriteri belirlemiştim ve ona sadık kaldım

    • Bu yazı aslında Texts.com’un iç yazısıydı; birkaç hafta önce ben de tam olarak aynı yaklaşımı denemiş, belirlediğim süre sınırına takılıp vazgeçmiştim. Paylaşım için düzenlerken o kısmı çıkardım
      Başta 2 saat boyunca çeşitli komutları değiştirip denedim, sonra vazgeçtim. Daha sonra tersine mühendis “Hassan Mostafa”nın (cyclon3) daha önce aynı yöntemle başarılı olduğu bir yazıyı, yani iOS’ta Instagram’a Hopper Disassembler uyguladığı yazıyı gördüm ve o gece tekrar denedim ama başarısız oldum. Aynı komutu da bulup değiştirmeyi denedim
      Sonra bırakmaya karar verdim; birkaç hafta sonra içimde biraz ukde kalmışken anlık bir hevesle yeniden denedim ve sandbox fonksiyonunu bulduktan yaklaşık 30 dakika sonra işi bitirdim
  • eBPF kullanırsanız TLS şifrelemesinden önce veriyi okuyabiliyor gibi görünüyor: Debugging with eBPF Part 3: Tracing SSL/TLS connections https://blog.px.dev/ebpf-openssl-tracing/

    • Kullanışlı bir yöntem; Frida gibi bir şeyle TLS gönderme/alma fonksiyonlarını hook’lamak gibi başka yollar da neredeyse kesinlikle mümkün. Ancak sertifika sabitlemeyi aşmanın avantajı, araştırmacının trafiği Burp Suite veya mitmproxy gibi mevcut araçlardan geçirebilmesi
      Gerçek uygulama trafiğini araya giren bir proxy’ye yönlendirmek, amaca bağlı olarak süreyi ciddi biçimde azaltır. Örneğin kimlik doğrulama/oturum kurulumundan sonra ortaya çıkan bir isteğin tek bir parametresini otomatik olarak değiştirmek istiyorsanız, ilk akışın tamamını gerçekleştiren yeni bir istemci yazmaktan ya da eBPF filtresinde değiştirme mantığı kodlamaktan çok, uygulamanın kendi işini yapmasına izin verip proxy’de tek bir yeri değiştirmek çok daha hızlıdır
    • Bu arada bu yöntem, en yaygın kullanılan Rust TLS kütüphanesi olan rustls’i statik olarak linkleyen Rust programlarında işe yaramaz
  • Çok zekice bir yöntem. Yine de sandbox modunda da sertifika sabitlemeyi zorunlu kılabilirlerdi gibi geliyor
    Üniversitedeyken Snapchat’i ortadaki adam saldırısıyla incelemeye çalışmıştım; orada da sertifika sabitleme kullandıkları için sonunda aşamamıştım

    • Ben de aynısını denedim; uygulamayı patch’leyip istekleri yakalamayı başardım ama istek imzalama işinden sorumlu paylaşımlı nesneyi tersine mühendislikle çözmeye çalışırken vazgeçtim
      Giriş noktasını bile bulamamıştım. Nispeten küçük bir sosyal medya uygulamasına göre 2015’te bile güvenliği akıl almaz derecede güçlüydü
    • Kullanıcı binary’yi değiştirebiliyorsa sertifika sabitlemeyi zorunlu kılmak temelde zordur
      Sandbox modunda sertifika sabitleme kullansalardı bile, sabitlenmiş sertifika kontrolünü kaldırmanın başka bir yolu büyük olasılıkla olurdu
    • Doğru. Tüketici fonksiyonunun içinde sandbox flag fonksiyonunun çıktısını true atayacak şekilde de uygulanabilirdi, ama bu durumda mevcut yöntem de gayet iyi çalıştı :)
    • Mobil uygulamalarda bunu deneyip takılan bu kadar çok kişi olması komik
      Artık öyle değil gerçi
  • Bu yazı bana +Orc dönemini hatırlattı. İstenmeyen dallanmayı bulup NOP’a çevirmek gibi, o zamanlar yaygın olan pek çok bilginin kaybolmuş gibi olduğunu düşünüyorum
    Bugün öğrenilecek çok daha fazla teknoloji var; bu da anlaşılır
    [1]: https://en.m.wikipedia.org/wiki/Old_Red_Cracker

    • +Orc ya da Fravia (RIP) adı geçince hep nostalji hissediyorum
      Yine de NOP patch yapan hâlâ çok kişi olduğunu düşünüyorum. Sadece karmaşıklık arttı. DRM kıran ya da rastgele mobil uygulamaları hex editör vb. ile inceleyen insanlar hâlâ var
      Günümüz programları daha karmaşık olduğu için başlamak zorlaştı, ama aynı zamanda gereken bilgiye erişmek de daha kolaylaştı
  • Meta uygulama trafiğini yakalamak istiyorsanız bunu illa böyle yapmanız gerekmez
    https://www.facebook.com/whitehat/bugbounty-education/261571...

    • Bu yalnızca Android’de çalışıyor. Biz Android uygulamasını yakalamakla ilgilenmiyorduk
  • Bu tür değişiklikleri zorlaştırmak için runtime binary checksum kullanmak işe yarar mıydı merak ediyorum
    Mobil uygulamalarda standart uygulama değil mi? iOS ya da Android SDK böyle bir özellik sunuyor mu? Resmî yayın süreciyle bağlantılı olup, her birinin jailbreak yapılmamış platformunda zorunlu kılınan bir şey gibi olurdu sanırım
    Temel bir soru ama nihai çözüm binary’de birkaç byte değiştirmek olduğu için engellenebilir gibi görünmüştü

    • macOS (masaüstü) bu, iOS (mobil) değil
    • Binary’yi değiştirdiğinizde zaten yeniden imzalamanız gerektiği için aynı etki kalır
      Jailbreak yapılmamış platformlarda bu genelde geliştirici sertifikasıyla yapılır
  • Meta’nın, en azından Messenger’ın tersine mühendislik savunması epey gevşek görünüyor
    Gelişmiş obfuscation’a kadar gitmeden bile, production build’de IsUsingSandbox()’ı tamamen kaldırmak kolay olurdu gibi

    • Ben orada çalışırken tersine mühendislik savunması hiç hedef olmamıştı
      Sertifika sabitleme, saldırganların kurcalamasını zorlaştırmak içindi; kullanıcıların yapmasını zorlaştırmak için değil
    • Meta uygulamalarında production build’lerde bile debug menüsü komple yer alıyor. Yazarın bulduğu string de muhtemelen böyle bir menünün parçası
  • İlk uygulamamı crack’lediğimde doğal olarak başarısız olacağımı düşünmüştüm; meğer bu şekilde değiştirmesi kolay JNE/JEZ noktalarını bulmak sandığımdan daha kolaymış
    Yanlış yeri seçseniz bile orijinal dosyaya dönüp başka bir noktayı deneyebilirsiniz
    Bunu yapay zekanın kolayca otomatikleştirebileceğini düşünüyorum. Birkaç aday noktada JEZ/JNZ’yi ters çevirip uygulamayı çalıştırır, dırdır ekranının çıkıp çıkmadığına bakar

    • Bu pek yapay zeka meselesi değil, daha çok fuzzing gibi
      Başarısızlık koşulu iyi tanımlanmışsa sonuçta adayları daraltırsınız
      Yapay zeka Denuvo gibi bir şeyi sıfır denemede (0-shot) kırabilirse o başka mesele olur
    • Böyle araçlar 90’larda bile vardı. Yapay zeka değil, düpedüz brute force idi
  • Böylesine büyük bir şirketin uygulamasının neden tamamen obfuscate edilmediğini ve değiştirilmiş ikililerin çalıştırılmasını engelleyen korumaları neden yeterince eklemediğini merak ediyorum

    • Facebook uygulamasında bu kararı ilk veren tarafta biri olarak söyleyeyim: buna değmez
      Yeterince yetkin ya da motivasyonu yüksek bir kişi/grup/devlet varsa eninde sonunda aşar. İstemci ikilisini dağıtmanın doğası zaten bu
      Engellemek için muazzam zaman ve para harcayabilirsiniz. Eskiden Pinterest kendi dilini ve sanal makinesini dağıtmaya çalışmıştı; ben karşı çıkmıştım. Ya da istemci kodunun temelde zaten ele geçirilmiş olduğunu kabul edip mantığı sunucuya koyar ve devam edersiniz
      Sertifika pinning neredeyse bedavaya yakındır ve “bu anahtarın üzerinde olmalı ki binebilesin” gibi bir mekanizmadır. Güvenli değildir ama sıradan denemeleri eler
    • Obfuscation maliyetlidir; sertifika pinning ise tersine mühendisliği engellemekten çok kullanıcı aleyhine olan ortadaki adam saldırılarını zorlaştırma amacına daha yakındır
      Elbette tersine mühendisliği de etkiler ama bu daha çok yan fayda gibidir
      Sonuçta kod kullanıcının cihazında çalışır ve kullanıcı kodun ne yaptığını gözlemleyebildiği için her zaman obfuscation geri alınabilir. Bir kişi çözüp sonucu paylaşırsa kopyalamak da çok kolaylaşır. Bu obfuscation işe yaramaz demek değil, ama üzerine çok fazla zaman harcanacak bir şey de değil
    • Mobil/frontend uygulamalarda bunu yapsanız da pek işe yaramaz
      Saldırganın cihaza fiziksel erişimi varsa o noktadan sonra durdurmanın yolu yoktur. Yapabileceğiniz tek şey süreci daha zahmetli hale getirip sinirlenip vazgeçmesini ummaktır
    • Büyük olasılıkla öncelik ve maliyet-fayda meselesi
      Obfuscation bu deneyin sonucunu neredeyse hiç etkilemezdi; yaklaşım yalnızca biraz daha fazla dinamik enstrümantasyon kullanmaya kaymış olabilirdi. Gördüğüm en etkili obfuscation VM obfuscation’dı, ama performans etkisi kayda değer. Obfuscation normal hata ayıklamayı da zorlaştırır
      Değiştirilmiş ikilileri engelleme sistem düzeyinde yapılır; uygulama düzeyinde de uygulanabilir ve oldukça yaygındır. Ama bu özelliğin kendisi de aşılabilir; güvenlik kontrolleri bittikten sonra Frida gibi dinamik enstrümantasyon kütüphaneleriyle değişiklik yapmak da mümkündür
      Meta açısından tersine mühendislerle kedi-fare oyunu oynamak en iyi seçenek gibi görünmüyor
    • Neden bütün bankaların güvenliği Fort Knox gibi değil sanıyorsunuz?
  • Yazıda kullanılan proxy aracının ne olduğunu merak ediyorum. Çalışırken tüm uygulama trafiğini oraya mı yönlendiriyor?
    Aptalca bir soruysa kusura bakmayın

    • İyi soru. Yazıda kullanılan araç Proxyman
      macOS’te tüm uygulama trafiğini oraya yönlendiriyor; cihaza kendinden imzalı bir sertifika kurup proxy’ye bağlarsanız iOS cihazlarını da proxy üzerinden geçirebiliyorsunuz