- 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
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
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/
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
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
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ü
Sandbox modunda sertifika sabitleme kullansalardı bile, sabitlenmiş sertifika kontrolünü kaldırmanın başka bir yolu büyük olasılıkla olurdu
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
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 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ü
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 gibiSertifika sabitleme, saldırganların kurcalamasını zorlaştırmak içindi; kullanıcıların yapmasını zorlaştırmak için değil
İ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
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ö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
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
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
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
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
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
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