Android ***測試學習手冊(三)Android 應用的逆向和審計

在本章中,我們將查看 Android 應用程序或 .apk 文件,並瞭解其不同的組件。 我們還將使用工具( 如 Apktool,dex2jar 和 jd-gui) 來逆向應用程序。 我們將進一步學習如何通過逆向和分析源代碼來尋找 Android 應用程序中的各種漏洞。 我們還將使用一些靜態分析工具和腳本來查找漏洞並利用它們。

3.1 Android 應用程序拆解

Android 應用程序是在開發應用程序時創建的數據和資源文件的歸檔文件。 Android 應用程序的擴展名是 .apk ,意思是應用程序包,在大多數情況下包括以下文件和文件夾:

  • Classes.dex (文件)

  • AndroidManifest.xml (文件)

  • META-INF (文件夾)

  • resources.arsc (文件)

  • res(文件夾)

  • assets(文件夾)

  • lib (文件夾)

爲了驗證這一點,我們可以使用任何歸檔管理器應用程序( 如 7zip,WinRAR 或任何首選應用程序) 簡單地解壓縮應用程序。 在 Linux 或 Mac 上,我們可以簡單地使用 unzip 命令來展示壓縮包的內容,如下面的截圖所示:




這裏,我們使用 -l ( list) 標誌,以便簡單地展示壓縮包的內容,而不是解壓它。 我們還可以使用 file 命令來查看它是否是一個有效的壓縮包。


Android 應用程序由各種組件組成,它們一起創建可工作的應用程序。 這些組件是活動,服務,廣播接收器,內容供應器和共享首選項。 在繼續之前,讓我們快速瀏覽一下這些不同的組件:

  • 活動( Activity) :這些是用戶可以與之交互的可視界面。這些可以包括按鈕,圖像, TextView 或任何其他可視組件。

  • 服務( Service) :這些 Android 組件在後臺運行,並執行開發人員指定的特定任務。這些任務可以包括從 HTTP 下載文件到在後臺播放音樂的任何內容。

  • 廣播接收器( Broadcast Receiver) :這些是 Android 應用程序中的接收器,通過Android 系統或設備中存在的其他應用程序,監聽傳入的廣播消息。一旦它們接收到廣播消息,就可以根據預定義的條件觸發特定動作。條件可以爲收到 SMS,來電呼叫,電量改變等等。

  • 共享首選項( Shared Preference) :應用程序使用這些首選項,以便爲應用程序保存小型數據集。此數據存儲在名爲 shared_prefs 的文件夾中。這些小數據集可以包括名值對,例如遊戲中的用戶得分和登錄憑證。不建議在共享首選項中存儲敏感信息,因爲它們可能易受數據竊取和泄漏的影響。

  • 意圖( Intent) :這些組件用於將兩個或多個不同的 Android 組件綁定在一起。意圖可以用於執行各種任務,例如啓動動作,切換活動和啓動服務。

  • 內容供應器( Content Provider) :這些組件用於訪問應用程序使用的結構化數據集。應用程序可以使用內容供應器訪問和查詢自己的數據或存儲在手機中的數據。

現在我們知道了 Android 應用程序內部結構,以及應用程序的組成方式,我們可以繼續逆向Android 應用程序。 當我們只有 .apk 文件時,這是獲得可讀的源代碼和其他數據源的方式。

3.2 逆向 Android 應用

正如我們前面討論的,Android應用程序只是一個數據和資源的歸檔文件。 即使這樣,我們不能簡單地解壓縮歸檔包(.apk ) 來獲得可讀的源代碼。 對於這些情況,我們必須依賴於將字節代碼( 如在 classes.dex 中) 轉換爲可讀源代碼的工具。

將字節碼轉換爲可讀文件的一種方法,是使用一個名爲 dex2jar 的工具。 .dex 文件是由Java 字節碼轉換的 Dalvik 字節碼,使其對移動平臺優化和高效。 這個免費的工具只是將Android 應用程序中存在的 .dex 文件轉換爲相應的 .jar 文件。 請遵循以下步驟:

1. 從 code.google.com/p/dex2j 下載 dex2jar 工具。

2. 現在我們可以使用它來運行我們的應用程序的 .dex 文件,並轉換爲 .jar 格 式。

3. 現在,我們需要做的是,轉到命令提示符並訪問 dex2jar 所在的文件夾。 

接下來,我們需要運行 d2j-dex2jar.bat 文件( 在 Windows 上) 或 d2j-dex2jar.sh 文件( 在 Linux /Mac 上) ,並提供應用程序名稱和路徑作爲參數。 這裏的參數中,我們可以簡單地使用 .apk 文件,或者我們甚至可以解壓縮 .apk 文件,然後傳遞 classes.dex 文件,如下面的截圖所示:


