王倩文,沈蘇彬,吳振宇
(1.南京郵電大學 計算機學院,江蘇 南京 210003;2.南京郵電大學 物聯網學院,江蘇 南京 210003)
隨著智能手機的普及,手機惡意軟件的數量急速增加,尤其近年來,基于安卓平臺的手機在智能手機終端市場占據主導地位,針對安卓系統的惡意軟件數量呈快速上升趨勢。手機惡意軟件主要收集手機用戶地理位置、通訊錄、短信等個人隱私信息,嚴重威脅了手機用戶的個人隱私。有效監測惡意軟件并還原上層行為信息可以為后續清除惡意軟件提供有力依據。
目前針對安卓惡意軟件的監測方法主要包括靜態檢測和動態監測[1]。靜態檢測方案[2]是在不執行應用程序的情況下,采用逆向分析技術,通過抽取靜態特征來判別應用程序是否包含惡意行為[3]。靜態檢測方案雖然能夠識別應用程序的敏感行為,但是依賴于特征庫,特征庫中只存放已知惡意行為的特征碼。因此,靜態檢測無法檢測未知的惡意攻擊行為[4]。
安卓應用程序的動態檢測方案[5]是在模擬器等安卓運行環境中實際運行應用程序,觸發其潛在的惡意行為,動態監測其運行過程,從而判斷該應用程序是否包含惡意行為。相對而言,動態監測方案對安卓應用軟件行為的監測效率更高。Xu等[6]通過程序插樁的方式對應用程序的行為進行監測,并針對不同的攻擊配置相應的安全策略。Enck等[7]通過修改安卓系統的中間層代碼,以添加標簽的方式來監測數據流向,從而監測應用程序是否包含隱私竊取等敏感惡意行為。Burguera等[8]通過修改安卓系統內核層代碼實現對應用程序的監測,采用strace獲取安卓應用程序的系統調用信息,并對獲取到的信息進行聚類分析,從而判斷該應用程序是否存在惡意行為。
文中給出了一種基于安卓平臺的惡意軟件的動態監測方案。通過研究安卓簽名機制和重打包技術,對樣本實現過濾。研究安卓安全架構各層的特點,分析不同層面所存在的監測機制。著重研究了應用程序框架層的Hook API方法和內核層的系統調用攔截方法[9],分析了這兩種方法的優缺點,選定更加有效的基于內核層的系統調用攔截方法,并對其進行優化。另外,為減輕手機端負荷,與PC端結合,利用monkey工具實現apk自動安裝和卸載[10]。
在安卓平臺,大部分惡意軟件的流入都是通過應用重打包。通過研究重打包技術,判別應用程序是否存在重打包跡象,可以一定程度上實現對惡意樣本的篩選。安卓平臺本身針對惡意軟件攻擊也存在相應的安全策略,例如安卓系統安全架構最高層應用層的代碼安全和最底層內核層的文件訪問控制。深入研究安卓系統安全架構以及各架構層的應用程序監測機制,對分析惡意軟件行為來說意義重大。
隨著惡意軟件的數量愈發龐大,安卓手機用戶的隱私受到了嚴重威脅。Zhou Yajin等[11]深入研究了安卓惡意軟件,收集了1 260個安卓惡意軟件的樣本,在這些樣本中有86%的惡意樣本都是采用重打包的方式制作的。重打包是從安卓系統剛開始流行到現在占據智能手機終端主導地位,一直存在的攻擊手段。不論是哪種惡意軟件,都是將能夠執行惡意行為的代碼加入到已有應用程序中來實現惡意行為的。對正常應用程序進行反編譯處理,獲取該應用程序的源代碼,然后將惡意代碼植入到源代碼文件中,將越權信息添加到配置文件中,然后重打包并發布到第三方市場,如圖1所示。

圖1 惡意代碼植入過程
判斷應用程序是否經過重打包處理,安卓系統安全機制中的簽名機制給出了解決方案。安卓系統簽名機制能夠有效地對開發者進行審查。一方面能夠避免出現修改程序包的情況,另一方面可以幫助程序確認信賴關系,實現具有相同私鑰的應用程序之間代碼和數據的共享[12]。APK簽名后會生成一個META-INF文件目錄,其中包括MAINFEST.MF、CERT.SF和CERT.RSA三個簽名文件。在安裝應用程序前,安卓系統首先會檢查待安裝的APK包是否有簽名,具有簽名的應用程序才會得到系統的認可。同樣地,只有在數字簽名相同的情況下才會進行應用程序的更新和升級,否則當作新程序處理。
安卓的系統安全架構采用分層模式,圖2中安卓系統架構分為四層,從低到高分別是內核層、系統運行庫層、應用程序框架層、應用程序層[13]。

