ZooPark是一个针对中东的APT组织,截至2017年,已经发展到了4.0版本,本次分析是第三个版本,相比较V1、V2版本的代码的复杂性,2016年流出的V3版本的样本可以说有关于信息窃取这方面的功能比之前有了质的飞跃,如果说之前两个版本让人感觉新手练手的作品,那么这个版本已经可以说是有开发经验的老司机来写的了。我们入门先做静态的代码分析,理顺分析流程。
工具:JEB1.5、AndroidKiller1.3
样本运行流程图

V3
分析之前,我们需要理清思路,逐步分析,慢慢行成一套属于自己的分析流程。
1、 是否加固过,混淆过未加固、未混淆。
2、看安装包目录结构,看是否有特别的文件,记录下来方便后面的分析。
证书信息,看样本大概流出的时间:

资产目录assets中全是这些看起来很火辣的小姐姐,很明显可能用于诱惑用户查看点击之类的:

布局文件夹res的有几十个values文件(values-nb等),文件里面有不同国家的字体,和之前两个版本,可以看出,开发人员有了质的飞跃:

3、 看清单文件,静态注册了哪些广播接收器。
在清单文件AndroidManifest.xml中有这样静态注册的广播,因为它没有设置intent-filter,所以不会捕获任何广播,只能主动通过构造显式intent+发送广播sendBroadcast才可以唤醒这个广播:
receiver android:name="com.wallpaper.OnGPSReceiver" />
receiver android:name="com.wallpaper.OnAlarmReceiver" />
使用Android Killer工具的全局字符串搜索,只发现OnAlarmReceiver这个广播接收器在OnBootReceiver开机广播中被启用,结合起来实现的功能是开机后,设置一个重复的警报,来启动这个广播,用来唤醒AppService服务(服务比较复杂,在分析完清单文件后,分析):


从广播接收器的名称就可以看出他是一个检测网络变化然后执行某些行为的广播。从代码中可以看出他的主要行为就是如果可以联网,就会开启AppService服务(这是第二个为了开启这个服务的广播了,可以看出极有可能这个服务就是恶意行为的主要发起者)。这里勾选上write方法是建议留个印象,如果分析多个样本,那么其实可以从代码编写习惯中,看出一些端倪:
receiver android:label="NetworkConnection" android:name="com.wallpaper.NetworkChangeReceiver">
intent-filter android:enabled="true" android:exported="false">
action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
intent-filter>
receiver>

这是将这个样本APP激活成设备管理器,在meta-data中知道device_admin_sample.xml文件存放了,激活设备管理器请求开启的策略,并且一旦策略被触发就会调用这个广播接收器中重写的方法,如图7.png,都会打印一条日志:
intent-filter>
action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
intent-filter>
meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin_sample" />
receiver>
收到短信时,会将短信内容、号码、时间等存入data数据库中的tbl_SMS表中:
receiver android:enabled="true" android:name="com.wallpaper.SMSReceivers">
intent-filter>
action android:name="android.provider.Telephony.SMS_RECEIVED" />
intent-filter>
receiver>

开机启动广播,首先会尝试开启ScreenStateService服务,然后创建一个重复的警报,每隔4分钟来启动这个OnAlarmReceiver,即开启AppService服务。
receiver android:enabled="true" android:name="com.wallpaper.OnBootReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
intent-filter>
action android:name="android.intent.action.BOOT_COMPLETED" />
category android:name="android.intent.category.DEFAULT" />
intent-filter>
receiver>
综上,这些静态注册的广播,主要是通过监听网络变化、开机自启动来打开AppService、ScreenStateService服务,下面主要分析这两个服务。然后还有一些窃取用户收到的短信内容,写入数据库、激活设备管理器
4、分析两大服务的功能:AppService、ScreenStateService
ScreenStateService
动态注册ScreenReceiver广播接收器来监听屏幕的解锁和锁屏:
ScreenStateService.mReceiver = new ScreenReceiver();
this.getApplicationContext().registerReceiver(ScreenStateService.mReceiver, new IntentFilter(
"android.intent.action.SCREEN_ON"));
this.getApplicationContext().registerReceiver(ScreenStateService.mReceiver, new IntentFilter(
"android.intent.action.SCREEN_OFF"));
(1) 锁屏时,开启AppService服务(不知道第几次启动它,证明这个服务才是真正的恶意功能执行者)。执行Start_check_mic方法,开启线程来录音8分钟存储到外部存储/android/data/AndroidService/时间.3gpp,然后将~/android/data/AndroidService/目录下多有录音文件POST上传到C2地址的/spyMobile/recordcall_upload.php文件上:

在构造C2地址时,如果第一次访问这个地址MainActivity.Server_Domain,因为还没有被赋值,所以会异常,调用MainActivity.findServer()方法来,获取C2地址(通过访问网络图片获取返回的流数据,然后正则匹配出C2地址):

(2) 屏幕解锁时,打印Intent Action: android.intent.action.SCREEN_ON。
AppService
一般来说,浏览服务做了哪些事,从onCreate或者onStartCommand(onCreate没有重写的情况),但是这个服务没有这两个方法,再仔细看看,发现这个服务类,继承一个自定义类,而这个自定义类继承IntentService类,看到这个类我们就需要从onHandleIntent方法入手了(解决开发这忘记开启线程和忘记调用 stopSelf()),发现主要执行了doWakefulWork抽象方法,所以再回到AppService类中,检查他的重写方法即可:
public class AppService extends WakefulIntentService
public abstract class WakefulIntentService extends IntentService
......
abstract void doWakefulWork(Intent arg1);
......
this.doWakefulWork(intent);
WakefulIntentService.getLock(((Context)this)).release(); //锁屏(没有唤醒锁的前提)
(1) 检查是否开启ScreenStateService服务来偷偷录音,如果没有就打开这个服务:

|