2018-12-18 17:19:0410324人阅读
背景
在分析某android设备时,偶然发现一处后门,净查证,应该是360的雷电OS中的一个组件,顺便分析一波
01后门功能
system权限的app
提供诸多高危接口如:命令执行、静默安装/卸载应用、设置GPS信息、任意删除文件等操作;hook了众多framework函数如startService、getContentProvider、bindService等,监听交互流程;
02 发现
在系统里偶然发现一个system进程如下:
将其应用拖出来,解压之后目录如下:
这里主要分析ChiMaster.apk和chimahelper.apk
03 ChiMaster.apk分析
先分析其Manifest.xml文件:
可以看到其注册了广播BootReceiver监听开机android.intent.action.BOOT_COMPLETED,猜其是开机自启,并启动恶意服务,跟进该广播:
其作用是启动一个action为com.chima.android.policy.IPolicyService的服务,查看Manifest可知,该服务对应的是DaemonService,跟进该服务,找到其onCreate函数:
其中除了正常的初始化流程之外,还有一个a.a函数,跟进下该函数,发现该函数的作用是初始化了NewPolicyService这个类,如下:
继续跟进NewPolicyService这个类:
发现是IPolicyService的一个实现,我们看下IPolicyService,发现其是一个AIDL接口,并提供诸多高危函数:
而回到DaemonService,发现如下:
并通过onBind进行返回:
因此可以确定,DaemonService对外提供服务,通过IPolicyService定义的AIDL接口进行,而真正的实现函数在NewPolicyService这个类中,这里我们分析其中的两个函数executeCmdInShell和forceStopPackage
签名校验
原本以为这些接口可以随意利用提权,结果发现了签名校验函数
跟进如下:
可以看到获取了调用者的Uid,v0是签名校验成功与否的标志位,该函数通过反射的方式调用了checkSignPermissionByAPI,并将调用接口的名称和调用者的uid传入了进去,直接找到checkSignPermissionByAPI的实现
经过重重调用,最终定位到了其签名白名单
因此第三方app无法调用,因此也无法提权,这里我做了下验证:
if (binder != null) {
Log.e(Tag, "start");
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken("com.chima.android.policy.
IPolicyService");
binder.transact(2, _data, _reply, 0);// getversion
Log.e(Tag, "" + _reply.readInt());
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.e(Tag, "binder is null");
}
Intent intent8 = new Intent();
intent8.setAction("com.chima.android.policy.IPolicyService");
intent8.setPackage("com.chima.vulcan");
bindService(intent8,connection,BIND_AUTO_CREATE);
果然是签名校验失败:
froceStopPackage
从命名来看应该是强制关停某应用的,跟进其实现,这里中间绕过了一些细节:
可以看到是通过反射了ActivityManager中的forceStopPackage函数来实现的,这个只是一个代表,其中很多接口都是反射系统接口实现的
executeCmdInShell
该接口从命名来看是执行shell命令的,跟进关键部分:
继续跟进,中间省略几处跳转,最终跟到了下面,v6_1是最终构造的参数,c是一个OutputStream
这里困惑了,执行shell命令为何会向OutputStream中写入?我们需要跟进这个c的赋值处:
这里我理解了,是一个本地的socket,执行shell命令的是一个native程序,通过localsocket进行通信,继续跟进通信的this.b的赋值处
也就是应该存在chima这样一个程序,通过localsocket执行shell命令,这里我并没找到chima这个程序,关于localsocket的介绍参考:
https://www.cnblogs.com/bastard/archive/2012/10/09/2717052.html
因此这个执行shell命令的接口是通过接受签名白名单中应用的输入,然后通过localsocket与chima进行交互。
04 chimahelper.apk
这个apk并没有被动态加载,因此怀疑ChiMaster是个裁剪过的后门,也或者是本菜鸡并未分析出其加载的位置
chimahelper.apk主要是对一些framwork函数进行hook,hook方法应该是借鉴了Legend的免root,hook方法,其hook的方法如下:
1. getContentProvider;
2. bindService;
3. deletePackage;
4. installPackageAsUser;
5. startService;
hook的主要作用是用来做自我保护,不让任何非白名单的应用来启动服务,这里分析startService函数:
首先就是获取调用者的uid和pid,这里直接跳到关键位置:
跟进shouldBlock这个函数,应该是阻断函数:
isChimasterCalling函数
isOnForeGround函数
应该也是一个提供给第三方调用的stub,并不太清楚
isExistInBlackList函数
黑名单函数
是从policyprovider中去读的黑名单packagename
isAppAlive函数
确定是否是运行着的进程
05 总结
1. 该样本应该是个裁剪过的样本,比如自我保护apk并没有动态加载到主进程中,我执行bindservice也并没有阻断;
2. 该样本的基本功能是作为一个后门程序供白名单app使用,由于我测试的设备并未获取root权限,部分分析是处于猜测,并为实际验证;
3. 命令执行的chima代理也并未找到(权限不够),也无法查询init.rc来看是否真正定义;
4. 分析还略微糙,本菜鸡还需努力
样本下载:ChiMaster.apk.zip
本文由百度安全合作作者(ID:三胖子日了猫了)提供,如需转载需注明出处及本文链接