周凡
摘 要 在Android手機廣泛普及的今天,其被惡意程序攻擊、病毒感染、信息復制等事件頻頻發(fā)生。Android應用安全問題自然也引起人們的更多關注。結合Android體系架構的特點,本文主要是通過ptrace注入的方式對Android手機軟件進程代碼注入攻擊與防御進行研究,從而提高Android應用的安全性。
關鍵詞 Android系統(tǒng) ptrace注入
現(xiàn)在Android手機應用已有案例遭到代碼注入攻擊:由于應用是通常運行在Dalvik虛擬機上的,其底層依然是C和C++環(huán)境。攻擊者進程通常偽裝成gdb調(diào)試器對指定進程進行調(diào)試,然后遠程調(diào)用dlopen使指定進程加載預先寫好的惡意SO代碼,從而竊取相關關鍵信息。
1 ptrace原理
程序員的任務就是寫程序,寫完程序就是調(diào)程序,估計沒人敢說自己寫程序不用調(diào)試的,尤其是程序規(guī)模龐大了之后更是如此,第一個實現(xiàn)調(diào)試器的是一個偉大的人,個人見解:ptrace就是為gdb而生的,ptrace應該算是gdb的核心了。
2 Android下的ptrace注入
ptrace讓調(diào)試變得方便,也讓程序變得不安全。
對于每一個Android應用,都對應一個Dalvik虛擬機,其上層是JAVA實現(xiàn),下層又有支持C、C++的JNI環(huán)境 ,按照上述ptrace原理,可以在JNI環(huán)境下使用ptrace通過注入的方式使一個Android應用執(zhí)行我們自己寫的JAR包。由于是執(zhí)行在指定Android應用的進程空間中,我們的JAR包可以很方便的修改、獲取該應用中的數(shù)據(jù)。
2.1時序圖原理
時序圖的基本流程如下:
(1)通過Shell指令執(zhí)行Inject,Aseck在執(zhí)行時必須擁有root權限。
(2)可執(zhí)行文件Inject的流程非常通用,arm平臺上無需更改。
(3)加載的libJavaLoader.so文件流程也是通用的,無需更改。
(4)加載的Jar包中必須保證有一個無參構造函數(shù)和一個execInject函數(shù),至于execInject函數(shù)的邏輯可以按需隨意更改。
2.2進程注入過程的主要依賴關系介紹
(1)在ndk環(huán)境下使用ndk-build命令編譯jni文件夾中的內(nèi)容。
(2)Invader是一個lib項目,也就是將要注入的jar包,首先生成temp.jar,然后執(zhí)行dx-dex-output=invader.jar temp.jar生成dex包,將生成的invader.jar放在assets/dexjar文件夾下。
2.3基于ptrace的執(zhí)行詳細流程
(1)首先啟動Aseck程序,在adb中PS出想要注入的進程pid,輸入之,Aseck會根據(jù)pid找到對應的processName,然后將inject和libJavaLoader.so拷貝至本地進程所屬文件夾,將invader.jar拷貝到pid進程所屬文件夾。
(2)Aseck獲取root權限,使用shell執(zhí)行inject程序。
(3)執(zhí)行Inject詳細流程:
①ptrace attach掛起指定pid進程。
②保存進程2程序執(zhí)行上下文。
③計算進程2中dlopen、dlsym、mmap等函數(shù)首地址。
④使用ptrace_call在進程2中調(diào)用mmap函數(shù)開內(nèi)存用于存放待注入的匯編指令。
3手機軟件進程代碼注入防御
經(jīng)過測試,現(xiàn)階段Arm平臺上的手機軟件,絕大部分應用都可以注入成功(危險),當前有以下五種防御方案:
第一種是TraceMe,此方案的缺點是,一旦開啟此狀態(tài)就不能關閉,但現(xiàn)階段是最優(yōu)化的解決方案。
第二種是比較父進程ID,實測在內(nèi)核版本較高的系統(tǒng)上,此方法已不在有效;
第三種是查看/proc/pid/status文件,當進程被注入時,此文件中會有一項TracerPID標識出注入進程ID;但如果檢查的不夠頻繁可能由于外部進程注入時間過短而錯過。
第四種是查看/proc/pid/fdinfo下的所有fd信息,當進程被注入時,需要打開so文件,因而增加了新的fd,此方式的局限性在于文件描述符的控制上,假如當前應用正要打開某個文件,那也勢必會增加新的fd。
第五種方案,修改ld動態(tài)庫的符號庫,不過實現(xiàn)可能會對其他代碼產(chǎn)生影響。
4外部進程函數(shù)地址計算
linux的每個執(zhí)行中的進程在內(nèi)存中都映射了一個文件/proc/self/maps,內(nèi)容大致如下:
左邊是某進程中的邏輯地址,右邊是對應加載動態(tài)庫名,以dlopen函數(shù)為例,如果知道本進程內(nèi)的函數(shù)地址,知道本進程內(nèi)其所屬庫/system/bin/linker(/lib/ld-2.8.so) 的起始加載地址,再知道該庫在指定pid進程內(nèi)的起始加載地址,就可以推算出dlopen在指定pid進程內(nèi)的函數(shù)地址。
5結束語
Android手機平臺由于其開源性和免費所帶來的安全缺陷導致其應用在架構層次上存在一些根本性的安全問題。結合Android自身的特點,通過ptrace注入的方式對Android手機軟件進程代碼注入攻擊與防御進行研究,能夠大大地提高Android手機應用的安全性,這種方法具有很好的推廣性,值得進一步深入研究。
參考文獻
[1] 姚華.4大隱患威脅手機支付安全[N].城市快報,2015.
[2] 李光.360攜合作伙伴解決發(fā)起手機支付安全+行動[N].光明網(wǎng)IT頻道,2015.
[3] 史成浩.Android平臺應用軟件保護技術研究與實現(xiàn)[D].2012.