正如我們在上面截圖中看到的,dex2jar 已經成功地將應用程序的 .dex 文件轉換爲名爲 helloworld-dex2jar.jar 的 .jar 文件。 現在,我們可以在任何 Java 圖形查看器( 如JD-GUI) 中打開此 .jar 文件,JD-GUI 可以從其官方網站 Java Decompiler 下載。

4. 一旦我們下載並安裝 JD-GUI,我們現在可以繼續打開它。 它看起來像下面的截圖所示:


5. 在這裏,我們現在可以打開之前步驟中轉換的 .jar 文件,並查看 JD-GUI 中的所有Java 源代碼。爲了打開 .jar 文件,我們可以簡單地訪問 File | Open 。


在右側窗格中,我們可以看到 Java 應用程序的 Java 源代碼和所有方法。 請注意,重新編譯過程會爲你提供原始 Java 源代碼的近似版本。 這在大多數情況下無關緊要; 但是,在某些情況下,你可能會看到轉換的 .jar 文件中缺少某些代碼。 此外,如果應用程序開發人員使用一些防止反編譯的保護,如 proguard 和 dex2jar,當我們使用 dex2jar 或 Apktool 反編譯應用程序時,我們不會看到準確的源代碼; 相反,我們將看到一堆不同的源文件,這不是原始源代碼的準確表示。

3.3 使用 Apktool 逆向 Android 應用

另一種逆向 Android應用程序的方法是將 .dex 文件轉換爲 smali 文件。 smali 是一種文件格式,其語法與稱爲 Jasmine 的語言類似。我們現在不會深入瞭解 smali 文件格式。有關更多信息,請參閱在線 wiki code.google.com/p/smali ,以便深入瞭解 smali。

一旦我們下載 Apktool 並配置它,按照前面的章節的指示,我們都做好了進一步的準備。 與JD-GUI 相比,Apktool 的主要優點是它是雙向的。這意味着如果你反編譯一個應用程序並修改它,然後使用 Apktool 重新編譯它,它能跟完美重新編譯,並生成一個新的 .apk 文件。然而,dex2jar 和 JD-GUI 不能做類似功能,因爲它提供近似代碼,而不是準確的代碼。

因此,爲了使用 Apktool 反編譯應用程序,我們所需要做的是,將 .apk 文件與Apktool 二進制文件一起傳遞給命令行。一旦反編譯完成,Apktool 將使用應用程序名稱創建一個新的文件夾,其中會存儲所有的文件。爲了反編譯,我們只需調用 apktool d [app-name].apk 。這裏, -d 標誌表示反編譯。

在以下屏幕截圖中,我們可以看到使用 Apktool 進行反編譯的應用程序:


現在,如果我們進入 smali 文件夾,我們將看到一堆不同的 smali 文件,它們包含開發應用程序時編寫的 Java 類的代碼。在這裏,我們還可以打開一個文件,更改一些值,並使用Apktool 再次構建它。爲了從 smali 構建一個改動的應用程序,我們將使用 Apktool 中的 b ( build) 標誌。

apktool b [decompiled folder name] [target-app-name].apk


但是,爲了反編譯,修改和重新編譯應用程序,我個人建議使用另一個名爲 Virtuous TenStudio( VTS) 的工具。這個工具提供與 Apktool 類似的功能,唯一的區別是 VTS 提供了一個漂亮的圖形界面,使其相對容易使用。此工具的唯一限制是,它只在 Windows 環境中運行。我們可以從官方下載鏈接 Virtuous Ten Studio 下載 VTS。以下是反編譯同一項目的應用程序的屏幕截圖:


3.4 

審計 Android 應用

Android 應用程序通常包含許多安全漏洞,大多數時候是由於開發人員的錯誤和安全編碼實踐的無視。 在本節中,我們將討論基於 Android 應用程序的漏洞,以及如何識別和利用它們。

內容供應器泄露

許多應用程序使用內容供應器來存儲和查詢應用程序中的數據或來自電話的數據。 除非已經定義了內容提供者可以使用權限來訪問,否則任何其他應用都可以使用應用所定義的內容供應器,來訪問應用的數據。 所有內容供應器具有唯一的統一資源標識符( URI) 以便被識別和查詢。 內容提供者的 URI 的命名標準慣例是以 content:// 開始。

