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. 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.
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. 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. 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
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?
26. UYGULAMAYI İLK ÇALIŞTIRMA DENEMESİ
Uygulama cihazın
Jailbreak'li olduğunu
anladı ve uygulamanın
devamına izin vermiyor
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. İ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. 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.
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. 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. 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. 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:
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
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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. BINARY ARM KODUNU YAMALAMA
IDA View'a tekrar
geçtiğimizde amacımıza
ulaştığımızı görüyoruz.
63. BINARY ARM KODUNU YAMALAMA
Yaptığımız yamayı binary koda
aktarmak IDA ile çok kolay
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. 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. 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.
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. Ş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. Ş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
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. 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. 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. 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. "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. "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. 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. 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. 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. 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. 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. 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. RUNTIME MANİPÜLASYON İLE JAILBREAK
KONTROLÜNÜ ATLATMA
LLDB ile debugserver'a
bağlandıktan sonra bu metoda
breakpoint koyalım
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. 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)
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. 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. 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. 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
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. 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. JAILBREAK KONTROLÜNÜ KALICI OLARAK
KALDIRMA
Jailbreak kontrolünü kalıcı olarak
kaldırabilmek için yine yamalama
yolunu izlememiz lazım
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. 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. 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)
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. HTTP(S) İSTEKLERİNDE ARAYA GİRME
Burp'ün kullandığı CA
sertifikasını cihaza yüklemeden
önce Burp'ü çalıştırıyoruz
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
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. 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. 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
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. 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. 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. 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. 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. 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. 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. 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. 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
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. SSL PINNING KONTROLÜ VE AŞILMASI
SSL Kill Switch aracını aktif ettiğimizde HTTPS
isteklerimizi Burp üzerinde görmeye başlayabiliriz
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
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. 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
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. 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. 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. 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. 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. 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. 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. 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.
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. 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. 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. 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
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. 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. 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. 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. 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. 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. 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. 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
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. 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. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN
İNCELENMESİ – SQLITE VERİTABANLARI
Veritabanı dosyasında bizi
ilgilendirebilecek 2 tablo göze
çarpıyor
163. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN
İNCELENMESİ – SQLITE VERİTABANLARI
Bunlardan FATURALAR tablosu
içinde veri barındırıyor
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. 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. 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. 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
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. 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. 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. 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. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN
İNCELENMESİ – KEYBOARD CACHE
Örnek olarak alfabetik karakterlerle bir kullanıcı kodu girelim
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. 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. 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. CİHAZ ÜZERİNDEKİ HASSAS VERİLERİN
İNCELENMESİ – UYGULAMA LOGLARI
Cihaz üzerindeki loglar cihaz tekrar başlatılıncaya kadar bulunur