在前面的文章中,我們看到了如何使用調(diào)試器和工具如Cycript對(duì)iOS應(yīng)用進(jìn)行運(yùn)行時(shí)分析和操作。我們也看到了在運(yùn)行時(shí)通過使用GDB來修改寄存器的值是如何修改方法的具體實(shí)現(xiàn)的,看到了怎樣使用工具如Cycript來進(jìn)行swizzling方法實(shí)現(xiàn)。有Cycript和GDB這樣的工具在手,加上你的應(yīng)用程序可執(zhí)行文件的拷貝,一切就都在攻擊者的掌控之中。不過,有一些技巧能夠使得攻擊者更難攻擊。本文我們將查看開發(fā)者能夠用來對(duì)抗運(yùn)行時(shí)分析和操作的防御技巧。
在Xcode中,開發(fā)者(譯者注:原文寫的是攻擊者,按上下文理解應(yīng)該是開發(fā)者)能夠使用一些檢測(cè)方法來查看一個(gè)應(yīng)用是否正被調(diào)試。在Xcode中,你可以用下面的代碼來檢查調(diào)試器是否存在。
#ifndef DEBUG
SEC_IS_BEING_DEBUGGED_RETURN_NIL();
#endif
正如名字指出的,如果應(yīng)用正被調(diào)試,那么這個(gè)宏會(huì)返回nil。你可以把這個(gè)檢查放到一些重要的地方,比如訪問或者返回重要數(shù)據(jù)的地方。如果在那時(shí)(訪問或者返回重要數(shù)據(jù)的時(shí)候)應(yīng)用正被調(diào)試,這個(gè)宏就會(huì)返回nil。因此你的應(yīng)用就不會(huì)工作正常,因此攻擊者就會(huì)遇到問題?;蛘吣憧梢栽谝粋€(gè)Timer中調(diào)用,一旦你發(fā)現(xiàn)應(yīng)用正被調(diào)試,你可以刪除存儲(chǔ)在應(yīng)用中的所有重要信息、重要文件等等。但是,請(qǐng)注意攻擊者使用Cycript能夠劫持你的方法實(shí)現(xiàn),因此比較明智的是只使用一個(gè)宏而不是在一個(gè)方法內(nèi)使用這個(gè)宏。請(qǐng)注意這個(gè)宏只在release下能工作正常。要在你的設(shè)備上測(cè)試,你需要在build中選擇release。選擇scheme,然后點(diǎn)擊Edit Scheme。

在Info下面,把Build Configuration設(shè)置為Release。

現(xiàn)在你可以使用Xcode在你的設(shè)備上運(yùn)行這個(gè)應(yīng)用,你會(huì)看到成功檢測(cè)到調(diào)試器。這是因?yàn)閄code會(huì)給正在運(yùn)行的應(yīng)用附加一個(gè)調(diào)試器。
再次說一下,這個(gè)方法并不能保證應(yīng)用不會(huì)被調(diào)試。一個(gè)技藝熟練的攻擊者能夠?qū)?yīng)用程序的二進(jìn)制文件對(duì)這個(gè)宏相關(guān)的匯編指令打補(bǔ)丁。作為開發(fā)者,你應(yīng)該在多個(gè)地方檢查,使得攻擊者更難調(diào)試。
另一個(gè)阻止調(diào)試器附加到應(yīng)用程序的方法是使用ptrace函數(shù)。使用這個(gè)函數(shù),傳遞一個(gè)特定的參數(shù),能夠阻止其它任何調(diào)試器附加到應(yīng)用程序上。像GDB和LLDB在附加到進(jìn)程的時(shí)候就會(huì)使用ptrace函數(shù)。使用ptrace,加上參數(shù)PT_DENY_ATTACH就會(huì)告訴這個(gè)函數(shù),應(yīng)用不允許追蹤。下面是蘋果官方文檔關(guān)于PT_DENY_ATTACH的截圖。

讓我們?cè)囋?。在Xcode中創(chuàng)建一個(gè)新工程。點(diǎn)擊File->New->Project->Single View Application。然后在模擬器中運(yùn)行。你會(huì)得到如下的視圖。

現(xiàn)在,使用如下的代碼來修改main.m文件。導(dǎo)入ptrace.文件,然后在main函數(shù)中增加如下代碼。
#ifndef DEBUG
ptrace(PT_DENY_ATTACH, 0, 0, 0);
#endif
你的main.m看起來應(yīng)該像這樣。