如果 Android API 版本低於 17,則內容供應器的默認屬性是始終導出。 這意味着除非開發人員指定權限,否則任何應用程序都可以使用應用程序的內容供應器,來訪問和查詢數據。 所有內容供應器都需要在 AndroidManifest.xml 中註冊。 因此,我們可以對應用程序使用Apktool,並通過查看 AndroidManifest.xml 文件檢查內容供應器。

定義內容供應器的一般方法如下所示:

android:name="com.test.example.DataProvider"
android:authorities ="com.test.example.DataProvider">


所以現在,我們將舉一個漏洞應用程序的例子,並嘗試利用內容供應器泄漏漏洞:

1. 爲了反編譯應用程序,我們將使用 Apktool 來使用 apktool d [appname].apk 反編譯應用程序。

2. 爲了找到內容供應器,我們可以簡單地查看定義它們的 AndroidManifest.xml 文件,或者我們可以使用一個簡單的 grep 命令,從應用程序代碼中獲取內容供應器,如下所示:



3. 我們可以使用 grep 命令來查找內容提供者,使用 grep –R 'content://' 。 此命令將在每個子文件夾和文件中查找內容供應器,並將其返回給我們。


4. 現在,我們在模擬器中安裝應用程序。 爲了查詢內容供應器並確認漏洞是可利用的,我們需要在 Android 設備或模擬器中安裝該應用程序。 使用以下代碼,我們將在設備上安裝易受***的 app.apk 文件:

$ adb install vulnerable-app.apk1869 KB/s (603050 bytes in 0.315s)
pkg: /data/local/tmp/vulnerable-app.apk
Success


5. 我們可以通過創建另一個沒有任何權限的應用程序來查詢內容供應器,然後查詢漏洞應用程序的內容供應器。 爲了快速獲得信息,我們還可以使用 adb 查詢內容供應器,我們可以在以下命令中看到:

adb shell content query - - uri [URI of the content provider]


以下是在漏洞應用程序上運行的命令,輸出展示了存儲在應用程序中的註釋:


在這裏,我們還可以使用 MWR 實驗室的另一個名爲 Drozer 的工具,以便在 Android 應用程序中找到泄漏的內容供應器漏洞。 我們可以從官方網站 Drozer 下載並安裝 Drozer。

6. 一旦我們安裝了它,我們需要將代理組件 agent.apk 安裝到我們的模擬器,它位於下載的 .zip 文件內。 該代理是系統和設備相互交互所需的。 我們還需要在每次啓動模擬器時轉發一個特定的端口(31415) ,以便建立連接。 要在 Mac 和其他類似平臺上安裝設備,我們可以按照 mwrinfosecurity.com/sys 上提供的在線指南。


7. 一旦完成,我們可以啓動應用程序,並單擊"Embedded Server( 嵌入式服務器) "文本。從那裏,我們需要回到設備,啓動 Drozer 應用程序,並通過單擊名爲 Disabled 的左上角切換按鈕啓用服務器。


8. 此後,我們需要訪問終端並啓動 Drozer,並將其連接到模擬器/設備。 爲此,我們需要輸入 drozer console connect ,如下面的截圖所示:


9. 在這裏,我們可以運行 app.provider.finduri 模塊來查找所有內容供應器,如下所示:

dz> run app.provider.finduri com.threebanana.notesScanning com.threebanana.notes…
content://com.threebanana.notes.provider.NotePad/notes
content://com.threebanana.notes.provider.NotePadPending/notes/
content://com.threebanana.notes.provider.NotePad/media
content://com.threebanana.notes.provider.NotePad/topnotes/
content://com.threebanana.notes.provider.NotePad/media_with_owner/
content://com.threebanana.notes.provider.NotePad/add_media_for_note
content://com.threebanana.notes.provider.NotePad/notes_show_deleted
content://com.threebanana.notes.provider.NotePad/notes_with_images/


10. 一旦我們有了 URI,我們現在可以使用 Drozer 應用程序查詢它。 爲了查詢它,我們需要運行 app.provider.query 模塊並指定內容供應器的 URI,如下面的截圖所示:


如果 Drozer 能夠查詢和顯示來自內容供應器的數據,這意味着內容供應器泄漏數據並且存在漏洞,因爲 Drozer 沒有被明確地授予使用數據集的任何權限。

11. 爲了修復此漏洞,開發人員需要做的是,在創建內容供應器時指定參數 android:exported = false ,或者創建一些新的權限,另一個應用程序在訪問供應器之前必須請求它。

3.5 不安全的文件存儲

通常,開發人員爲應用程序存儲數據時,未指定文件的正確文件權限。 這些文件有時被標記爲全局可讀,並且可以由任何其它應用程序訪問而不需要請求權限。

