- iOS uygulamalarında tersine mühendislik için çalışan uygulamayı gözlemleyip manipüle edebilmek gerekir; ancak bu widget uygulaması debugger engelleme, kod enjeksiyonu engelleme ve jailbreak tespitini birlikte kullanıyor
- Temel engelleme,
ptraceiçindeki PT_DENY_ATTACH ya da aynı etkiyi veren doğrudan sistem çağrısı (svc #0x80) ile uygulanabiliyor; bu yüzden yalnızca basit birptracebreakpoint’i ile yakalanmıyor - Doğrudan sistem çağrısı, ikili dosyada
mov w16, #26desenini bulupsvckonumuna breakpoint koyarak velldb jumpile ilgili komutu atlayarak aşılabiliyor - Jailbreak tespitinden sonra telefonu soft-reboot/respring yapan davranış,
snapshotViewAfterScreenUpdates:metodunu sonsuz döngü içinde çağıran bir fonksiyonla bağlantılıydı ve fonksiyon başlangıcındathread returnile atlanabiliyordu - Kod enjeksiyonundan sonraki çökme, ayrı bir runtime framework denetiminden çok App Group yetkisinin kaybına yakındı;
containerURLForSecurityApplicationGroupIdentifier:metodunu geçici dizine yönlendiren bir swizzle ile uygulama normal cihazlarda da çalıştırılabildi
Birden fazla korumayı üst üste kullanan iOS widget uygulaması
- Hedef, App Store’daki bir widget uygulaması ve sıradan widget uygulamalarından daha güçlü savunma davranışları içeriyor
- debugger attach engelleme
- kod enjeksiyonu sırasında uygulamayı kapatma
- jailbreak durumunda çalıştırılırsa telefonun tamamını soft-reboot/respring yapma
- iOS uygulamalarının jailbreak tespiti ya da kod karmaşıklaştırma gibi korumalar eklemesi alışılmadık değil, ancak bu uygulama birden fazla yöntemi birlikte kullanıyor
- Uygulama içindeki diğer ilginç davranışlar sonraki yazıya bırakılıyor
PT_DENY_ATTACH ile debugger attach engelleme
- Jailbreak’li cihazlarda genelde
sshile bağlanıpdebugserverçalıştırarak, başka bir bilgisayardakilldbüzerinden uygulama hata ayıklanabiliyor - Aynı yöntemle bu uygulamaya
debugserverbağlanınca Segmentation fault oluşuyor ve attach başarısız oluyor - Nedeni,
ptraceiçindekiPT_DENY_ATTACHisteğiyle ilgiliptrace, iOS’ta private API, macOS’ta ise public APIPT_DENY_ATTACH, sonrasında ebeveyn sürecin trace etmesini reddeden bir bayrak ayarlıyor- Süreç zaten trace ediliyorsa uygulama
ENOTSUPdurumuyla sonlanıyor - Bu bayrağın ayarlandığı bir süreci ebeveyn trace etmeye çalışırsa ebeveyn tarafında segmentation violation oluşuyor
- Basit uygulama,
ptrace(PT_DENY_ATTACH, 0, 0, 0)çağrısıyla mümkün- Bu iOS private API olduğu için gerçek çağrıda
dlopen,dlsymilelibsystem_kernel.dylibiçindekiptracesembolünü bulmak gerekiyor - Bu yöntem,
ptraceüzerine breakpoint koyupthread returnile çağrıyı atlayarak nispeten kolay aşılabiliyor
- Bu iOS private API olduğu için gerçek çağrıda
Kolay yöntemin işe yaramamasının nedeni
PT_DENY_ATTACHdebugger’ı ancak çağrıldıktan sonra engellediği için, uygulama kodu çalışmadan önce attach olunursa bir bypass noktası oluşturulabiliyordebugserverı sürece doğrudan bağlamadan çalıştırıp, ardındanlldbiçindeprocess attach --name TopWidget --waitforile uygulamanın başlaması beklenirse uygulama kodu çalışmadan önce attach olunabiliyor- Ancak bu uygulamada
b ptracebreakpoint’i ilk başta çözümlenmedi ve sonrasında çözümlense bile uygulama kapanana kadar hiç tetiklenmedi - Çünkü uygulama
ptracefonksiyon çağrısı yerine aynı etkiyi veren doğrudan sistem çağrısı yöntemini kullanıyordu
Doğrudan sistem çağrısının yerini bulma
ptracefonksiyonunun disassembly çıktısında temel olaraksvc #0x80sistem çağrısı bulunuyorx0içinePT_DENY_ATTACHdeğeri olan31yazılıyorx1,x2,x3içine kullanılmayan0argümanları yazılıyorx16içineptracesistem çağrısı numarası olan26yazılıyor
- Uygulama
ptracefonksiyonunu çağırmak yerine inline assembly ile aynı register değerlerini ayarlayıpsvc #0x80komutunu doğrudan çalıştırabiliyor- Bu yöntem
dlopen,dlsymgibi şüpheli private API lookup’larını önlüyor ptracegibi ortak bir fonksiyona breakpoint koyma yaklaşımıyla yakalanması zorlaşıyor
- Bu yöntem
- Bypass için şifresi çözülmüş uygulama ikilisini bir disassembler’da açıp
ptracesistem çağrısının yerini bulmak gerekiyor - Aranacak desen
mov x16, #26ya da aynı register’ın 32 bit görünümü olanmov w16, #26- armconverter.com üzerinden
mov x16, #26için50 03 80 D2baytları elde edilip ikili aramada kullanılabiliyor mov x16, #26araması sonuç vermedi,mov w16, #26aramasında ise 4 sonuç bulundu
- armconverter.com üzerinden
- Bunlardan ikisinde çevredeki komutlar beklenen desenle uyuşmuyordu; üçüncü sonuçta ise şu yapı doğrulandı
MOV X0, #0x1FMOV X1, #0MOV X2, #0MOV X3, #0MOV W16, #0x1ASVC 0x80
- Dördüncü sonuç aynı fonksiyonun başka bir branch’iydi ve bu fonksiyonun debugger attach’i engelleyen yer olduğu doğrulandı
svc komutunu atlamak
- Disassembler’da görülen
svcadresleri0x102A2BB14ve0x102A2BB68 lldbiçinde ikili dosya tabanlı adresi gerçek yükleme adresine çevirmek için breakpoint’e-s TopWidgetekleniyorbr s -a 0x102A2BB14 -s TopWidgetbr s -a 0x102A2BB68 -s TopWidget
- Çalışma sürdürüldüğünde breakpoint
svc #0x80konumunda yakalanıyor - En kolay bypass, bir sonraki komut adresine jump ederek sistem çağrısının kendisini hiç çalıştırmamak
- Örnekte mevcut komuttan sonraki adres olan
0x10327bb18içinjump *0x10327bb18çalıştırılıyor
- Örnekte mevcut komuttan sonraki adres olan
- Bu süreçten sonra debugger attach edilmiş halde uygulamanın içine girilebiliyor
Telefonu soft-reboot yapan davranış
- Debugger attach bypass edildikten sonra bile uygulama telefonu soft-reboot/respring yapan koruma davranışını çalıştırıyor
- Bu kez
lldbhâlâ attach durumda olduğu için, sürecinSIGKILLaldığı an ve stacktrace görülebiliyor - Stacktrace’te ekran içeriğini yakalayan bir akış görünüyor
QuartzCoreiçindekiCARenderServerSnapshotUIKitCoreiçindeki_UISnapshotScreenWindowsRectAfterCommit- uygulama içindeki
TopWidgetadlı isimsiz sembol
lldb image lookupile runtime adresi, ikili dosya tabanlı0x100041898adresine çevrilip disassembler’da ilgili fonksiyon inceleniyor- Decompile sonucunda fonksiyonun sonsuz döngü içinde yalnızca şu işleri tekrar ettiği görülüyor
+[UIScreen mainScreen]çağrısı- dönen ekran nesnesi üzerinde
snapshotViewAfterScreenUpdates:çağrısı - sonuç kullanılmadan release edilmesi
snapshotViewAfterScreenUpdates:view snapshot oluşturan bir public API olsa da bu uygulama bellek yoğun bu çağrıyı sonsuz biçimde tekrarlıyor- Bağlantılı videoda bu çağrının kökeninin
com.apple.tw.twrrnotification’ı ile ilişkili olduğu ve telefona yönelik risk kontrolü geçilemezse respring yaşandığı doğrulanıyor - Bypass, ilgili fonksiyonun başlangıcına breakpoint koyup tetiklendiğinde
thread returnile fonksiyon yürütmesini atlamakla mümkün
Kod enjeksiyonu sırasında oluşan çökme
- Hata ayıklama sırasında ekrandaki butonların erişilebilirlik bilgisini log’lamak gibi karmaşık yardımcı araçlar, uygulamaya enjekte edilen bir framework içinde uygulanıp debugger’dan çağrılabiliyor
- Jailbreak’li cihaz olmadığında da Frida veya Flex enjekte edilerek uygulama üzerinde ilk keşif yapılabiliyor
- Genel olarak bu tür enjeksiyon, uygulamayı yeniden imzalayan araçlarla yapılıyor; örnek olarak Sideloadly kullanılıyor
- Bu uygulama yeniden imzalandıktan sonra çalıştırıldığında anında crash ediyor
- Crash stack’inin üst kısmındaki
0x1002027D4adresi disassembler’da incelendiğindeBRKkomutu görülüyor; bu danilforce-unwrap gibi kasıtlı çökme durumlarıyla uyumlu - Decompile edilmiş kodda sorunlu görünen çağrı
containerURLForSecurityApplicationGroupIdentifier:- Bu metot, aynı group içindeki uygulama ve extension’ın birlikte erişebildiği klasör URL’sini döndürüyor
- App Group, kod imzalama sürecinde tanımlanıyor
- Kod enjeksiyonundan sonra yeniden imzalama yapılınca mevcut uygulama imzası atılıyor ve App Group yetkisi de kayboluyor
- Bu yüzden URL yerine
nildönüyor ve uygulama bunu force-unwrap ettiği için crash etmiş olma ihtimali yüksek
- Widget uygulamaları, ana ekran widget gösterimini üstlenen extension ile App Group paylaşmak zorunda olduğundan, bu sorun savunma amaçlı kasıtlı davranıştan çok yaygın bir kod imzalama problemine benziyor
App Group sorununu aşma
- En kolay çözüm uygulamayı yeniden imzalamamak
- Jailbreak’li cihazlarda bir jailbreak tweak ile framework enjekte edilirken uygulamayı yeniden imzalamadan devam edilebiliyor
- Geçersiz imzalı kod çalıştırmak ya da istenen uygulamayı istenen group’a eklemek de mümkün
- Jailbreak’li cihaz yoksa ve yeniden imzalama gerekiyorsa, küçük bir framework ile metod swizzle yapılarak da aşılabiliyor
- Örnek kod,
NSFileManageriçindekicontainerURLForSecurityApplicationGroupIdentifier:metodunu değiştiriyor- Orijinal metot çağrıldığında yerine replacement method çalışıyor
- Replacement method, shared container yerine
temporaryDirectorydöndürüyor
- Bu değişiklik uygulamanın aslında istediği davranışla aynı değil
- Uygulamanın istediği, uygulama ile extension’ın birlikte erişebileceği paylaşımlı klasör
- Geçici dizin böyle bir paylaşımlı klasör değil
- Yine de amaç yalnızca ana uygulamanın davranışını incelemekse yeterli olabiliyor
- Bu tür küçük bir patch app extension’ı bozabilir
- Yalnızca ana uygulamanın temel işlevleri gerekiyorsa sorun olmayabilir
- Daha büyük bir bypass, yeni bir App Group oluşturup ana uygulama ile tüm extension’ları bu group ile yeniden imzaladıktan sonra ilgili metotların yeni group identifier’ı kullanmasını swizzle etmek
- Bu çok daha büyük bir iş ve gerçekten gerekmedikçe jailbreak’li bir cihaz edinmek daha mantıklı olabilir
- Bu framework
Flexgibi araçlarla birlikte enjekte edildiğinde uygulama normal cihazlarda da düzgün çalışıyor - Jailbreak’li cihazlarda önceki anti-debugging ve respring korumalarının yeniden aşılması gerekiyor, ancak sonrasında
Flexenjekte edilmiş halde uygulamanın içine girilebiliyor
Son durum
- Sonuçta uygulama, debugger attach, jailbreak tespitini aşma ve kod enjeksiyonu açısından tamamen erişilebilir hâle geliyor
- Uygulama içinde gerçekte neyin incelenmek istendiği ise sonraki yazının konusu olarak bırakılıyor
1 yorum
Hacker News yorumları
Bryce Bostwick, uygulama hata ayıklama ve tersine mühendislik konusunda gerçekten harika ve ilham verici işler yapıyor
Onu YouTube’da keşfettim; TikTok’u yalnızca kedi videoları gösterecek şekilde modifiye ettiği videosunu (https://youtu.be/YW3jL2gI9IE) izledikten sonra Instagram’ı, kullandığım mesajlaşma özelliği dışında her şeyi kaldıracak şekilde modifiye etmeyi denedim
Eskiden beri Windhawk (https://windhawk.net/) tarzında Windows’u modifiye etme yöntemlerini, özellikle modifikasyon ve tersine mühendisliği daha derinlemesine incelemek istiyordum; Bryce iOS’ta bu tür işleri gerçek zamanlı, adım adım videolarla çok iyi tanıtıyor
Revanced ile harika şeyler yapılabildiğini gördüm ama bu tür işlere nasıl başlanacağını anlatan iyi bir rehber pek yok gibi görünüyor
Süreci bir yere derlersen ilgimi çeker
Fotoğraf yüklemek ya da arkadaşlarımla sohbet etmek istediğimde bile Reels’e maruz kalmak zorunda kalmaktan hoşlanmıyorum
Hata ayıklamayı engelleme ve hatta hata ayıklamayı engellemeyi devre dışı bırakmayı yeniden engelleme teknikleri DOS/Windows tarafında çok eskiden beri yaygındı
Eski cracking veya unpacking kaynaklarına bakarsanız bu konuların farklı derinliklerde ele alındığını görürsünüz
Kullanıcının uygulama davranışını ne kadar kolay denetleyebildiği, platformun kullanıcıya ne kadar düşmanca olduğuyla ters orantılıdır
PT_DENY_ATTACH tam da bu kullanıcı düşmanlığı için yapılmış bir özellik gibi görünüyor
Bildiğim kadarıyla Windows’ta böyle bir özellik yok; bunun yerine uygulamayı kendi kendisine attach ettirme tekniği kullanılıyor
https://www.x86matthew.com/view_post?id=selfdebug
https://anti-debug.checkpoint.com/techniques/interactive.htm...
Apple’ın App Store incelemesinin doğrudan sistem çağrısı yapan uygulamaları reddetmemesi biraz şaşırtıcı
Apple platformlarındaki sistem çağrıları kararlı bir ABI değil; bu yüzden tüm sistem çağrılarının libSystem üzerinden geçmesi gerekir ve libSystem’i atlayıp doğrudan sistem çağrısı yapan uygulamalar yapmamaları gereken bir şeyi yapıyor sayılır
Benzer şekilde, burada yazarın kodda
svc 0x80yerine nedenmov w16, #26aradığını da merak ediyorumsvc 0x80, herhangi bir sistem çağrısını çalıştıran komuttur; tam olarak hangi çağrının çalışacağı x16 yazmacına göre belirlenirUygulama muhtemelen alakasız çok sayıda sistem çağrısı yapacağı için oraya breakpoint koymak pek yararlı olmazdı
En azından videoda böyle açıklıyordu
Aynı nedenle SVC komutunu ararsanız çok fazla sonuç çıkar
X16’ya taşınan tam sistem çağrısı ID’sini bulursanız doğrudan yakalayabilirsiniz
Yazının yazarıyım. Sorular varsa yanıtlayabilirim. Paylaştığı için xmprt’ye teşekkürler
Yazılı sürümünü de sunman iyi olmuş
Yazara birkaç şey sormak isterim: En bilinen ticari araç gerçekten Guardsquare ise, bu tarz kolay disassembly’yi engelleyen yeni bir şey sunduğunu düşünüyor musun?
TopWidgets’ın buna benzer bir koruma kullanıp kullanmadığını, yoksa kendi yaptığı seviyede bir şey mi olduğunu da merak ediyorum
Kişisel olarak Android kullandığım için teknik olarak doğrudan uygulanabilir değil, ama iOS’ta düşük seviyeli hata ayıklamanın nasıl çalıştığını öğrenmekten yine de çok değer elde ediyorum
En üstteki video, şimdiye kadar gördüğüm programlama videoları arasında en üst seviyedekilerden biri
Akışı hızlı, tam kararında ön bilgi varsayıyor ve videonun temposunu bozmayan harika demolar içeriyor
Harika bir yazı
Bunun aşırı paranoyak normal bir uygulama mı, yoksa en başından kötü amaçlı yazılım olduğundan şüphelenildiği için mi debug edilen bir uygulama olduğunu gerçekten merak ediyorum
Öyle değilse harcanan çaba epey abartılı görünüyor
Widget’larla oldukça havalı işler yapıyor, sanırım bunu korumaya çalışmış. Ancak bu tür stratejiler de zaten yavaş yavaş sızmaya başlamıştı
Binary içinde ilginç şeyler de vardı
Bir ara neden Windows
.isoindiriyor gibi görünen bir koda baktığımı anlamaya çalıştım; meğer gerçekten öyleymiş ve ağ hızı testi widget’ında kullanılıyormuş“PT_DENY_ATTACH’i atlatmak (zor mod)”dan daha zor bir mod da var
Eskiden macOS’ta kernel’i patch’leyerek PT_DENY_ATTACH’in hiçbir şey yapmamasını sağlamıştım
Mac’te patch’lenmiş bir kernel çalıştırmak aslında oldukça kolay sayılır, ama iOS’ta KTRR gibi şeyler yüzünden bunun çok daha zahmetli olacağını düşünüyorum
XNU teknik olarak açık kaynak olsa da yeniden derlemektense patch’i hex editörle uygulamak daha kolaydı
İmzasız kod sayfalarına ve RWX’e izin vererek JIT’i de mümkün kılabilirsiniz
“Jailbreak açıkken çalıştırınca tüm telefon çöküyor” ise, bunu mağazaya kötü amaçlı yazılım olarak bildirmek gerekmez mi?
Telefonu çökertmek açıkça kötü amaçlı yazılım davranışı; ayrıca saklamaya çalıştığı başka hangi kötü niyetli eylemler olabileceğinden de şüphelenmek gerekir
Apple’ın kapalı ekosistem gerekçesi bu tür çöpleri engellemek değil miydi?
Apple’ın jailbreak’li telefonda uygulamanın çökmesini pek umursayacağını sanmıyorum
com.apple.tw.twrr bildirimi gerçekten merak uyandırıcı
Neden
com.appleile başlıyor?Buradaki söz konusu uygulama Apple uygulaması değil, Top Widgets adlı uygulama gibi görünüyor
Çakışmaları önlemek için bu tür “tam ad” kullanmak gelenektir
Bu durumda geliştirici tesadüfen böyle bir önek seçmiş gibi görünüyor
Araçlar farklı olsa da bu, 1980’lerde boot tracing ile Apple II kopya korumasını kırmakla tamamen aynı his
Bazı şeyler değişmiyor