開篇先扯幾句題外話,許多朋友都問我怎么不寫防啊,我確實有點猶豫。 hackers 總是想象如果自己是開發(fā)者會怎么寫,然后才能找到入手點。同理,開發(fā)者們也要想象自己是 hackers 會怎么做,才能采取相應的防御措施。然后,就是一場遞歸的博弈。
拿越獄檢測這件事來說,起初大家只需判斷有無安裝 Cydia 就好了,hackers 們說好,那我就不安裝 Cydia 也可以動手腳。開發(fā)者們又說,那你一定得用的上 MobileSubstrate ,bash ,ssh 吧,我去檢測手機有沒有安裝這些工具??墒怯钟惺裁从媚??你判斷什么我繞過去什么。
當 class-dump 大肆流行,函數(shù)符號都被暴露,開發(fā)者想盡辦法藏起自己的敏感函數(shù)代碼。hackers 們也知道 class-dump 的死穴在哪里,于是新的檢索辦法油然而生。也就說,當一個防御手段成為流行,它就不會再是個讓 hackers 大罵“真特么費勁”的防御手段了。比如之前介紹的一個小技巧:內(nèi)存數(shù)據(jù)擦除 ,hackers 知道開發(fā)者都去擦數(shù)據(jù)了,那我 hook memset 在你擦之前去讀就好了。開發(fā)者說:我直接寫硬盤上然后刪除!hackers 說:難道你沒聽說過文件恢復?
http://wiki.jikexueyuan.com/project/ios-security-defense/images/data-erase1.png" alt="data-erase1" />
OK,貧的有點多了,本文介紹一下防御相關的話題—— iOS 的數(shù)據(jù)保護 API 。
文件系統(tǒng)中的文件、keychain 中的項,都是加密存儲的。當用戶解鎖設備后,系統(tǒng)通過 UDID 密鑰和用戶設定的密碼生成一個用于解密的密碼密鑰,存放在內(nèi)存中,直到設備再次被鎖,開發(fā)者可以通過 Data Protection API 來設定文件系統(tǒng)中的文件、keychain 中的項應該何時被解密。
/* 為filePath文件設置保護等級 */
NSDictionary *attributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete
forKey:NSFileProtectionKey];
[[NSFileManager defaultManager] setAttributes:attributes
ofItemAtPath:filePath
error:nil];
//文件保護等級屬性列表
NSFileProtectionNone //文件未受保護,隨時可以訪問 (Default)
NSFileProtectionComplete //文件受到保護,而且只有在設備未被鎖定時才可訪問
NSFileProtectionCompleteUntilFirstUserAuthentication //文件收到保護,直到設備啟動且用戶第一次輸入密碼
NSFileProtectionCompleteUnlessOpen //文件受到保護,而且只有在設備未被鎖定時才可打開,不過即便在設備被鎖定時,已經(jīng)打開的文件還是可以繼續(xù)使用和寫入
/* 設置keychain項保護等級 */
NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrGeneric:@"MyItem",
(__bridge id)kSecAttrAccount:@"username",
(__bridge id)kSecValueData:@"password",
(__bridge id)kSecAttrService:[NSBundle mainBundle].bundleIdentifier,
(__bridge id)kSecAttrLabel:@"",
(__bridge id)kSecAttrDescription:@"",
(__bridge id)kSecAttrAccessible:(__bridge id)kSecAttrAccessibleWhenUnlocked};
OSStatus result = SecItemAdd((__bridge CFDictionaryRef)(query), NULL);
//keychain項保護等級列表
kSecAttrAccessibleWhenUnlocked //keychain項受到保護,只有在設備未被鎖定時才可以訪問
kSecAttrAccessibleAfterFirstUnlock //keychain項受到保護,直到設備啟動并且用戶第一次輸入密碼
kSecAttrAccessibleAlways //keychain未受保護,任何時候都可以訪問 (Default)
kSecAttrAccessibleWhenUnlockedThisDeviceOnly //keychain項受到保護,只有在設備未被鎖定時才可以訪問,而且不可以轉(zhuǎn)移到其他設備
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly //keychain項受到保護,直到設備啟動并且用戶第一次輸入密碼,而且不可以轉(zhuǎn)移到其他設備
kSecAttrAccessibleAlwaysThisDeviceOnly //keychain未受保護,任何時候都可以訪問,但是不能轉(zhuǎn)移到其他設備
把一段信息 infoStrng 字符串寫進文件,然后通過 Data Protection API 設置保護。
NSString *documentsPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"DataProtect"];
[infoString writeToFile:filePath
atomically:YES
encoding:NSUTF8StringEncoding
error:nil];
NSDictionary *attributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete
forKey:NSFileProtectionKey];
[[NSFileManager defaultManager] setAttributes:attributes
ofItemAtPath:filePath
error:nil];
設備鎖屏(帶密碼保護)后,即使是越獄機,在 root 權限下 cat 讀取那個文件信息也會被拒絕。
http://wiki.jikexueyuan.com/project/ios-security-defense/images/data-erase2.jpeg" alt="data-erase2" />