轉載請注明出處,謝謝。
Android系統開放,各大論壇活躍,應用程序分發渠道廣泛,這也就為惡意軟件的傳播提供了良好的環境。好在手機上安裝了安全軟件,是否能有效的檢測出惡意軟件呢?下邊針對LBE安全大師、騰訊安全管家和360手機衛士做出一系列實驗。
1. Android惡意樣本實驗。
Android Malware Genome Project(http://www.malgenomeproject.org/)收集了2010年8月到2011年10月的涵蓋主要惡意軟件類型的超過1200個惡意程序樣本,樣本有些陳舊,但這是目前手頭上有的,最新的樣本不知如何獲得,希望有了解的同學留言告知。
從中抽取了涵蓋不同類型的100多個樣本進行安裝實驗。結果惡意軟件識別率驚人的高。幾乎全部可以檢測的到。

惡意軟件的檢測率如此高,確實很讓我驚訝,那這些安全軟件到底是如何檢測惡意軟件的呢,實驗的結果更是讓我驚訝,這項實驗才是重點。
2. Plankton類型的5aff5198c2fe5798bd7f1519dab0cd4ee737d5d2.apk程序測試安全軟件的檢測方式
起初,我考慮檢測惡意軟件主要是掃描APK的Manifest文件,分析函數調用關系,所以我考慮對樣本進行反向工程,然后自己新建項目去實現,當增加一段代碼安全軟件就判定為惡意程序,刪除這一段代碼后就檢測正常時,這段代碼就是惡意軟件的核心特征。在這樣的考慮下,首先綜合使用apktool、dex2jar和jdgui對apk樣本進行處理。
2.1 樣本反向工程
5aff5198c2fe5798bd7f1519dab0cd4ee737d5d2.apk樣本為一款憤怒的小鳥修改器程序,名稱為Angry Birds Cheater,圖標如下:

Apktool處理,發現程序結構很簡單,只有res和smali目錄,還有Manifest.xml文件,Manifest文件中只有一個Activity和一個Service,申請的權限不少,我懷疑這些權限是不是一個檢測的點。
Manifest文件如下:
<?xml version="1.0" encoding="UTF-8"?> <manifest android:versionCode="3" android:versionName="2.01" package="com.crazyapps.angry.birds.cheater.trainer.helper" xmlns:android="http://schemas.android.com/apk/res/android"> <application android:label="@string/app_name" android:icon="@drawable/icon"> <activity android:label="@string/app_name" android:name=".AngryBirdsCheater" android:configChanges="keyboardHidden|orientation"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.plankton.device.android.service.AndroidMDKService" android:enabled="true" /> </application> <uses-sdk android:minSdkVersion="8" /> <supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" /> <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" /> <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" /> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="com.motorola.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="com.motorola.launcher.permission.WRITE_SETTINGS" /> <uses-permission android:name="com.motorola.launcher.permission.INSTALL_SHORTCUT" /> <uses-permission android:name="com.motorola.launcher.permission.UNINSTALL_SHORTCUT" /> <uses-permission android:name="com.lge.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="com.lge.launcher.permission.WRITE_SETTINGS" /> <uses-permission android:name="com.lge.launcher.permission.INSTALL_SHORTCUT" /> <uses-permission android:name="com.lge.launcher.permission.UNINSTALL_SHORTCUT" /> </manifest>
Smali代碼看起來比較吃力,所以采用dex2jar和jdgui來查看代碼,代碼的結構如下圖:

其中AngryBirdsCheater為Activity,在onCreate方法里調用了AndroidMDKService服務的initMDK方法啟動服務,然后向服務器請求攻擊指令,下載jar文件等。
看雪論壇有對Plankton惡意程序的一篇分析文章:http://bbs.pediy.com/showthread.php?t=176363 。此處不多講了,因為實驗結果出現的太突然了,根本沒需要深入理解代碼過程,下邊解釋出現了什么。
2.2 創建工程實現Plankton惡意程序
接下來自己創建工程,程序名為Plankton2,第一個Activity頁面就自動生成的也沒改,然后添加com.plankton.device.android.service包,創建AndroidMDKService類,在Manifest中聲明這個服務,寫到這,先運行下試試吧。
結果,結果令人震驚:

什么,這就報毒了,我還什么都沒寫呢,MainActivity里只有onCreate,而且里邊只setContentView里,AndroidMDKService里只有onBind,里邊還是空的,Manifest文件里甚至沒有申請一項權限。這誤報的太明顯了。
Plankton2代碼結構:

MainActivity代碼:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
AndroidMDKService代碼:
public class AndroidMDKService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Manifest文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.shuai.plankton2" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name="com.shuai.plankton2.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.plankton.device.android.service.AndroidMDKService"> </service> </application> </manifest>
這樣的結果着實很出乎我的意料。
還好,360和他們不一樣,報的是安全的。

難道僅僅是有了AndroidMDKService類就唬住LBE和手機管家了嗎,現在點到這個類上F2,重命名,去掉MDK的K,重新安全,此時所有檢測均為安全的了。
進一步測試發現,必須是com.plankton.device.android.service包名下創建AndroidMDKService類才會被檢測,看來LBE和手機管家檢測惡意程序是根據惡意類名的方式實現的,這樣的做法導致惡意軟件只要更改包名就可以繞過檢測。
360還無法檢測到惡意,那繼續完善程序,根據反編譯的結果把類補充完整,因為反編譯的結果直接貼到工程中會有不少錯誤,修改了很長時間360還是一直識別是安全的,我在想是不是因為哪些功能或者特征沒有實現處理,所以360就不會報毒,讓我認為360的檢測結果還是比較靠譜的。
2.3 樣本重簽名,360不認識了
突然想到給程序重簽名試試看,重簽名的過程網上可以搜到,用WinRAR打開APK文件,刪除META-INF目錄,然后在命令行用keytool生成密鑰,用jarsigner簽名。
這時候再安裝,360報未發現安全風險,和上圖相同,這明明是個惡意程序的,怎么成安全的了,只是換了個簽名而已,程序的惡意行為部分又不會影響。
總結:
普通的惡意樣本檢測中,三款安全軟件都表現良好,能准確的檢測出惡意軟件;進一步的分析中發現,LBE和騰訊手機管家識別惡意軟件時通過類的URI(不知道這種叫法是否合理),只要包名和類名符合惡意程序特征,就會報惡意程序,即使這個程序什么都不做,這就會造成很多誤報情況發生,而且惡意程序可以通過更換包名和類名的方法繞過檢測;360手機衛士是通過簽名來識別惡意程序的,對程序重簽名可以繞過這種檢測方法。
總的來說,靜態的基於特征的檢測總會存在這些問題,這也是在考慮效果和性能情況下的折中,畢竟在程序安裝時就進行復雜的檢測會帶來過大的系統開銷,但是這就又帶來了一下安全隱患,這種檢測方式還必須及時更新病毒庫,否則最新出現的惡意程序會無法識別。