應用程序層(接入權限、代碼安全)應用程序框架層(數字證書)SQLite(數據庫安全)虛擬機(沙箱安全)SSL(網絡安全)Linux Kernel(文件訪問控制)
圖2 安卓系統安全架構
(1)應用程序層。
系統以及核心應用程序包一同發布,其中包括主屏、瀏覽器和通訊錄等程序,共同實現用戶與界面的交互。其中所有的應用程序都采用Java語言,通過調用相應的API來完成。
(2)應用程序框架層。
應用程序框架層包含程序開發所需要的一系列類庫,這使得程序開發者能夠很方便地使用API框架。其設計模式簡化了組件的重用,應用程序只要遵循框架的安全性限制,都可以發布自身功能塊,并且可以使用其他發布的功能塊。活動管理器主要用來管理應用程序的生命周期,同時提供導航等常用的功能;窗口管理器用來管理已開啟的程序窗口;內容提供器能夠實現應用程序之間數據的共享以及應用程序之間互相訪問的功能;視圖系統用來管理應用程序界面所涉及到的一些基本組件。
(3)系統運行庫層。
系統將運行時庫分為兩個部分:Dalvik虛擬機和核心庫。Dalvik虛擬機的設計目的是使手機這種低內存平臺上能夠適用安卓系統,每個程序都具有獨立的Dalvik虛擬機;核心庫包含了Java語言所提供的核心庫的大部分功能,同時為應用程序開發者提供了安卓的核心API。
(4)內核層。
安卓系統依賴于Linux內核又不完全依賴于Linux。安卓系統一方面借助Linux內核來實現進程管理等核心的功能,另一方面增加了自身獨有的功能,如低內存管理器等。這使得內核能夠更加適應智能手機終端這樣的環境,很大程度上提升了智能手機終端的相關性能。
目前,針對如何增強安卓系統安全架構有很多相關的工作。但核心的思路大致相同,通過截取系統調用的方式還原用戶的上層行為。在獲取具體行為之后,根據不同的安全策略對行為進行控制。安卓安全架構各層對應用軟件行為有著不同的監測機制。應用程序層采用庫替換的方式實現對目標進程的跟蹤。應用程序框架層可以采用Hook技術截獲API調用實現應用程序行為監測。內核層可以通過對內核代碼的編譯實現行為監測。
下面著重研究在內核層加入運行時監測機制和在應用程序框架層加入運行時監測機制。
安卓系統為開發者提供了一系列API函數,應用程序通過調用這一系列API函數可以實現諸多功能[14]。因此,通過監測應用程序調用的API函數,便可對應用程序的行為進行分析,判斷其是否存在惡意傾向[15]。
采用Hook技術截獲API調用的基本原理是先將代碼注入到目標進程中,然后使用ptrace[16]函數對目標進程attach,接著跳轉到mmap函數來分配一小段內存空間,然后將機器碼拷貝到剛分配的內存中,接下來執行注入的代碼。Hook常用工具為Xposed框架,獲得root權限后,安卓的Xposed框架能夠對應用程序的運行產生影響并且不修改APK。采用替換/system/bin/app_process的方式來控制zygote進程,這樣使得app_process在啟動過程中會加載XposedBridge.jar包,實現Zygote進程的截獲。
內核層監測機制采用修改系統調用表的方式。這種方式主要是通過內核模塊來修改系統調用表。使用自身模塊內的函數替換系統原有的調用函數,從而實現對目標進程行為的監測。這種方式的優點在于強制性監測。安卓系統是嚴格控制root權限的。一旦內核模塊被植入內核是很難再被取出來的,這樣就不必擔心被繞過的可能了。在內核層監測安卓系統應用程序時覆蓋全面。不管是否為安卓進程,不管是否為第三方應用,均能夠被監測。
兩種監測方式相比,內核層監測獲取的信息更加全面,要想執行文件訪問操作,必須得到內核層的支持。另外,內核層監測相對而言對系統性能的損耗較小,其提供的系統調用接口數量也較少。因此,內核層監測產生的影響要遠遠小于框架層監測所產生的影響。綜上所述,文中設計的監測方案中監測方式的選擇采用在內核層加入運行時監測機制。
文中設計了一種基于安卓平臺的惡意軟件的動態監測方案。首先根據安卓簽名機制,計算出相應文件MD5[17]值,判斷應用程序是否有重打包跡象。比對標準是官方渠道獲取的軟件,對樣本進行過濾。
下面采用內核層監測機制來監測惡意軟件。通過內核模塊對系統調用表進行修改。通過使用自身模塊內的函數去替換系統原有的調用函數。在替換過程中同時進行安全檢查,達到對目標進程行為的監測。將監測到的系統調用按照時間先后順序記錄在一個特定的日志文件中,日志信息的格式如圖3所示。

