转载请注明出处,谢谢。
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手机卫士是通过签名来识别恶意程序的,对程序重签名可以绕过这种检测方法。
总的来说,静态的基于特征的检测总会存在这些问题,这也是在考虑效果和性能情况下的折中,毕竟在程序安装时就进行复杂的检测会带来过大的系统开销,但是这就又带来了一下安全隐患,这种检测方式还必须及时更新病毒库,否则最新出现的恶意程序会无法识别。