ios 越獄與安全性分析

通過看一些文檔發現越獄有風險,但是風險還是在可控范圍內的,所以touchid用于交易還是可行的。

一越獄存在的問題

理論上iPhone越獄沒有安全性可言,所有安裝在你手機的APP都以root權限運行,它們可以

?任意讀寫文件系統數據

?HTTP(S)實時被監測

?重新打包ipa

?暴露的函數符號

?未加密的靜態字符

?篡改程序邏輯控制流

?攔截系統框架API

?逆向加密邏輯

?跟蹤函數調用過程(objc_msgSend)

?可見視圖的具體實現

?偽造設備標識

?可用的URL schemes

runtime任意方法調用

以上安全風險都基于一個前提:安裝了一個惡意APP或插件。所以只要自己注意不要下載到這些東西就不會有問題。越獄后不知名的APP就不要下了,特別是那些只有盜版市場有的APP。不知名的盜版市場最好也不好用,cydia的源不要隨意添加,下載插件要謹慎。

另外實際上AppStore上的APP在越獄環境下也不是絕對安全的,因為蘋果也檢測不到這些APP有沒有做以上那些不軌之事。對于在盜版市場下載知名APP,似乎跟在AppStore上下載沒區別,目前沒見到有安裝包被注入程序,不像Android市場。像支付寶這樣敏感的APP數據是有加密的,就算獲取了也沒那么容易破解。所以也不用太擔心在越獄機器上用它們不安全。雖然越獄后的iPhone有這么高風險,但比Android安全得多,因為市場環境好,沒多少惡意APP出現,所以情況還是樂觀的,了解清楚情況,只要稍微注意點就沒問題,至今沒聽說有人因越獄了iPhone損失了什么

二越獄防護

一般而言完美越獄的設備,是非常危險的,通過腳本動態庫注入,可以修改app的方法實現。所以盡量少越獄,即使越獄也不要隨意安裝插件。

1越獄檢測,很多現在常用檢測是判斷

/Applications/Cydia.app

/Library/MobileSubstrate/MobileSubstrate.dylib

這兩個是否存在,但是黑客現可能會改變這些工具的安裝路徑,躲過你的判斷。

但比較好的辦法是通過檢測當前程序運行的環境變量:

?voidprintEnv(void)

?{

?char*env?=?getenv("DYLD_INSERT_LIBRARIES");

?NSLog(@"%s",?env);

?}

未越獄設備返回結果是null,越獄設備就各有各的精彩了,尤其是老一點的iOS版本越獄環境。

2敏感交易的時候我們可以做一次校驗判斷是否正版app,通過二進制文件的驗證,來確定app的安全性。

網上的方法是讀取沙盒的程序二進制經過md5加密后做一些處理傳給服務器驗證,這個我也沒想好。

3 GDB是大多數hackers的首選,阻止GDB依附是應用的常規辦法

?#import?

?

?intmain(intargc,charchar*argv[])

?{

?#ifndef?DEBUG

?ptrace(PT_DENY_ATTACH,0,0,0);

?#endif

?@autoreleasepool{

?returnUIApplicationMain(argc,?argv,nil,?NSStringFromClass([WQMainPageAppDelegateclass]));

?}

?}

但遺憾的是,iPhone真實的運行環境是沒有sys/ptrace.h拋出的。雖然ptrace方法沒有被拋出,但是不用擔心,我們可以通過dlopen拿到它。

dlopen:當path參數為0是,他會自動查找$LD_LIBRARY_PATH,$DYLD_LIBRARY_PATH, $DYLD_FALLBACK_LIBRARY_PATH和當前工作目錄中的動態鏈接庫.

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

文件系統中的文件、keychain中的項,都是加密存儲的。當用戶解鎖設備后,系統通過UDID密鑰和用戶設定的密碼生成一個用于解密的密碼密鑰,存放在內存中,直到設備再次被鎖,開發者可以通過Data

Protection API來設定文件系統中的文件、keychain中的項應該何時被解密。

1)文件保護

?/*為filePath文件設置保護等級*/

?NSDictionary*attributes?=?[NSDictionarydictionaryWithObject:NSFileProtectionComplete

?forKey:NSFileProtectionKey];

?[[NSFileManagerdefaultManager]setAttributes:attributes

?ofItemAtPath:filePath

?error:nil];

//文件保護等級屬性列表

NSFileProtectionNone//文件未受保護,隨時可以訪問(Default)

NSFileProtectionComplete//文件受到保護,而且只有在設備未被鎖定時才可訪問

NSFileProtectionCompleteUntilFirstUserAuthentication//文件收到保護,直到設備啟動且用戶第一次輸入密碼

NSFileProtectionCompleteUnlessOpen//文件受到保護,而且只有在設備未被鎖定時才可打開,不過即便在設備被鎖定時,已經打開的文件還是可以繼續使用和寫入

2keychain項保護

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

這個妹子是阿里安全部的,很厲害啊。。。。

微博:程序媛念茜

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容