Android安全分析挑戰:運行時篡改Dalvik字節碼 .

本文章由Jack_Jia編寫,轉載請註明出處。  

文章鏈接:http://blog.csdn.net/jiazhijun/article/details/8833710

作者:Jack_Jia    郵箱: [email protected]


     移動互聯網已經是一種趨勢,僅2012年就有45億應用程序下載量。伴隨着移動互聯網的火爆,衆多攻擊者也被吸引到這個平臺,移動平臺惡意軟件呈現爆炸式增長態勢。與PC平臺不同的是,PC平臺有大量的反病毒包和惡意軟件分析工具,而新興的移動互聯網卻缺乏強大的分析工具和技術。這些工具和技術將是保持移動互聯網遠離惡意軟件和惡意應用程序的關鍵。它們一般來自於學術界和安全界的研究人員,但是它們都有一定的缺陷,並不適合所有的情況,加入安全社區可以幫助我們學習和發展android應用的分析方法。


一、介紹

      首先介紹一下移動應用程序的分析方法和背景。我們可以採用很多工具來對應用程序進行分析,Android應用程序的分析一般都是基於APK文件,APK文件代表了一個應用程序。
     它存儲了以下內容:


           1、程序邏輯:dex字節碼和so本地庫。
           2、元數據信息:AndroidManifest.xml文件。
           3、資源文件:圖像或其他類型數據。


     分析工具一般採用以下兩種應用分析方法:


          1、靜態分析:該方式收集有關應用程序的信息,但程序代碼不執行。
          2、動態分析:該方式執行應用程序,同時收集應用運行行爲。


     這兩種分析技術都各有利弊,在Android逆向分析領域,許多工具都是基於靜態分析技術,也有用於動態分析的沙箱系統,但受限於動態分析系統的交互靈活性,分析師往往在那些部分需要動態分析上沒有足夠的控制力。在逆向工程過程中,分析人員一旦確定了感興趣的應用程序部分,它們更側重於使用靜態分析工具。問題是如何找到那些部分呢?靜態分析技術的另一個主要缺點是不知道什麼被真正執行和程序上下文在某特定點的執行是否有效。當我們假定應用程序代碼在運行過程中不會改變時,分析工作將是十分容易的,我們可以通過分析apk文件來識別程序代碼邏輯,混淆的應用程序會給分析人員帶來一定的挑戰。隨着運行時篡改Dalvik字節碼的講解,我們將暴露這些基於代碼流分析的工具的限制和問題。


     我們將在接下來的部分描述一下應用程序的基本組成部分,並指出重要的運行時組件。這將使我們更容易明白當運行crackme時發生了什麼事情。之後,我們將講述用於欺騙靜態分析工具所採用的主要技術。最後我們會進入crackme挑戰的細節。


二、應用程序執行的上下文


      應用程序的生命週期開始於zygote進程的fork方法,因爲它已經預先加載了Android框架,所以應用程序不必再花時間加載這些基礎類,同時這也可以有效降低整體的內存開銷。在新的進程降低權限之後,它加載了apk文件中的classes.dex文件,該文件包含了可被Dalvik虛擬機(DVM)解釋執行的Dalvik字節碼,代表了應用程序邏輯。此外,應用程序還帶有可以在運行時動態加載的Native庫。因爲Dalvik虛擬機和Native庫運行在同一進程中,因此它們具有相同的權限。一個典型的(縮短的)應用程序的內存佈局如圖1所示。



圖1典型的APP內存佈局


       我們可以看到,Android框架和共享庫及dex文件一樣被映射到我們的進程。我們的dex文件字節碼被映射爲只讀。


三、篡改技術


       回到靜態分析工具的話題,如果Dalvik字節碼在運行時不能改變的話,靜態分析工具將能很好的工作。因爲我們可以直接從APK文件中提取的出和運行時相匹配的字節碼。你可能會說這種假設是成立的,因爲dex文件映射爲只讀,所以Dalvik指令集是不能夠修改的字節碼本身的。有限的Dalvik指令集使我們不能夠篡改程序字節碼,但我們可以利用捆綁在APK文件中的本地庫。本地代碼和DVM運行在相同的較低水平,如圖2:



圖2 本地代碼和DVM在同一級別的操作


      本地代碼是能夠任意操作自己進程上下文內存的,因此我們可以通過本地代碼覆蓋已加載Dalvik字節碼。但是classes.dex被映射爲只讀。這意味着,如果我們修改該段內存,內核將會殺掉我們的進程,因此在實際篡改我們的應用程序的字節碼之前,我們必須重新映射該段內存爲可寫。之後,我們就可以寫我們的新字節碼到我們的應用程序。如果程序調用我們篡改過的方法,那麼將執行新的字節碼。沒有進一步修改應用程序或DVM的必要。通過這種方法,我們發現“字節碼在運行時不能修改”的假設也不是絕對的。只關注classes.dex文件的靜態分析工具沒有考慮到這種情況,這樣的工具就必須改進以應對這種情況。可以使用靜態和動態分析的組合來克服這種限制,但這樣的複雜的分析系統是不常見的。


三、示例-Crackme


     爲了說明我們前面所討論的一些問題,我們決定創建一個案例研究“challenge”的應用程序“crackme”,它使用惡意軟件使用的混淆技術進行了處理。您可以使用任何分析技術和工具,並弄清楚它是如何工作的。找到正確的密碼,輸入到上面的文本框中。點擊按鈕,查看是否得到了正確的答案。這將顯示按鈕下面的文字。


     您可以在這裏下載crackme的apk文件的副本:https://github.com/blueboxsecurity/DalvikBytecodeTampering/raw/master/delta.apk


     停止閱讀,如果你打算接受挑戰。下面是挑戰的答案 -----

     首先我們開始分析Action類,這是我們的應用程序的Activity的入口,按鈕會觸發verify()方法。在這裏,我們第一次獲取TextField中的輸入的文本,並把它轉換成一個String。這個String對象並不是java.lang.String類的一個實例而是我們自己的實現。在構造函數中,我們使用第二種方法改變字符串。結果將被儲存在私有的區域,和Action類的硬編碼在一塊。如果密碼相同,將被用於顯示在屏幕上的消息的加密。

     但是String類內所使用的改變文本方法的方法,或者更準確地說,這種方法的字節碼,將永遠不會被執行。當應用程序啓動後,在Action的靜態類的構造函數中,這個方法的字節碼已經被替換掉了。在這裏,我們加載本地庫'libnet.so'和執行READMEM()函數。在這個庫中,我們獲取一個指針從堆棧到我們的映射的dex文件,並嘗試找到文件的開頭。這可以很容易地通過正向搜索內存頁,直到我們發現dex文件的magic byte。現在我們可以從dex文件的開頭解析頭文件。當我們解析dex文件時,我們可以找到的我們要篡改方法的地址。但正如前面提到的,我們首先要重新映射內存爲可寫。這可以使用mprotect()函數實現。之後,我們就可以覆蓋原來的字節碼,並通過從本機代碼到類的初始化的返回來完成。類初始化已經結束,Activity在Android設備上彈出。現在,當我們按下按鈕時,我們執行的是新的字節碼,而不是原來dex的字節碼。


英文源址:http://blog.bluebox.com/2013/03/25/android-security-analysis-challenge-tampering-dalvik-bytecode-during-runtime/

發佈了7 篇原創文章 · 獲贊 7 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章