爲了檢查這個漏洞,我們所需要做的是訪問 adb shell ,之後使用 cd 進入 /data/data/[package name of the app] 。

如果我們在這裏執行一個簡單的 ls -l ,就可以看到文件和文件夾的文件權限:

# ls -l /data/data/com.aditya.example/files/userinfo.xml
-rw-rw-rw- app_200 app_200 22034 2013-11-07 00:01 userinfo.xml

這裏我們可以使用 find 來搜索權限。

find /data/data/ -perm [permissions value]


如果我們執行 cat userinfo.xml ,它儲存了應用的用戶的用戶名和密碼。

#grep 'password' /data/data/com.aditya.example/files/userinfo.xmlmysecretpassword


這意味着任何其他應用程序也可以查看和竊取用戶的機密登錄憑據。 可以通過在開發應用程序時指定正確的文件權限,以及一起計算密碼與鹽的散列來避免此漏洞。

目錄遍歷或本地文件包含漏洞

顧名思義,應用程序中的路徑遍歷漏洞允許***者使用漏洞應用程序的供應器讀取其他系統文件。

此漏洞也可以使用我們之前討論的工具 Drozer 進行檢查。 在這裏,我們用例子來說明由 Seafastian Guerrero 發現的 Adobe Reader Android 應用程序漏洞
seguesec.com) 。 此漏洞存在於 Adobe Reader 10.3.1 中,並在以後的版本中進行了修補。 你可以從 APK Download of Free Android Apps 下載各種 Android 應用程序的舊版本。

我們將啓動 Drozer,並運行 app.provider.finduri 模塊來查找內容供應器 URI。

dz> run app.provider.finduri com.adobe.readerScanning com.adobe.reader...
content://com.adobe.reader.fileprovider/
content://com.adobe.reader.fileprov

一旦我們找到了 URI,我們現在可以使用 app.provider.read 搜索並利用本地文件包含漏洞。


在這裏,我嘗試從系統中讀取一些文件,如 /etc/hosts 和 /proc/cpuinfo ,它們默認存在於所有的 Android 實例中,因爲它是基於 Linux 的文件系統。

dz> run app.provider.read content://com.adobe.reader.fileprovider/../../../../etc/host

s

127.0.0.1 localhost


正如我們在下面的屏幕截圖中看到的,我們已經成功地使用 Adobe Reader 漏洞內容供應器讀取了 Android 文件系統中的文件。



客戶端注入***

客戶端***通常發生在應用程序未檢查用戶輸入的時候。例如,在對 SQLite 數據庫的查詢期間,應用程序正在解析用戶輸入,因爲它位於查詢語句中。

讓我們舉一個應用程序的示例,它檢查本地 SQLite 數據庫,來根據登錄憑據驗證用戶。 因此,當用戶提供用戶名和密碼時,正在運行的查詢將如下所示:

SELECT * FROM 'users' where username='user-input-username' and password='user-input-password'


現在,在正常情況下,這將正常工作,用戶輸入其真正的登錄憑據,並且查詢取決於條件將返回 true 或 false 。

SELECT * FROM 'users' where username='aditya' and password='mysecretpass


但是,如果***者輸入 SQL 語句而不是正常的用戶名怎麼辦? 請參考以下代碼:

SELECT * FROM 'users' where username='1' or '1' = '1' - - and password='mysecretpassword


因此,在這種情況下,即使用戶不知道用戶名和密碼,他們可以通過使用 1'or'1'='1 查詢來輕鬆繞過它,這在所有情況下都返回 true 。 因此,應用程序開發人員必須在應用程序中進行適當的檢查,來檢查用戶輸入。

我們還可以使用 Drozer 的 app.provider.query 來利用 SQL 注入漏洞。 其語法看起來像:

run app.provider.query [Content Provider URI] --projection "* FROM SQLITE_MASTER WHERE type='table';- -"


現在,這將返回 SQLite 數據庫中整個表的列表,它的信息存儲在 SQLITE_MASTER 中。 您還可以繼續並執行更多的 SQL 查詢,來從應用程序提取更多的信息。 爲了使用 Drozer 實戰漏洞利用,你可以從 Drozer 下載他們的漏洞應用程序。

3.6OWASP 移動 Top10


Web 應用程序開放安全項目( OWASP) 是涉及安全和漏洞搜索的標準之一。 它還發布了前10 名漏洞的列表,其中包括在各種平臺中最常見和重要的漏洞。可以在 Projects/OWASP Mobile Security Project - Top Ten Mobile Risks 上找到 OWASP 移動版的前 10 個指南。 如果我們查看 OWASP 移動項目,以下是它涵蓋的移動應用程序的 10 個安全問題:

  • 服務端弱控制

  • 不安全的數據存儲

  • 傳輸層保護不足

  • 意外的數據泄漏

  • 缺少授權和認證

  • 無效的加密

  • 客戶端注入

  • 通過不可信輸入的安全決策

  • 不正確的會話處理

  • 缺乏二進制保護

