Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

BTRisk iOS Mobil Uygulama Denetimi Eğitimi

3,167 views

Published on

BTRisk tarafından geliştirilen btrmobile uygulaması üzerinde uygulamalı olarak verilen mobil uygulama denetimi eğitimidir

Published in: Business
  • Login to see the comments

BTRisk iOS Mobil Uygulama Denetimi Eğitimi

  1. 1. iOS MOBİL UYGULAMA DENETİMİ EĞİTİMİ blog.btrisk.com @btrisk /btrisktv /btrisk
  2. 2. BTRİSK HAKKINDA TANIŞMA Pentest & BT Denetimi ISO27001 Danışmanlık Hizmetleri BG Operasyon Hizmetleri
  3. 3. Göreviniz, Deneyiminiz ve Eğitimden Beklentileriniz Nelerdir? TANIŞMA
  4. 4. iOS GELİŞTİRME ORTAMI XCODE iPhone Simulator
  5. 5. iOS GELİŞTİRME ORTAMI iPhone Simulator üzerinde çalıştığı Mac bilgisayarın /private/etc/hosts dosyasını kullanır HTTP(S) Sunucusu IP Adresi
  6. 6. SİMULATÖR ORTAMI Application Bundle dizininin bulunduğu alan Not: Bu dizin Mac OS X 10.10.5 ve Xcode 6.3.2 için geçerlidir. Farklı versiyonlarda farklı dizinlerle Karşılaşılması olasıdır.
  7. 7. SİMULATÖR ORTAMI iOS Simulator ve Cihaz ortamlarında cihaz ve uygulama dizinleri için UUID değerleri kullanılıyor
  8. 8. SİMULATÖR ORTAMI Bu nedenle doğru dizinleri tespit edebilmek için sıklıkla "find" komutunu kullanıyoruz
  9. 9. SİMULATÖR ORTAMI Uygulamanın ürettiği verileri barındıran "Documents" dizininin bulunduğu alan Not: Bu dizin Mac OS X 10.10.5 ve Xcode 6.3.2 için geçerlidir. Farklı versiyonlarda farklı dizinlerle Karşılaşılması olasıdır. Güvenlik Notu: Documents dizinindeki dosyalar cihaz yedeklerinin içinde bilgisayarlara da aktarılır.
  10. 10. SİMULATÖR ORTAMI Uygulamanın ürettiği logları barındıran system.log dosyasının bulunduğu alan Not: Bu dizin Mac OS X 10.10.5 ve Xcode 6.3.2 için geçerlidir. Farklı versiyonlarda farklı dizinlerle Karşılaşılması olasıdır. Güvenlik Notu: Cihaz loguna yazılan veriler sandbox kontrolü ile korunmaz, cihaz üzerindeki diğer tüm uygulamalar tarafından okunabilir.
  11. 11. UYGULAMANIN (GELİŞTİRME ORTAMINDAN) CİHAZA AKTARILMASI • Normalde uygulamaları test cihazına da olsa yüklemek için bir Apple Developer hesabına ihtiyaç bulunmaktadır. Aksi takdirde Xcode ile bir uygulamayı cihaz üzerinde debug etmek mümkün olmamaktadır. • Ancak Xcode'un 6 veya daha güncel bir versiyonu yukarıda görüldüğü gibi uygulamayı cihaz üzerine kurabilmektedir. Bununla birlikte debug etmek için uygulamayı başlattığında cihaz üzerinde hata oluşmakta ve uygulama kendini sonlandırmaktadır. 1 2
  12. 12. UYGULAMANIN (GELİŞTİRME ORTAMINDAN) CİHAZA AKTARILMASI Xcode ile debug edemesek de uygulamamız cihaz üzerinde çalışıyor.
  13. 13. CİHAZ IP ADRESİ
  14. 14. CİHAZ'LA DOSYA ALIŞVERİŞİ İÇİN
  15. 15. CİHAZ'LA DOSYA ALIŞVERİŞİ İÇİN Jailbreak edilen cihazlardaki öntanımlı "root" parolası: "alpine"
  16. 16. CİHAZ'LA DOSYA ALIŞVERİŞİ İÇİN Jailbreak edilen cihazlardaki öntanımlı "root" parolası: "alpine"
  17. 17. CİHAZ'A KOMUT SATIRI ERİŞİMİ İÇİN Jailbreak edilen cihazlardaki öntanımlı "root" parolası: "alpine"
  18. 18. Jailbreak edilen cihazlardaki öntanımlı "root" parolası: "alpine" CİHAZ'A KOMUT SATIRI ERİŞİMİ İÇİN
  19. 19. iOS jailbreaking is the process of removing software restrictions imposed by iOS, Apple's operating system, on devices running it through the use of software exploits; such devices include the iPhone, iPod touch, iPad, and second-generation Apple TV. Jailbreaking permits root access to the iOS file system and manager, allowing the download of additional applications, extensions, and themes that are unavailable through the official Apple App Store. JAILBREAK NEDİR?
  20. 20. SİMULATOR VE CİHAZ ÜZERİNDEKİ UYGULAMALARIN FARKI NEDİR? SIMULATOR X86
  21. 21. SİMULATOR VE CİHAZ ÜZERİNDEKİ UYGULAMALARIN FARKI NEDİR? CİHAZ ARM
  22. 22. SİMULATOR VE CİHAZ ÜZERİNDEKİ UYGULAMALARIN FARKI NEDİR? SIMULATOR X86
  23. 23. SİMULATOR VE CİHAZ ÜZERİNDEKİ UYGULAMALARIN FARKI NEDİR? CİHAZ ARM
  24. 24. CİHAZ ÜZERİNDE HOSTS DOSYASININ AYARLANMASI
  25. 25. CİHAZ ÜZERİNDE HOSTS DOSYASININ AYARLANMASI HTTP(S) Sunucusu IP Adresi
  26. 26. UYGULAMAYI İLK ÇALIŞTIRMA DENEMESİ Uygulama cihazın Jailbreak'li olduğunu anladı ve uygulamanın devamına izin vermiyor
  27. 27. UYGULAMAYI DEVAM ETTİREBİLMEK İÇİN NE YAPABİLİRİZ? STATİK ANALİZ DİNAMİK ANALİZ ANCAK "BINARY" DÜNYADA SABIRLI OLMALI VE MÜDACELEYE DAYANMALIYIZ !
  28. 28. İLK DİNAMİK ANALİZ DENEMESİ Debug etmek için "btrmobile" prosesine bağlanmaya çalıştığımızda Segmentation Fault hatası alıyoruz
  29. 29. iOS BINARY DEBUGGING'E GİRİŞ • Apple geçmişten bu yana GCC derleyicisini ve GNU Debugger (GDB)'ı desteklemiş, bu açık kaynaklı araçlara Objective C desteğini eklemiştir. • Ancak Apple 2005'ten sonra desteğini GNU toolchain'den LLVM derleyicisine doğru kaydırmıştır. • Bu nedenle Xcode da debug aracı olarak LLDB'yi kullanmaya başlamıştır. Yeni iOS versiyonlarında halen GDB'yi kullanabilirsiniz, ancak Objective C veri yapıları ile ilgili yeterli desteği alamazsınız.
  30. 30. iOS BINARY DEBUGGING'E GİRİŞ XCODE
  31. 31. iOS BINARY DEBUGGING'E GİRİŞ • LLDB debug mimarisi de tıpkı Android'de olduğu gibi istemci sunucu mimarisiyle çalışır. debugserverLLDB Debug Eden Debug Edilen ör: TCP 4444
  32. 32. iOS BINARY DEBUGGING'E GİRİŞ • Normalde bir iOS cihaz debug amaçlı olarak Xcode tarafından kullanılmamışsa üzerinde "debugserver" uygulaması bulunmaz (en azından bizim gözlemimiz bu şekilde). • Eğitimin ilk adımlarında kendi geliştirdiğimiz bir uygulamayı cihaza kurup debug etmeye çalışmamış olsa idik bizim cihazımızda da bulunmayacaktı.
  33. 33. iOS BINARY DEBUGGING'E GİRİŞ • Bu durumda Mac bilgisayar üzerindeki geliştirici CD imajı içinden ARM için derlenmiş olan debugserver uygulamasını alıp cihaza aktarmamız gerekecekti. • Dosyayı aktarmadan önce ayrıca yeni bir entitlements.plist dosyası oluşturarak debugserver uygulamasını bu dosyayı da kullanarak imzalamamız gerekecektir. Bu Mac OS ve iOS dünyalarında uygulanan kontrollere uyulması için gerekli.
  34. 34. iOS BINARY DEBUGGING'E GİRİŞ • Debugserver uygulamasının iOS cihaza aktarılabilmesi için gerekli işlemler hakkında güncel bilgiye şöyle bir arama ile ulaşabilirsiniz:
  35. 35. DEBUG (DİNAMİK ANALİZ) PROBLEMİMİZE TEKRAR DÖNERSEK Statik ve dinamik analiz ikilisinin yanında başka bir yardımcı daha işimize yarayabilir
  36. 36. DEBUG (DİNAMİK ANALİZ) PROBLEMİMİZE TEKRAR DÖNERSEK Kolay ve hızlı bir yolculuk olmayabilir, ama olası yolları keşfetmek için daha iyi bir kaynağımız yok
  37. 37. DEBUG (DİNAMİK ANALİZ) PROBLEMİMİZE TEKRAR DÖNERSEK Bu bizim karşılaştığımız duruma benziyor Ayrıca bir aşma önerisi de var
  38. 38. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM IDA Pro'da ptrace fonksiyonunu arayalım
  39. 39. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM _ptrace fonksiyonuna çift tıkladığımızda bu fonksiyonun adresine atlanan stub prosedürüne ulaşıyoruz Burada IDA bizim için bu instruction'ı bir fonksiyon gibi ayırmış ve _ptrace olarak isimlendirmiş. Bu instruction ile "ptrace" fonksiyonunun import adresini PC (Program Counter) register'ına atıyor uygulama. Dolayısıyla bir sonraki adımda ptrace fonksiyonunun çağrılması sağlanıyor.
  40. 40. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM _ptrace fonksiyon adına tıkladıktan sonra "X" tuşuna bastığımızda bu adrese referans veren (XREF) kod bölümlerini görüyoruz Bu adrese çift tıklayarak bu stub'ın çağrıldığı alana gidelim
  41. 41. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM _ptrace fonksiyonunun çağrıldığı nokta burası (main fonksiyonunun içinde) Objective C dili ve derleyicileri C dilini tam olarak destekliyor. C dilinde olduğu gibi uygulamanın kullanıcı kodları anlamında başlangıç noktası "main" fonksiyonu. Programcı bu fonksiyonun içine bir anti-debug kontrolü yerleştirmiş.
  42. 42. ARM ASSEMBLY'YE GİRİŞ ÖNEMLİ NOT: X86 Assembly biliyorsanız, birazdan bahsi geçecek konuları anlamak daha kolay olacaktır. Bu konuda deneyiminiz yoksa • Hafıza (memory) • Register • Instruction • Stack / Heap • Uygulama akış kontrolü • Calling Convention'ları konularında temel bilgi ihtiyacınız olacaktır. Ayrıca burada 32 bit'lik ARM assembly üzerinde inceleme yapılacaktır. 64 bit'lik ARM x86 ve x64'te de olduğu gibi farklıdır.
  43. 43. ARM ASSEMBLY'YE GİRİŞ ARM REGISTER'larından bazıları R0 (1. parametre olarak kullanılır) R1 (2. parametre olarak kullanılır) R2 (3. parametre olarak kullanılır) R3 (4. parametre olarak kullanılır, bundan sonraki parametreler stack'e yerleştirilir) R4 R5 ... R12 R13 (aynı zamanda SP, Stack Pointer olarak adlandırılır) R14 (aynı zamanda LR, Link Register olarak adlandırılır) R15 (aynı zamanda PC, Program Counter olarak adlandırılır) CPSR (Current Program Status Register, Zero bit ve diğer flag'leri barındırır)
  44. 44. ARM ASSEMBLY'YE GİRİŞ ARM INSTRUCTION'larından bazıları Genel Instruction Yapısı • Instruction {Condition} {Condition Flag'i Güncelle} Örnek: ADD R0, R1, R2 (yani R0=R1+R2) ADDEQ R0, R1, R2 (yani eğer Zero Flag işaretli ise R0=R1+R2) ADDS R0, R1, R2 (yani R0=R1+R2 hesabını yap ve flag'leri güncelle)
  45. 45. ARM ASSEMBLY'YE GİRİŞ ARM INSTRUCTION'larından bazıları Uygulama akışına etki eden instruction'lar • Branch B{<cond>} label • Branch with Link BL{<cond>} sub_routine_label Not: ARM'da RET instruction'ı yoktur. MOV R15, R14 ya da MOV PC, LR instruction'ları ile geri dönülür.
  46. 46. ARM ASSEMBLY'YE GİRİŞ ARM INSTRUCTION'larından bazıları Uygulama akışına etki eden instruction'lar (devamı) • BL (Thumb subroutine'e geçişte kullanılır) • BLX (ARM subroutine'e geçişte kullanılır, mod değiştirilebilir) • Thumb modunda instruction'lar 16 bit uzunluğundadır. • ARM modunda instruction'lar 32 bit uzunluğundadır. • ARM bir RISC (Reduced Instruction Set Computer), yani az sayıda instruction'dan oluşan bir mimaridir. • Buna karşılık X86 bir CISC (Complex Instruction Set Computer) mimarisidir ve çok daha özellikli instruction'ları barındırır.
  47. 47. ARM ASSEMBLY'YE GİRİŞ ARM INSTRUCTION'larından bazıları Karşılaştırma instruction'ları Bu instruction'ların tek işlevi condition flag'lerini (Zero flag'de bunlardan birisidir) güncellemektir. Bu yüzden S ekini almalarına gerek yoktur. <Operation>{<cond>} Rn, Operand2 • CMP operand1 - operand2 (sonuç herhangi bir register'a yazılmaz) • CMN operand1 + operand2 (sonuç herhangi bir register'a yazılmaz) • TST operand1 AND operand2 (sonuç herhangi bir register'a yazılmaz) • TEQ operand1 EOR operand2 (sonuç herhangi bir register'a yazılmaz)
  48. 48. ARM ASSEMBLY'YE GİRİŞ ARM INSTRUCTION'larından bazıları Karşılaştırma instruction'ları (devamı) Örnek: • CMP R0, R1 • TSTEQ R2, #5
  49. 49. ARM ASSEMBLY'YE GİRİŞ ARM INSTRUCTION'larından bazıları Veri atama instruction'ları <Operation>{<cond>}{S} Rd, Operand2 Örnek: • MOV R0, R1 • MOVS R2, #10 • MVNEQ R1,#0
  50. 50. ARM ASSEMBLY'YE GİRİŞ ARM INSTRUCTION'larından bazıları Load / Store instruction'ları Register'lar ve hafıza arasında veri yükleme ve saklama işlemlerini sağlarlar: Load and Store Word or Byte (LDR / STR / LDRB / STRB) Load and Store Halfword ( LDRH / STRH)
  51. 51. ARM ASSEMBLY'YE GİRİŞ ARM INSTRUCTION'larından bazıları Load / Store instruction'ları (devamı) Örnek: STR R0, [R1] (R0 register değerini R1 register'ı ile işaret edilen hafıza alanına sakla) LDR R2, [R1] (R2 register'ına R1 register'ı ile işaret edilen hafıza alanındaki değeri yükle)
  52. 52. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM ARM Assembly Giriş bölümünde anlatılanlardan sonra bu instruction'ın bir Branch instruction'ı olduğunu rahatlıkla görebiliriz ARM ile ilgili bilgi dağarcığımıza eklememiz gereken önemli bir bilgi de "genellikle" çağrılan fonksiyonların döndürdükleri değeri R0 register'ına atamalarıdır.
  53. 53. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM Öyle görünüyor ki _ptrace fonksiyonu çağrıldıktan sonra yakın bir gelecekte "R0" register'ı kullanılmıyor. _ptrace fonksiyonunun tersine mühendisliğini yapma zahmetine girmeden uğradığımız sıkıntıyı aşma yolu olarak _ptrace fonksiyonunun çağrıldığı noktayı geçersiz hale getireceğiz. Ancak bu seçimin riskli olduğunu yine de belirtmeliyiz. Çünkü teorik olarak fonksiyonun değiştirebileceği farklı register'lar da olabilir ve bu değerler program akışı için önemli olabilir. Belki de daha güvenli yol _ptrace fonksiyonunu çağırırken kullanılan fonksiyon parametrelerini değiştirmek olabilirdi.
  54. 54. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM Önce yamalayacağımız alanı daha rahat görebilmek ve belirlemek için Opcode'ları görünür hale getirelim.
  55. 55. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM Opcode'lar Assembly kodlarının binary halleri. 2 byte olarak gördüğünüz satırlar Thumb instructionları. 4 byte olarak gördüğünüz satırlar ARM instruction'ları. Bunların yanında 4 byte daha görüyorsanız bu değerler de hafıza adresleridir.
  56. 56. DİNAMİK ANALİZ PROBLEMİMİZİ STATİK ANALİZ İLE İNCELEYELİM Yamalayacağımız opcode'ların ilk byte'ına tıkladıktan sonra Hex View'a geçersek aynı opcode değerlerini burada da görebiliriz. Amacımız _ptrace fonksiyonunun çağrılmasına neden olan bu opcode'ları pasifize etmek. Bunun için bu alana Thumb modunda 2 adet (yani toplam 16 x 2 = 32 bit'lik) NOP instruction'ı yerleştireceğiz.
  57. 57. BINARY ARM KODUNU YAMALAMA NOP opcode'larını bulmak için belki de en kolay yol Google'da bu konuyu aramak olurdu. Ama biz balık tutmayı öğrenelim ve herhangi bir ARM Assembly kodunu opcode'larına nasıl çevirebileceğimizi (yani Assemble edebileceğimizi) görelim. Yukarıda .thumb ifadesi ile Assembly instruction'larımızın Thumb modunda derlenmesini istiyoruz. _start label'ı ise uygulamanın başlangıcını belirtmek için kullanılıyor.
  58. 58. BINARY ARM KODUNU YAMALAMA Burada kullandığımız toolchain'i şu komutla Ubuntu'ya yükledik: "sudo apt-get install binutils-arm-linux-gnueabi" Derliyoruz Linkliyoruz
  59. 59. BINARY ARM KODUNU YAMALAMA Derlenmiş kodumuzun opcode'larını görebilmek için disassemble ediyoruz. Bunun için yine aynı toolchain ile gelen aşağıdaki aracı kullanıyoruz: "arm-linux-gnueabi-objdump -d ARM" Burada aslında NOP instruction'ının R8 register'ında bir değişikliğe neden olmayan MOV R8, R8 olduğunu da görebiliyoruz.
  60. 60. BINARY ARM KODUNU YAMALAMA NOP opcode'umuzun "46 c0" olduğunu gördüğümüze göre artık uygulamamızı yamalayabiliriz. Buna göre önce IDA Pro'da Hex View'a geçtikten sonra uygun noktada imlecimizi konumlandırıp Edit / Patch program / Change byte seçeneğini seçmeliyiz.
  61. 61. BINARY ARM KODUNU YAMALAMA Opcode'ları değiştirirken "little endian" veri formatını unutmamamız lazım. Bu nedenle "46 c0" opcode'larını yazarken "c0 46" biçiminde yazıyoruz. Eski Yeni
  62. 62. BINARY ARM KODUNU YAMALAMA IDA View'a tekrar geçtiğimizde amacımıza ulaştığımızı görüyoruz.
  63. 63. BINARY ARM KODUNU YAMALAMA Yaptığımız yamayı binary koda aktarmak IDA ile çok kolay
  64. 64. BINARY ARM KODUNU YAMALAMA Yamalanmış kodumuzu "btrmobile" ismi ile kopyaladıktan sonra cihazımızın "Bundle" dizinine atıyoruz. (Cihaz üzerindeki dizin yapısına daha sonra değineceğiz)
  65. 65. DEBUG ENGELİNİ AŞMA Cihaz üzerindeki uygulamayı kapatarak yeni binary'yi tekrar başlattıktan sonra debugserver hatasız olarak uygulamaya "attach" olabildi
  66. 66. SIRA LLDB'DE • LLDB açık kaynak kodlu bir debug client ve Linux üzerinde de derlenebiliyor. Ancak (eğitimin hazılanma tarihi itibarıyla) Linux için dağıtılan paket içinde "remote-ios" desteği bulunmamaktaydı. • Bu problemi aşmak için bir yama mevcut ancak LLDB'nin derlenmesi öncesinde yapılması gereken LLVM derlemesi v.s. işler çok uzun sürdüğü için biz Mac platformunu kullanmayı tercih ettik.
  67. 67. SIRA LLDB'DE
  68. 68. AMACIMIZ JAILBREAK KONTROLÜNÜ AŞMAK • Ve bunu dinamik analiz yöntemiyle aşmayı deneyeceğiz. • Ancak daha önce de belirttiğimiz ve gözlemlediğimiz gibi dinamik analiz, statik analiz ile desteklendiğinde daha etkili olabiliyor. • Jailbreak kontrolünü aşmak için izleyeceğimiz strateji şu şekilde: • Kontrolün uygulandığı View Controller'ın class adını öğreneceğiz • "btrmobile" binary kodu içinde yer alan sınıf, metod ve özellik bilgilerini elde edeceğiz • Elde ettiğimiz bilgiler ışığında Jailbreak kontrolünün nerede uygulanıyor olabileceğini tahmin etmeye çalışacağız • Bu incelememizi IDA ile reversing yaparak da destekleyeceğiz • LLDB ile kontrolün yapıldığını düşündüğümüz noktaya "BREAKPOINT" koyacağız ve çalışma anında manipülasyon yaparak kontrolü atlatacağız.
  69. 69. ŞU ANDA HANGİ VIEW CONTOLLER'IN İÇİNDEYİZ DESTEKLER Cycript aracı çalışma anı manipülasyonu için kullanılır, Javascript syntax'ını destekler. Cycript ve daha sonra değineceğimiz SSL Kill Switch gibi uygulamalar Cydia Substrate'in getirdiği Metod Hooking imkanından faydalanır. Cycript hedef proses'e bir debugger gibi bağlandıktan sonra sorgulama ve manipülasyon işlemlerini gerçekleştirebiliriz.
  70. 70. ŞU ANDA HANGİ VIEW CONTOLLER'IN İÇİNDEYİZ Uygulamayı foreground'da tutarken Cycript'te aktif View Controller class'ını sorguluyoruz loginVC View Controller Class'ı aktif iken Jailbreak kontrolü gerçekleşiyor
  71. 71. "loginVC" CLASS'I VE DİĞER CLASS'LAR HAKKINDA BİLGİ EDİNME
  72. 72. "loginVC" CLASS'I VE DİĞER CLASS'LAR HAKKINDA BİLGİ EDİNME
  73. 73. "loginVC" CLASS'I VE DİĞER CLASS'LAR HAKKINDA BİLGİ EDİNME loginVC View Controller Class'ının metodları içinde doğrudan Jailbreak kontrolüne ilişkin bir isim göremiyoruz. Ancak Jailbreak kontrolü login düğmesine basıldığında gerçekleştiğinden "btnLogin" metodunun içinde aradığımızı bulma ihtimalimiz var.
  74. 74. DERLENMİŞ BINARY BİR DOSYADAN BU KADAR BİLGİYİ NASIL ALABİLDİK • Bu sorunun cevabı Objective C Runtime işleyişinde saklı. • Objective C messaging tabanlı bir runtime ortamına sahip. Yani uygulama derlenirken (örneğin bir C uygulamasında olduğu gibi) uygulama akışı içinde çağrılan tüm fonksiyon ve metodların adresleri uygulama içine gömülmüyor. • Bunun yerine çağrılacak metodun ait olduğu SINIF ADI, ve METODUN ADI (nın adres referansları) daha önce değindiğimiz R0 ve R1 register'larına yazıldıktan sonra objc_msgSend() fonksiyonu çağrılıyor.
  75. 75. DERLENMİŞ BINARY BİR DOSYADAN BU KADAR BİLGİYİ NASIL ALABİLDİK • objc_msgSend fonksiyon prototipi: • objc_msgSend(receiver, selector, arg1, arg2, ...) • Yukarıda arg1, arg2, ... Olarak geçen parametreler çağrılan metoda aktarılacak olan parametrelerdir. • objc_msgSend fonksiyonu çağrılan metod ilgili sınıf içinde tanımlanmamışsa ISA pointer'ından da faydalanarak üst sınıflarda arar.
  76. 76. DERLENMİŞ BINARY BİR DOSYADAN BU KADAR BİLGİYİ NASIL ALABİLDİK • Objective C Runtime çalışma şekli IDA Pro gibi araçlarla uygulama akışını anlamamızı zorlaştırırken (çünkü tüm metod çağrıları tek bir fonksiyona doğru görünür, çoğu durumda da mesaj fonksiyonunun adresi bir register'da tutulduğundan bu bile belirsizleşir), diğer taraftan da sembol bilgilerinin oldukça zengin biçimde binary dosya içinde kalmasına neden olduğundan statik analizi kolaylaştırır.
  77. 77. "btnLogin" METODU Jailbreak'e ilişkin sınıf ve metod adlarını gözlemleyebiliyoruz Bu atamalardan sonraki ilk Branch instruction'ı Branch with Link bir fonksiyon çağrısı anlamına geliyor Çağrılan metodun döndürdüğü değer (R0 register'ı) "0" ile karşılaştırılıyor ve Branch kararı veriliyor
  78. 78. "btnLogin" METODU Yeşil kol karşılaştırmanın doğru olduğu durumda izleniyor String'lerden yola çıkarak bu yolun Jailbreak kontrolünün aşıldığı yol olduğunu söyleyebiliriz
  79. 79. DENEYİMLİ BİR TERSİNE MÜHENDİSLİK UZMANI NE YAPARDI? IDA'da Search / sequence of bytes seçeneği ile Unicode strings ve Find all occurences seçeneklerini de seçerek kontrolün görüntülediği mesaj string'inin bir parçasını tespit etmeye çalışırdı
  80. 80. DENEYİMLİ BİR TERSİNE MÜHENDİSLİK UZMANI NE YAPARDI? Text Search yapsak bu veriyi bulamazdık, çünkü IDA bunun bir string olduğunu anlamamış Yine Unicode arama yapmasaydık bu veriye ulaşamazdık, çünkü her ASCII karakterden sonra bir "0" byte'ı var, ayrıca Türkçe karakterler de mevcut
  81. 81. DENEYİMLİ BİR TERSİNE MÜHENDİSLİK UZMANI NE YAPARDI? "C" karakterinin sağında bulunan _cfstring referansına tıkladıktan sonra "X" tuşuna basarak bu adrese referans veren alanları görebiliriz. Görünen her iki alan da loginVC sınıfının btnLogin metoduna işaret ediyor
  82. 82. DENEYİMLİ BİR TERSİNE MÜHENDİSLİK UZMANI NE YAPARDI? Bunlardan birine tıklayarak btnLogin metoduna ulaştığımızda daha önce gördüğümüz Branch instruction'ının sol tarafındaki akışa rastgeldiğimizi görebiliyoruz Bu şekilde farklı bir yoldan da hedef alanımızı tespit edebilirdik
  83. 83. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA Yaptığımız statik analiz sonrasında kontrolün "isJailbroken" metodunda uygulandığını tahmin etmiştik Stratejimiz bu metoda breakpoint koyarak metod çağrıldıktan sonra döndüreceği R0 register değerine müdahale etmek olacak
  84. 84. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA IDA'da isJailbroken metodunu fonksiyon listesinde aradığımızda bu metodun "JailbreakKontrol" class'ı içinde bulunduğunu görüyoruz Ayrıca Objective C syntax'ına göre baştaki "+" işareti bu metodun Statik bir metod olduğunu ifade ediyor
  85. 85. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA LLDB ile debugserver'a bağlandıktan sonra bu metoda breakpoint koyalım
  86. 86. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA "c" komutuyla uygulamanın devam etmesine izin verdikten sonra cihazda uygulamanın "Giriş" düğmesine basalım ve breakpoint noktamıza ulaşalım (NOT: LLDB eğer projenin kaynak kodları bilgisayar üzerinde ise kaynak kod seviyesinde debug yapıyor. Assembly seviyesinde ilerleyebilmek için proje dizininin isminin değiştirilmesi lazım)
  87. 87. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA LLDB komutlarından bazıları: • b (breakpoint koyma) • br l (breakpoint noktalarını listeleme) • register read (tüm register değerlerini listeleme) • register write r0 0 (R0 register'ına 0 değerini atama) • finish (içinde bulunduğumuz metodun tamamlanarak bir sonraki instruction'a dönme) • c (devam etme) • disassemble --pc (Program Counter'dan itibaren disassemble et) • ni (instruction seviyesinde step over işlemi)
  88. 88. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA "finish" komutu ile "isJailbreak" metodunu tamamlayarak çağıran fonksiyona dönelim
  89. 89. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA Yerimizi tam olarak anlamak için "disassemble --pc" komutu ile Program Counter'dan itibaren birkaç instruction'ı disassemble edelim
  90. 90. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA "ni" komutu ile instruction seviyesinde bir step over işlemini gerçekleştirelim Not: "n" komutu instruction seviyesinde değil, kaynak kod seviyesinde satır atlamaktadır
  91. 91. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA Tekrar "disassemble --pc" komutunu işleterek konumumuzu kontrol edelim Şu anda tam olarak isJailbroken metodundan dönen değerin (R0 register değerinin) kontrol edildiği noktadayız
  92. 92. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA "register read" komutu ile register değerlerini okuduğumuzda R0 register'ının değerinin "1" olduğunu görürüz
  93. 93. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA "register write r0 0" komutu ile R0 register'ına "0" değerine atayalım
  94. 94. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA Uygulamayı çalışma anında manipüle ettikten sonra "c" komutu ile uygulamanın devam etmesine izin verelim
  95. 95. RUNTIME MANİPÜLASYON İLE JAILBREAK KONTROLÜNÜ ATLATMA Uygulamamız Jailbreak'li bir cihaz üzerinde çalışmasına devam etti ve login olabildik
  96. 96. JAILBREAK KONTROLÜNÜ KALICI OLARAK KALDIRMA Jailbreak kontrolünü kalıcı olarak kaldırabilmek için yine yamalama yolunu izlememiz lazım
  97. 97. JAILBREAK KONTROLÜNÜ KALICI OLARAK KALDIRMA IDA'da Hex View penceresinde Edit / Patch program / Change byte seçeneğini seçerek "00" değerini "01" olarak değiştiriyoruz
  98. 98. JAILBREAK KONTROLÜNÜ KALICI OLARAK KALDIRMA IDA View ekranında da bu değişikliğin sonucunu gözlemliyoruz Bu değişiklikle uygulama Jailbreak'li bir cihaz üzerinde her zaman çalışmaya devam edecek
  99. 99. JAILBREAK KONTROLÜNÜ KALICI OLARAK KALDIRMA Gerçekleştirdiğimiz yamayı binary dosyaya aktarıyoruz (Unutmayın IDA üzerinde yaptığınız tüm değişiklikler IDA'nın ürettiği veritabanında gerçekleşir, uygulamanın kendi üzerinde değil)
  100. 100. JAILBREAK KONTROLÜNÜ KALICI OLARAK KALDIRMA Son olarak yamalanmış binary dosyayı cihaza aktarıyoruz
  101. 101. HTTP(S) İSTEKLERİNDE ARAYA GİRME Artık uygulamayı çalıştırmaya ve HTTP(S) sunucusu ile iletişimini incelemeye hazırız Ancak HTTPS servislerine araya girmek istediğimizde attack proxy'miz (Burp'ü kullanacağız) kendi CA sertifikası ile sahte sertifikalar üretecek Eğer karşımızda bir browser olsaydı kolaylıkla bu sertifikaya güven diyerek ilerleyebilirdik Ancak mobil uygulamalarda bu şansımız yok Bu nedenle Burp'ün CA sertifikasını cihazımıza yüklememiz gerekiyor Eklenen güvenilen sertifikaları cihaz üzerinde Ayarlar / Genel / Profiller bölümünden görebiliriz Şu anda henüz bir sertifika yüklenmediği için bu bölüm görünmüyor
  102. 102. HTTP(S) İSTEKLERİNDE ARAYA GİRME Burp'ün kullandığı CA sertifikasını cihaza yüklemeden önce Burp'ü çalıştırıyoruz
  103. 103. HTTP(S) İSTEKLERİNDE ARAYA GİRME Cihaz üzerinde Safari Browser'ı ile Burp'ün çalıştığı bilgisayarın 8080 portuna bağlanıyoruz Karşımıza çıkan sayfadaki "CA Certificate" linki ile bu sertifikayı indirerek cihaza tanıtıyoruz
  104. 104. HTTP(S) İSTEKLERİNDE ARAYA GİRME 1 2 3
  105. 105. HTTP(S) İSTEKLERİNDE ARAYA GİRME Bu şekilde Burp'ün CA sertifikasını güvenilir sertifika olarak yüklemiş olduk SSL Pinning uygulamayan ve OpenSSL gibi platform API'leri dışındaki kütüphaneleri kullanmayan uygulamaların HTTPS bağlantıları için artık rahatlıkla araya girebiliriz
  106. 106. HTTP(S) İSTEKLERİNDE ARAYA GİRME Proxy ayarını Wi-Fi ayarlarının bulunduğu menüde uyguluyoruz Bu andan itibaren standart platform API'lerini (ör: NSURLConnection, NSURLDownload) kullanan mobil uygulamalar için araya girebileceğiz
  107. 107. HTTP(S) İSTEKLERİNDE ARAYA GİRME Burp'ün test web sunucumuzu bulabilmesi için Burp'ün üzerinde çalıştığı bilgisayarda "hosts" dosyasını düzenlemeyi de unutmayalım
  108. 108. HTTP(S) İSTEKLERİNDE ARAYA GİRME İlk isteğimizi yaptığımızda Burp bir alarm mesajı üretti
  109. 109. HTTP(S) İSTEKLERİNDE ARAYA GİRME Cihazın üzerinde "btrmobile" uygulamasının ürettiği logları incelediğimizde de NSURLErrorDomain hatası aldığımızı gördük Açıkçası bu hatayı araştırdığımızda bizi doğrudan SSL Pinning'e bağlayan bir kaynak bulamadık Ancak daha önce çalışan bir uygulamanın araya girildiğinde hata üretmesi SSL Pinning ile ilgili bir şüphe doğurmalı
  110. 110. SSL PINNING KONTROLÜ VE AŞILMASI SSL Pinning Nedir? SSL pinning aslında aşağıdakilerden herhangi birine verilen genel addır: • Uygulamanın cihaz üzerinde yüklü trusted sertifikalara güvenmeden kendi paketinde yer alan bir sertifika dosyası veya kendi içinde tanımlanmış bir değişken değeri ile kendi trust store'unu oluşturması ve sertifika doğrulama için kullanması
  111. 111. SSL PINNING KONTROLÜ VE AŞILMASI SSL Pinning Nedir? (devamı) • Uygulamanın sunucunun gönderdiği sertifikanın tamamını kendi paketinde yer alan bir sertifika dosyası veya kendi içinde tanımlanmış bir değişken değeri ile karşılaştırması, aynı olmaları halinde SSL bağlantısını kurması (Certificate Pinning olarak da anılır) • Uygulamanın sunucunun gönderdiği sertifikanın içinde yer alan Public Key ile kendi paketinde yer alan bir dosya veya kendi içinde tanımlanmış bir değişken değeri ile karşılaştırması, aynı olmaları halinde SSL bağlantısını kurması (Public Key Pinning olarak da anılır)
  112. 112. SSL PINNING KONTROLÜ VE AŞILMASI SSL Pinning Nedir? (devamı) Ne yazık ki SSL pinning'i tam olarak teşhis edebilmek için uygulama geliştirme bilgisine ve tersine mühendislik çalışmasına ihtiyaç var. iOS uygulamalarda asenkron URL bağlantısı kurabilmek için bazı delegate metodları tanımlamak gerekiyor. Asenkron bağlantı kullanıcı arayüzünün HTTP yanıtını beklerken donmaması için önemli bir ihtiyaç. Bu delegate metodlarından birisi ve SSL pinning'in uygulanması için en uygun metodun adı "willSendRequestForAuthenticationChallenge". Bu durum genel teamül olsa da SSL pinning'i çok çeşitli biçimlerde uygulayabilirsiniz.
  113. 113. SSL PINNING KONTROLÜ VE AŞILMASI URL bağlantı hatasını yine loginVC view controller class'ı içinde alıyoruz Bu class içinde asenkron HTTP bağlantılarında kullanılan "willSendRequestForAuthenticationChallenge" metodunu görüyoruz Bu metodu incelediğimizde de uygulamanın kendi içinde bir Trust Store oluşturduğu ve buna güvendiğine ilişkin emareler var Bu emarelerden birisi de _SecTrustEvaluate fonksiyonunun çağrılıyor olması
  114. 114. SSL PINNING KONTROLÜ VE AŞILMASI Ayrıca kodun üst bölümlerinde bir sertifika dosyasına erişildiği de anlaşılıyor Bu dosya güvenilen CA sertifika(lar)ını içeriyor olmalı
  115. 115. SSL PINNING KONTROLÜ VE AŞILMASI Uygulamanın bundle dizini içinde de "btriskCA" doyasını görebiliyoruz İyi bir tersine mühendislik analiziyle bu dosyanın içeriğinin değiştirilmesi de SSL pinning kontrolünü aşmamıza imkan sağlayabileceğini de görebiliriz
  116. 116. SSL PINNING KONTROLÜ VE AŞILMASI Ne yazık ki _SecTrustEvaluate fonksiyonuna referans veren çok sayıda metod var Bu metodların her birine yama yapmak veya run time manipülasyon yapmak çok zahmetli olabilir
  117. 117. SSL PINNING KONTROLÜ VE AŞILMASI İşte şimdi bir araç çok işimize yarayabilir SSL Kill Switch daha önce de bahsettiğimiz Cydia Substrate'in imkanlarını kullanıyor Android'in aksine Cydia Substrate'in desteği iOS için oldukça iyi
  118. 118. SSL PINNING KONTROLÜ VE AŞILMASI SSL Kill Switch ne yapar?
  119. 119. SSL PINNING KONTROLÜ VE AŞILMASI SSL Kill Switch ne yapamaz? • Eğer programcı standart platform API'leri yerine OpenSSL veya benzeri farklı bir kütüphaneyi kullanırsa SSL Kill Switch etkisiz kalır. • Aslında bu durumda yaptığımız proxy ayarı dahi etkisiz olacaktır. Bu yüzden trafiği proxy üzerinden geçirmek için cihaz üzerinde "port forwarding" yapmak gerekecektir. • Böyle bir uygulama için tersine mühendislik becerisi çok gerekli olacaktır.
  120. 120. SSL PINNING KONTROLÜ VE AŞILMASI SSL Kill Switch aracını aktif ettiğimizde HTTPS isteklerimizi Burp üzerinde görmeye başlayabiliriz
  121. 121. KRİPTOLU VERİNİN ANLAŞILMASI Login isteğinde araya girebildik Ancak içerik anlaşılabilir bir formatta değil
  122. 122. KRİPTOLU VERİNİN ANLAŞILMASI Hex formatta görünen bu veriyi ASCII olarak decode ettiğimizde de anlamlı bir veriye ulaşamıyoruz Eğer kriptolu bir veri ile karşı karşıya isek bu veriyi ancak dinamik analiz ile uygulamanın hafıza alanında gözlemleyebiliriz
  123. 123. KRİPTOLU VERİNİN ANLAŞILMASI Daha önce de olduğu gibi debugserver'ı başlatalım ve lldb ile bu servise bağlanalım
  124. 124. KRİPTOLU VERİNİN ANLAŞILMASI Kriptolu veri login aşamasında gönderildiğinden btnLogin metoduna breakpoint koyalım ve "c" komutu ile uygulamanın akışına izin verelim
  125. 125. KRİPTOLU VERİNİN ANLAŞILMASI Uygulamanın "Giriş" düğmesine bastığımızda breakpoint noktasında duracağız Bu noktada PC register'ının bulunduğu alanı disassemble ediyoruz ve kodların hafızadaki adreslerini gözlemliyoruz Bu adresler IDA'da gözlemleyeceğimiz adreslerden farklı olacak, çünkü iOS ASLR desteği olan bir işletim sistemi Bu yüzden de uygulama her yüklendiğinde farklı bir adrese yerleştiriliyor Ancak ASLR'ın karakteristiği gereği son 3 adres rakamı değişmiyor
  126. 126. KRİPTOLU VERİNİN ANLAŞILMASI IDA'da adres bilgilerini görebilmek için "Line prefixes" seçeneğini aktif hale getirelim
  127. 127. KRİPTOLU VERİNİN ANLAŞILMASI Emek yoğun bir çalışma sonunda btnLogin metodunun son kısımlarına yakın bir alanda kriptolamayla ilişkili olabileceği düşünülebilecek doCipher metodunun çağrıldığı alanı bulabiliriz
  128. 128. KRİPTOLU VERİNİN ANLAŞILMASI Bu metod adının geçtiği bölüme en yakın olan Branch with Link instruction'ı da aşağıdaki instruction Bu satırın adresine baktığımızda son 3 rakamının "A0C" olduğunu görebiliyoruz
  129. 129. KRİPTOLU VERİNİN ANLAŞILMASI ASLR'ın son 3 rakamı değiştirmediğini söylemiştik Buna göre mevcut oturumumuzda btnLogin metodunun adreslerinin ilk 3 rakamını ve IDA'dan elde ettiğimiz son 3 rakamı kullanarak bir breakpoint tanımlıyoruz Daha sonra "c" komutu ile uygulamayı devam ettiriyoruz ve uygulama breakpoint noktasına geldiğinde duruyor
  130. 130. KRİPTOLU VERİNİN ANLAŞILMASI Bu noktada register değerlerini okuyoruz Objective C runtime ve objc_msgSend metodu ile ilgili söylediklerimizi hatırlarsanız objc_msgSend metodu çağrıldığı anda R0'da class adresi, R1'de metod adı (selector) ve bundan sonraki 2 register'da da çağrılan metodun parametrelerinin bulunduğunu belirtmiştik
  131. 131. KRİPTOLU VERİNİN ANLAŞILMASI Breakpoint koyduğumuz instruction'da R12 register'ında bulunan adres çağrılıyordu Runtime'da bu değerin objc_msgSend olduğunu görebiliyoruz
  132. 132. KRİPTOLU VERİNİN ANLAŞILMASI R2 register'ının işaret ettiği adres ilk parametre olmalı Bu adresteki 4 byte'lık ilk 10 HEX değere baktığımızda aşağıdaki sonuca ulaşıyoruz
  133. 133. KRİPTOLU VERİNİN ANLAŞILMASI Muhtemelen bu adreste bir object'in hafıza adresi var (kaynak kod'da bu nesnenin NSData tipinde olduğunu biliyoruz ) Açıkçası elimizde sadece binary uygulama olmuş olsa idi bu değerlerden adrese benzeyenleri aşağıdaki gibi denemekten başka bir yolumuz olmayacaktı Burada 5. 4 byte'lık değerin içerdiği adresi "string" tipinde okuyoruz
  134. 134. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK • Eğitim süresince kendi geliştirdiğimiz "btrmobile" uygulamasını kullandık. • Eğer Appstore'dan bir uygulama indirerek test etmemiz gerekseydi tersine mühendislik ve debug etme işlemlerimizi bu kadar kolay uygulayamazdık. • Çünkü store'a yüklenen uygulamalar (sadece çalıştırılabilir Mach-o dosyası, diğer bundle dosyaları değil) cihazımıza kriptolu olarak iniyorlar. Bu yüzden ilk olarak kriptoyu açmamız gerekiyor.
  135. 135. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK APPSTORE'dan indirdiğimiz bir uygulamayı inceleyelim
  136. 136. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Bu uygulamayı class-dump-z ile incelemek istediğimizde yukarıdaki uyarıyı alıyoruz
  137. 137. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK class-dump-z bizi uyarsa da bir çıktı üretti, bu çıktıyı inceleyelim
  138. 138. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK class-dump-z 'nin ürettiği çıktının önemli bir kısmı (tamamı değil) anlamı olmayan isimlerden oluşuyor
  139. 139. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Bu binary dosyanın başlık alanlarını incelemek için dosyayı Mac'e aktaralım
  140. 140. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK LC_ENCRYPTION_INFO load command bölümünde dosyanın kriptolu olduğu belirtiliyor (Crypt ID : 1) Crypt Offset alanı kriptolu verilerin başlangıç offset adresini, Crypt Size alanı ise bu adresten itibaren toplam kriptolu veri miktarını belirtiyor
  141. 141. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Aynı bilgiyi cihaz üzerinde "otool" aracı ile de görebiliriz. Bu load command nedeniyle iOS işletim sistemi bu binary'yi hafızaya yüklerken decrypt etmesi gerektiğini ve nereden başlayarak ne kadar veriyi decrypt etmesi gerektiğini anlıyor ve uygulamayı buna göre hafızaya yüklüyor
  142. 142. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Normalde bu uygulamanın decrypt edilmiş haline manuel yöntemlerle ulaşabiliriz Bunun için çalışmakta olan prosese bir debugger ile attach olduktan sonra LC_ENCRYPTION_INFO load command'ında belirtilen offset ve veri büyüklüğü bilgilerinden yola çıkarak hafızada yer alan ve zaten işletim sistemi tarafından decrypt edilmiş olan veriyi diske yazabiliriz (dump edebiliriz) Daha sonra dump ettiğimiz decrypt edilmiş bu veriyi diskteki orijinal dosyaya yazabiliriz Son olarak Crypt ID bilgisini "0" yaptıktan ve dosyayı imzaladıktan sonra istediğimiz dinamik ve statik analizleri kolaylıkla yapabiliriz Ama tüm bunları bizim için yapan bir araç varken bu kadar zahmete değmez
  143. 143. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Clutch2 uygulaması ile cihaza yüklü Appstore uygulamalarını listeleyebiliriz "Clutch2 –h" komutu ile Clutch'ın kullanım opsiyonlarını görebiliriz "Clutch2 –b" komutu ile yukarıda listelenen bir uygulamanın numarasını kullanarak decrypt etme işlemini gerçekleştirebiliriz
  144. 144. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Clutch2 uygulaması decrypt ettiği binary dosyaları /private/var/tmp/clutch dizini altına atar
  145. 145. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Clutch ile decrypt ettiğimiz dosyayı class- dump-z ile tekrar işleyelim
  146. 146. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Class ve metod listesini tekrar inceleyelim
  147. 147. APPSTORE'DAN İNDİRİLEN UYGULAMALARIN TESTİNE HAZIRLIK Görüldüğü gibi class-dump-z binary dosya içinde class ve metod isimlerini okuyabildi
  148. 148. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ Uygulama kullanım durumlarını gerçekleştirerek cihaz üzerinde saklanabilecek verilerin üretimini gerçekleştirelim
  149. 149. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – DİZİN YAPISI Uygulama dizinleri /private/var/mobile/Applications altında bir UUID numarasından oluşan dizinin içinde yer alır
  150. 150. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – DİZİN YAPISI Documents dizini veri sızması açısından en verimli dizindir Uygulama bu dizin altında yeni dosya ve veri oluşturabilir Documents dizini iTunes ile yedekleme sırasında bilgisayara da kopyalanır Ayrıca cihaz Jailbreak edilmese dahi bu dizin altındaki dosyalara iExplorer gibi araçlarla erişebilirsiniz
  151. 151. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – DİZİN YAPISI Uygulama adı ile başlayan ve sonu ".app" ile biten dizin "bundle" olarak da adlandırılan, uygulamanın kurulumu ile birlikte gelen pakettir. Bu dizin altındaki veriler statik'tir ve kurulum sonrasında uygulama tarafından değiştirilemez. Uygulamanın binary dosyası da bu dizin içindedir. Dizin içinde tüm dosyalar ortaya saçılmış gibi görülebilir, ancak Xcode proje organizasyonunu sağlamak için kendi içinde dosyaları gruplama imkanı sağlar
  152. 152. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – DİZİN YAPISI Library dizini zannedilebileceği gibi bir kod kütüphanesi barındırmaz, uygulamayı destekleyen verilerin oluştuğu ve biriktiği bir başka alandır Documents dizini kadar olmasa da bu dizin altında da veri sızma riski büyüktür
  153. 153. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – DİZİN YAPISI Örneğimizde "tmp" dizini altında bir veri oluşmuyor, ancak testler sırasında bir göz atmakta fayda olabilir Bu dizin altındaki veriler uygulamanın çalışması sona erdiğinde gereksiz hale gelecek dosyalar olmalıdır Bu dosyaların yedekleri de alınmaz
  154. 154. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYCHAIN • Keychain Mac OS'un ve iOS'un trusted özelliği bozulmamış (yani Jailbreak edilmemiş) platformlarda sağladığı güvenli veri saklama alanıdır • Jailbreak edilmiş bir sistemde eğer cihaz herhangi bir passcode ile korunmuyorsa (ki bizim test sistemlerimiz doğal olarak korunmuyor) tüm Keychain verileri okunabilir. Aksi takdirde bruteforce ile passcode'un kırılması gerekir • Keychain kayıtları ne zaman erişilebilecekleri (ör: cihaz ekran kilitli iken uygulamalar erişebilmeli mi), yedeklenip yedeklenmeyecekleri (yani bu kayıt sadece bu cihazda mı kullanılabilir), hangi uygulamalar belli bir kayda erişebilir (access group tanımlaması ile) gibi konularda detaylı güvenlik fonksiyonalitesine sahiptir
  155. 155. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYCHAIN Statik analizde uygulamanın Security framework'ü altında "SecItemAdd" gibi fonksiyonları kullanması Keychain'in kullanıldığına dair güçlü bir emaredir
  156. 156. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYCHAIN Keychain dosyası /private/var/Keychains dizini altındaki keychain-2.db SQLite veritabanıdır
  157. 157. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYCHAIN Keychain içeriği https://github.com/ptoomey3/Keychain- Dumper/blob/master/keychain_dumper adresinden indirilebilecek "keychain_dumper" aracı ile incelenebilir
  158. 158. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – PLIST DOSYALARI Text tabanlı "plist" dosyası örneği
  159. 159. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – BINARY PLIST DOSYALARI Dosyanın başındaki bplist ifadesi plist dosyasının binary formatta olduğunu ifade ediyor
  160. 160. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – BINARY PLIST DOSYALARI Dosyamızı Cyberduck ile Mac bilgisayara indirdikten sonra "plutil –convert xml1 CCInfo.plist" komutu ile dosyamızı binary formattan text formata dönüştürebiliriz
  161. 161. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – SQLITE VERİTABANLARI SQLite veritabanları ve genel olarak pek çok dosya türü için uzantılarının ne olduğunun önemi yoktur Dolayısıyla her zaman .db veya .sqlite uzantısı taşımayabilirler Potansiyel bulunma alanları Documents ve bundle (app) dizinleridir Bundle dizinindeki SQLite veritabanları genellikle öntanımlı ayarların saklanması ve bazen de Documents dizininde oluşturulacak SQLite veritabanı dosyalarının şablonu olarak kullanılır
  162. 162. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – SQLITE VERİTABANLARI Veritabanı dosyasında bizi ilgilendirebilecek 2 tablo göze çarpıyor
  163. 163. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – SQLITE VERİTABANLARI Bunlardan FATURALAR tablosu içinde veri barındırıyor
  164. 164. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – SQLITE VERİTABANLARI GÖRÜŞMELER tablosu ise veri barındırmıyor gibi görünüyor
  165. 165. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – SQLITE VERİTABANLARI "strings" komutuyla dosyayı incelediğimizde ise FATURALAR tablo kayıtlarının dışına GORUSMELER tablosu kayıtlarını da görüyoruz Bunun sebebi SQLite'ın veri kayıp riskini azaltmak için uyguladığı yedekleme yöntemi Örneğimizde son silme işleminde silinen kayıtlar veritabanı dosyasında görülüyor "Transaction Begin" ile başlatılan işlemlerde "Commit" işlemi gerçekleştirilmezse tüm silinen kayıtlar dosya içinde kalıyor
  166. 166. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – BINARY COOKIES Android'in aksine iOS kütüphanelerinin cookie desteği bulunmaktadır Bu nedenle bu cookie'lerin bir yerde saklanmaları gerekmektedir İşte o yer Library / Cookies dizinlerinde yer alan Cookies.binarycookies dosyalarıdır
  167. 167. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – BINARY COOKIES Binary cookie'leri http://www.securitylearn.net/2012/1 0/27/cookies-binarycookies-reader/ sitesinden edinilebilecek BinaryCookieReader.py Python script'i ile okuyabiliriz
  168. 168. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – BINARY COOKIES python BinaryCookieReader.py Cookies.binarycookies
  169. 169. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – SNAPSHOT RESİMLERİ Uygulama arka plana atıldığında o anki ekran görüntüsü uygulamanın Library/Caches/Snapshots dizini altındaki dizinlere kaydedilir
  170. 170. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – SNAPSHOT RESİMLERİ Uygulama background'a geçmeden hemen önce uygulama delegate metodları kullanılarak hassas bilgi alanları karartılmalıdır - (void)applicationWillResignActive:(UIApplication *)application Uygulama tekrar foreground'a gelmeden önce, benzer biçimde karartılan view alanları tekrar görünür hale getirilebilir - (void)applicationDidBecomeActive:(UIApplication *)application
  171. 171. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYBOARD CACHE iOS'un sağladığı autocomplete imkanının kullanılabilmesi için uygun alanlardaki veriler /private/var/mobile/Library/Keyboard dizini altındaki dosyalara kaydedilir Numerik veriler ve parola alanlarına girilen veriler kaydedilmezler
  172. 172. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYBOARD CACHE Testlerimize başlamadan önce Keyboard Cache'i temizlemek için Ayarlar -> Genel -> Sıfırlama-> Klavye Sözlüğünü Sıfırla seçeneğini kullanabiliriz
  173. 173. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYBOARD CACHE Örnek olarak alfabetik karakterlerle bir kullanıcı kodu girelim
  174. 174. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYBOARD CACHE
  175. 175. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – KEYBOARD CACHE Hassas alanlarda autocomplete özelliğini pasif hale getirmek için bu text alanının "secure" olarak işaretlenmesi: mytextField.secureTextEntry = YES ya da autocomplete'in iptal edilmesi gereklidir: mytextField.autocorrectionType = UITextAutocorrectionTypeNo
  176. 176. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – HTTP YANIT CACHE'LERİ Uygulamamızda UIWebView class'ından bir view kullanılmadığı için cache'lenen herhangi bir veri yok Ama olsa idi ve web sunucu cache'lenebilir bir yanıt verse idi bu yanıtlarla ilgili bilgileri bu SQLite veritabanında gözlemleyebilecektik
  177. 177. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – UYGULAMA LOGLARI NSLog fonksiyonu ile yazılan uygulama logları /private/var/log dizini altında bulunan "syslog" dosyasına yazılır Uygulama logları sandbox kontrolü ile korunmaz, dolayısıyla loga yazılan veriler diğer uygulamalar tarafından okunabilir
  178. 178. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN İNCELENMESİ – UYGULAMA LOGLARI Cihaz üzerindeki loglar cihaz tekrar başlatılıncaya kadar bulunur

×