現(xiàn)在運(yùn)行程序,你會(huì)發(fā)現(xiàn)應(yīng)用加載不起來。這是因?yàn)楫?dāng)Xcode加載應(yīng)用的時(shí)候,它會(huì)把一個(gè)調(diào)試器(LLDB或者GDB)附加到應(yīng)用上。因?yàn)槲覀冊(cè)趍ain.m中加了反調(diào)試代碼,因此Xcode不能附加調(diào)試器,因此它就退出應(yīng)用。
雙擊模擬器上的home按鈕,然后kill這個(gè)測(cè)試應(yīng)用。再次運(yùn)行,這次能夠啟動(dòng)起來。這是因?yàn)槲覀儧]有通過Xcode加載,因此沒有調(diào)試器附加到上面。
當(dāng)然,這個(gè)方法也不能保證你的應(yīng)用就絕對(duì)安全。技術(shù)熟練的攻擊者能夠在解密應(yīng)用之后對(duì)這個(gè)防檢測(cè)代碼打補(bǔ)丁。作為開發(fā)者,你應(yīng)該在多個(gè)地方使用這個(gè)方法,使得攻擊者的工作變得更難。
需要注意的事,上述兩種方法都將試圖阻止調(diào)試器加載到應(yīng)用上,但是它對(duì)Cycript沒有用,因?yàn)镃ycrit并不追蹤應(yīng)用。作為開發(fā)者,你能夠做下面的一些檢查使得攻擊者的工作變得盡可能的難。例如,你可以在應(yīng)用中增加一些假的方法,攻擊者可能會(huì)對(duì)這些假方法感興趣。例如,用userDidLogin:(BOOL)didLogin;作為名字,肯定會(huì)吸引攻擊者的注意。當(dāng)然,攻擊者會(huì)試圖用Cycript執(zhí)行。在這個(gè)方法實(shí)現(xiàn)中,你可以清除應(yīng)用中的所有數(shù)據(jù),甚至報(bào)告服務(wù)器,這個(gè)應(yīng)用已經(jīng)被侵入。對(duì)于特別需要安全的銀行應(yīng)用,你也可以檢查設(shè)備是否已經(jīng)越獄。如果是,可以拒絕所有訪問服務(wù)器并且刪除所有存在應(yīng)用本地的重要信息。在下一篇文章中,我們將查看如何檢查設(shè)備是否越獄。另一件需要做的事情就是檢查應(yīng)用是否被破解,然后執(zhí)行必要的步驟來防止攻擊者獲取信息。在github上有一個(gè)很簡(jiǎn)單的類可以幫你完成這個(gè)工作。當(dāng)然,攻擊者總是能夠劫持方法實(shí)現(xiàn)的,因此,把它改一個(gè)不那么起疑的名字。
對(duì)于那些檢查應(yīng)用是否安全的方法,你也可以給它們改個(gè)名字以便它們看起來不那么重要。例如,一個(gè)檢查應(yīng)用是否正被調(diào)試的方法不應(yīng)該被命名為-(BOOL)isAppBeingDebugged。這肯定將會(huì)引起攻擊者的注意并替換方法實(shí)現(xiàn)。相反,命名為-(BOOL)didChangeColor或者-(BOOL)didSetFont。就不錯(cuò)。這個(gè)情況下,這個(gè)函數(shù)在攻擊者看來就不那么重要了。
如果你已經(jīng)檢測(cè)到可疑行為,并且認(rèn)為最好退出應(yīng)用,你可以使用下面的命令。
exit(-1);
這將退出應(yīng)用。
最好,一個(gè)需要注意的非常重要的一點(diǎn)就是,沒有任何應(yīng)用在一個(gè)技藝熟練的攻擊者面前是安全的。有你的應(yīng)用的二進(jìn)制文件的拷貝,加上Cycript、GDB等工具在手,一切就都在攻擊者的掌控之中。我們能做的就是使用盡可能多的檢查,使得攻擊者的任務(wù)變得困難以至于他放棄我們的應(yīng)用去找那些更容易攻擊的應(yīng)用。
原文網(wǎng)址:http://resources.infosecinstitute.com/ios-application-security-part-23-defending-runtime-analysis-manipulation/