讓我們逐一介紹它們,並快速瞭解它們在移動應用程序中的關係,以及我們如何檢測它們:

服務端弱控制

第一個 OWASP 漏洞是服務端弱控制,顧名思義,服務端不以安全的方式將數據從移動應用程序發送到服務端,或者在發送數據時暴露一些敏感的 API。 例如,考慮一個 Android 應用程序發送登錄憑據到服務器進行身份驗證,而不驗證輸入。 ***者可以以這樣的方式修改憑證,以便訪問服務器的敏感或未授權區域。 此漏洞可視爲移動應用程序和 Web 應用程序中的一個漏洞。

不安全的數據存儲

這僅僅意味着,應用相關信息以用戶可訪問的方式在設備上存儲。 許多 Android 應用程序在共享首選項,SQLite( 純文本格式) 或外部存儲器中,存儲與用戶相關的私密信息或應用程序信息。 開發人員應該始終記住,即使應用程序在數據文件夾(/data/data/package-name )中存儲敏感信息,只要手機已 root,惡意應用程序/***者就可以訪問它。

傳輸層保護不足

許多 Android 開發人員依賴於通過不安全模式的網絡來發送數據,例如 HTTP 或沒有正確實現 SSL 的形式。 這使得應用程序易受到網絡上發生的所有不同類型的***,例如流量攔截,從應用程序向服務器發送數據時操縱參數,以及修改響應來訪問應用程序的鎖定區域。

意外的數據泄漏

當應用程序將數據存儲在本身易受***的位置時,會出現此漏洞。 這些可能包括剪貼板,URL 緩存,瀏覽器 Cookie,HTML5 DataStorage ,統計數據等。 一個例子是用戶登錄到他們的銀行應用程序,他們的密碼已經複製到剪貼板。 現在,即使是惡意應用程序也可以訪問用戶剪貼板中的數據。

缺少授權和認證

如果 Android 應用程序或一般的移動應用程序在沒有適當安全措施的情況下,嘗試基於客戶端檢查來驗證或授權用戶,則這些應用程序最容易受到***。 應該注意的是,一旦手機已root,大多數客戶端保護可以被***者繞過。 因此,建議應用程序開發人員使用服務器端身份驗證和授權進行適當的檢查,一旦驗證成功,請使用隨機生成的令牌,以便在移動設備上驗證用戶。

無效的加密

這僅僅表示使用不安全的密碼函數來加密數據部分。 這可能包括一些已知存在漏洞的算法,如 MD5,SHA1,RC2,甚至是沒有適當的安全措施的定製算法。

客戶端注入

這在Android應用程序中是可行的,主要成因是使用 SQLite 進行數據存儲。 我們將在本書的各章中執行注入***。

通過不可信輸入的安全決策

在移動應用程序中,開發人員應始終過濾和驗證用戶提供的輸入或其他相關輸入,並且不應該像在應用程序中那樣使用它們。 不受信任的輸入通常會導致應用程序中的其他安全風險,如客戶端注入。

不正確的會話處理

在爲移動應用程序執行會話處理時,開發人員需要處理很多因素,例如認證 cookie 的正常過期,安全令牌創建,cookie 生成和輪換,以及無法使後端的會話無效。 必須在 Web 應用程序和 Android 應用程序之間維護正確的安全同步。

缺乏二進制保護

這意味着不能正確地防止應用程序被逆向或反編譯。 諸如 Apktool 和 dex2jar 之類的工具可用於逆向 Android 應用程序,如果沒有遵循正確的開發實踐,它會暴露應用程序的各種安全風險。 爲了防止通過逆向***來分析應用程序,開發人員可以使用 ProGuard 和 DashO 等工具。

總 結

在本章中,我們學習了使用各種方法來逆轉 Android 應用程序並分析源代碼。 我們還學習瞭如何修改源代碼,然後重新編譯應用程序,來繞過某些保護。此外,我們還看到了如何使用Drozer 等工具尋找 Android 應用程序中的漏洞。你還可以通過 labs.securitycompass.com 親自嘗試 Exploit-Me 實驗室中的各種漏洞,它由 Security Compass 開發。

在下一章中,我們將進一步嘗試 Android 應用程序的流量攔截,並在我們的***測試中使用它。


轉自:

https://zhuanlan.zhihu.com/p/25399394

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章