通過看一些文檔發(fā)現越獄有風險,但是風險還是在可控范圍內的,所以touchid用于交易還是可行的。
一越獄存在的問題
理論上iPhone越獄沒有安全性可言,所有安裝在你手機的APP都以root權限運行,它們可以
?任意讀寫文件系統(tǒng)數據
?HTTP(S)實時被監(jiān)測
?重新打包ipa
?暴露的函數符號
?未加密的靜態(tài)字符
?篡改程序邏輯控制流
?攔截系統(tǒng)框架API
?逆向加密邏輯
?跟蹤函數調用過程(objc_msgSend)
?可見視圖的具體實現
?偽造設備標識
?可用的URL schemes
runtime任意方法調用
以上安全風險都基于一個前提:安裝了一個惡意APP或插件。所以只要自己注意不要下載到這些東西就不會有問題。越獄后不知名的APP就不要下了,特別是那些只有盜版市場有的APP。不知名的盜版市場最好也不好用,cydia的源不要隨意添加,下載插件要謹慎。
另外實際上AppStore上的APP在越獄環(huán)境下也不是絕對安全的,因為蘋果也檢測不到這些APP有沒有做以上那些不軌之事。對于在盜版市場下載知名APP,似乎跟在AppStore上下載沒區(qū)別,目前沒見到有安裝包被注入程序,不像Android市場。像支付寶這樣敏感的APP數據是有加密的,就算獲取了也沒那么容易破解。所以也不用太擔心在越獄機器上用它們不安全。雖然越獄后的iPhone有這么高風險,但比Android安全得多,因為市場環(huán)境好,沒多少惡意APP出現,所以情況還是樂觀的,了解清楚情況,只要稍微注意點就沒問題,至今沒聽說有人因越獄了iPhone損失了什么
二越獄防護
一般而言完美越獄的設備,是非常危險的,通過腳本動態(tài)庫注入,可以修改app的方法實現。所以盡量少越獄,即使越獄也不要隨意安裝插件。
1越獄檢測,很多現在常用檢測是判斷
/Applications/Cydia.app
/Library/MobileSubstrate/MobileSubstrate.dylib
這兩個是否存在,但是黑客現可能會改變這些工具的安裝路徑,躲過你的判斷。
但比較好的辦法是通過檢測當前程序運行的環(huán)境變量:
?voidprintEnv(void)
?{
?char*env?=?getenv("DYLD_INSERT_LIBRARIES");
?NSLog(@"%s",?env);
?}
未越獄設備返回結果是null,越獄設備就各有各的精彩了,尤其是老一點的iOS版本越獄環(huán)境。
2敏感交易的時候我們可以做一次校驗判斷是否正版app,通過二進制文件的驗證,來確定app的安全性。
網上的方法是讀取沙盒的程序二進制經過md5加密后做一些處理傳給服務器驗證,這個我也沒想好。
3 GDB是大多數hackers的首選,阻止GDB依附是應用的常規(guī)辦法
?#import?
?
?intmain(intargc,charchar*argv[])
?{
?#ifndef?DEBUG
?ptrace(PT_DENY_ATTACH,0,0,0);
?#endif
?@autoreleasepool{
?returnUIApplicationMain(argc,?argv,nil,?NSStringFromClass([WQMainPageAppDelegateclass]));
?}
?}
但遺憾的是,iPhone真實的運行環(huán)境是沒有sys/ptrace.h拋出的。雖然ptrace方法沒有被拋出,但是不用擔心,我們可以通過dlopen拿到它。
dlopen:當path參數為0是,他會自動查找$LD_LIBRARY_PATH,$DYLD_LIBRARY_PATH, $DYLD_FALLBACK_LIBRARY_PATH和當前工作目錄中的動態(tài)鏈接庫.
1#import?
2#import?
3
4typedefint(*ptrace_ptr_t)(int_request,?pid_t?_pid,?caddr_t?_addr,int_data);
5#if?!defined(PT_DENY_ATTACH)
6#define?PT_DENY_ATTACH?31
7#endif??//?!defined(PT_DENY_ATTACH)
8
9voiddisable_gdb()?{
10void*?handle?=?dlopen(0,?RTLD_GLOBAL?|?RTLD_NOW);
11ptrace_ptr_t?ptrace_ptr?=?dlsym(handle,"ptrace");
12ptrace_ptr(PT_DENY_ATTACH,?0,?0,?0);
13dlclose(handle);
14}
15
16intmain(intargc,charchar*argv[])
17{
18#ifndef?DEBUG
19disable_gdb();
20#endif
21@autoreleasepool{
22returnUIApplicationMain(argc,?argv,nil,?NSStringFromClass([WQMainPageAppDelegateclass]));
23}
}
4敏感的邏輯代碼重寫為C的代碼
把函數名隱藏在結構體里,以函數指針成員的形式存儲。
這樣做的好處是,編譯后,只留了下地址,去掉了名字和參數表,提高了逆向成本和攻擊門檻。
也許,程序中存在一個類似這樣的類:
?@interfaceXXUtil?:?NSObject
?
?+?(BOOL)isVerified;
?+?(BOOL)isNeedSomething;
?+?(void)resetPassword:(NSString*)password;
?
@end
改寫的程序如下:
?//XXUtil.h
?#import?
?
?typedefstruct_util?{
?BOOL(*isVerified)(void);
?BOOL(*isNeedSomething)(void);
?void(*resetPassword)(NSString*password);
?}XXUtil_t?;
?
?#define?XXUtil?([_XXUtil?sharedUtil])
?
?@interface_XXUtil?:?NSObject
?
?+?(XXUtil_t*)sharedUtil;
?@end
24//XXUtil.m
25#import?"XXUtil.h"
26
27staticBOOL_isVerified(void)
28{
29//bala?bala?...
30returnYES;
31}
32
33staticBOOL_isNeedSomething(void)
34{
35//bala?bala?...
36returnYES;
37}
38
39staticvoid_resetPassword(NSString*password)
40{
41//bala?bala?...
42}
43
44staticXXUtil_t*?util?=NULL;
45@implementation_XXUtil
46
47+(XXUtil_t*)sharedUtil
48{
49staticdispatch_once_t?onceToken;
50dispatch_once(&onceToken,?^{
51util?=?malloc(sizeof(XXUtil_t));
52util->isVerified?=?_isVerified;
53util->isNeedSomething?=?_isNeedSomething;
54util->resetPassword?=?_resetPassword;
55});
56returnutil;
57}
58
59+?(void)destroy
60{
61util???free(util):?0;
62util?=NULL;
63}
@end
最后,根據Xcode的報錯指引,把以前這樣的調用
[XXUtilisVerified];
對應改成:
XXUtil->isVerified();
5數據保護API
文件系統(tǒng)中的文件、keychain中的項,都是加密存儲的。當用戶解鎖設備后,系統(tǒng)通過UDID密鑰和用戶設定的密碼生成一個用于解密的密碼密鑰,存放在內存中,直到設備再次被鎖,開發(fā)者可以通過Data
Protection API來設定文件系統(tǒng)中的文件、keychain中的項應該何時被解密。
1)文件保護
?/*為filePath文件設置保護等級*/
?NSDictionary*attributes?=?[NSDictionarydictionaryWithObject:NSFileProtectionComplete
?forKey:NSFileProtectionKey];
?[[NSFileManagerdefaultManager]setAttributes:attributes
?ofItemAtPath:filePath
?error:nil];
//文件保護等級屬性列表
NSFileProtectionNone//文件未受保護,隨時可以訪問(Default)
NSFileProtectionComplete//文件受到保護,而且只有在設備未被鎖定時才可訪問
NSFileProtectionCompleteUntilFirstUserAuthentication//文件收到保護,直到設備啟動且用戶第一次輸入密碼
NSFileProtectionCompleteUnlessOpen//文件受到保護,而且只有在設備未被鎖定時才可打開,不過即便在設備被鎖定時,已經打開的文件還是可以繼續(xù)使用和寫入
2)keychain項保護
1/*設置keychain項保護等級*/
2NSDictionary*query?=?@{(__bridgeid)kSecClass:?(__bridgeid)kSecClassGenericPassword,
3(__bridgeid)kSecAttrGeneric:@"MyItem",
4(__bridgeid)kSecAttrAccount:@"username",
5(__bridgeid)kSecValueData:@"password",
6(__bridgeid)kSecAttrService:[NSBundlemainBundle].bundleIdentifier,
7(__bridgeid)kSecAttrLabel:@"",
8(__bridgeid)kSecAttrDescription:@"",
9(__bridgeid)kSecAttrAccessible:(__bridgeid)kSecAttrAccessibleWhenUnlocked};
10
11OSStatus?result?=?SecItemAdd((__bridge?CFDictionaryRef)(query),NULL);
1//keychain項保護等級列表
2kSecAttrAccessibleWhenUnlocked//keychain項受到保護,只有在設備未被鎖定時才可以訪問
3kSecAttrAccessibleAfterFirstUnlock//keychain項受到保護,直到設備啟動并且用戶第一次輸入密碼
4kSecAttrAccessibleAlways//keychain未受保護,任何時候都可以訪問(Default)
5kSecAttrAccessibleWhenUnlockedThisDeviceOnly//keychain項受到保護,只有在設備未被鎖定時才可以訪問,而且不可以轉移到其他設備
6kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly//keychain項受到保護,直到設備啟動并且用戶第一次輸入密碼,而且不可以轉移到其他設備
7kSecAttrAccessibleAlwaysThisDeviceOnly//keychain未受保護,任何時候都可以訪問,但是不能轉移到其他設備
for example
把一段信息infoStrng字符串寫進文件,然后通過Data
Protection API設置保護。
1NSString*documentsPath?=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,?NSUserDomainMask,YES)firstObject];
2NSString*filePath?=?[documentsPathstringByAppendingPathComponent:@"DataProtect"];
3[infoStringwriteToFile:filePath
4atomically:YES
5encoding:NSUTF8StringEncoding
6error:nil];
7NSDictionary*attributes?=?[NSDictionarydictionaryWithObject:NSFileProtectionComplete
8forKey:NSFileProtectionKey];
9[[NSFileManagerdefaultManager]setAttributes:attributes
10ofItemAtPath:filePath
11error:nil];
設備鎖屏(帶密碼保護)后,即使是越獄機,在root權限下cat讀取那個文件信息也會被拒絕。
參考鏈接:
http://blog.csdn.net/yiyaaixuexi/article/category/1302847/1
這個妹子是阿里安全部的,很厲害啊。。。。
微博:程序媛念茜