原型[自定義標識](uid)(pid)方法/系統調用樣例[Rootkit]( 954)(10074)android.app.…
圖3 日志信息格式
惡意軟件的攻擊類型主要有:權限泄露、合謀攻擊、財務攻擊、隱私數據竊取、其他攻擊[18]。針對不同的惡意軟件攻擊行為給出相應的安全策略[6]。選出惡意軟件已經代表了典型的惡意軟件行為。下面為針對短信劫持的安全策略,一旦出現截獲短信(例如驗證碼信息等)行為,立即向用戶發出警告。
UID operation [data] on target [context]
If [operation==sendSMS] then [
Record
If [data.smsNUM in Blacklist] then [warn user Dangerous]
If [context.isBackground==true] then [warn user Dangerous]
If [data.smsNUM not in contact] then [warn user Dangerous]
If [frequency>limit] then [warn user Dangerous]
]
If [UIDregister SMS_RECEIVED && target==ActivityManagerService] then [warn user Dangerous]
Else [go on]
另外,為了減輕手機端負荷,與PC端結合,利用monkey工具實現apk自動安裝和卸載。Monkey是一種測試工具,由Google的Android SDK提供,使用它們能夠達到模擬人工輸入的效果。使用adb工具來調用monkey命令,實現用戶事件流的隨機發送,測試指定應用的相關功能,也可以實現apk自動安裝和卸載。
PC端:Windows 7;
手機端:安卓模擬器(Android 4.3、Linux 2.6.29)。
模擬器配置信息如圖4所示。

圖4 模擬器配置信息
實驗中惡意軟件來源于Malgenome Project[11],數據集中的1 200個惡意樣本均已根據它們所產生的惡意行為的不同特點進行了歸類。
通過分析apk簽名信息,發現重打包程序的簽名不同于源程序的簽名。根據此性質,可采用MD5算法實現簽名信息的校驗,進而判斷應用程序是否有重打包跡象。
/*計算文件的MD5值*/
public class Md5Calculating {
public static String getMd5 (File file) throwsFileNotFoundException {
String s=null;
FileInputStream o=new FileInputStream(file);
try {
MappedByteBuffer byteBuffer=o.getChannel().map(
FileChannel.MapMode.READ_ONLY, 0, file.length());
MessageDigest md5=MessageDigest.getInstance("MD5");
md5.update(byteBuffer);
BigInteger b=new BigInteger(1, md5.digest());
s=b.toString(16);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null !=o) {
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return s;
}
public static void main(String[]args) throws IOException {
String path="C:\Users\Administrator\Desktop\md5test\commons-codec-1.10-bin.zip";
String f=getMd5 (new File(path));
System.out.println("MD5:" + f.toUpperCase());
FileInputStream x=new FileInputStream(path);
String md5=DigestUtils.md5Hex(IOUtils.toByteArray(fis));
IOUtils.closeQuietly(x);
System.out.println("MD5:" + md5);
}
}
使用adb工具調用monkey命令,實現用戶事件流的隨機發送,測試指定的程序。adb工具提供了一個配置文件setting.ini,如下:
#adb命令所在目錄
ADB Path=D:androidsdkplatform-tools
#測試數據所在目錄
Test Data Folder=D:API
修改系統調用表最核心的部分就是對內核進行編譯。編譯的步驟如下:
(1)下載安卓內核源碼。
執行如下命令,獲取內核源碼的主分支。
git clone git : // android.git.kernel.org /kernel/common.git
(2)設定環境變量。
這里要使用交叉編譯器。修改用戶目錄下的.bashrc文件,添加如下代碼:
export
PATH=$PATH:~/Android/source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin
export ARCH=arm
(3)設定交叉編譯參數。
打開makefile文件,該文件位于kernel目錄下。將CROSS_COMPILE指向arm-eabi編譯器。
(4)配置config文件。
獲取模擬器正在使用的config文件。首先要啟動AVD,執行adb pull /proc/config.gz命令,用來獲取模擬器中包含的內核配置文件,接著解壓config.gz文件。
(5)編譯內核。
進入內核目錄使用make命令對內核進行編譯。編譯完成后,會生成新的內核鏡像名為zImage,該文件位于/kernelarch/arm/boot/目錄下。
(6)修改安卓的系統調用表。
通過訪問/dev/kmem接口將Hook的新函數地址new_openat來覆蓋sys_call_table中的原始函數openat的調用地址。
采用基于內核的監測方式與針對不同攻擊行為所設計的安全策略,能夠有效地將惡意行為通知給用戶。
文中給出了一種基于安卓平臺的惡意軟件的動態監測方案。通過研究安卓簽名機制和重打包技術,對樣本實現過濾。通過分析安卓安全架構不同層面所存在的監測機制,選定基于內核層的系統調用攔截方法對應用程序行為進行監控,將監測到的系統調用按照時間先后順序記錄在一個特定的日志文件中,并且針對不同惡意軟件攻擊行為設定了相應安全策略,一旦檢測到惡意行為,立即向用戶發出警告。該方案能夠很好地對安卓惡意軟件行為進行監測,對增強安卓安全框架具有一定的指導意義。