首页
下载应用
提交文章
关于我们
🔥 热搜 🔥
1
法明传[2024]173号
2
起源 解读 龚
3
中共中央
4
中美友好合作故事
5
赵紫阳
6
妈 分享 回
7
写小说
8
南京李志
9
百度
10
今日热点
分类
社会
娱乐
国际
人权
科技
经济
其它
首页
下载应用
提交文章
关于我们
🔥
热搜
🔥
1
法明传[2024]173号
2
起源 解读 龚
3
中共中央
4
中美友好合作故事
5
赵紫阳
6
妈 分享 回
7
写小说
8
南京李志
9
百度
10
今日热点
分类
社会
娱乐
国际
人权
科技
经济
其它
观察|官方通报陕西蒲城一职校学生坠亡:事发前与舍友发生口角和肢体冲突 认定该生系高空坠落死亡
市管干部“龚书记”免职迷局
讣告!又一知名女星在家中去世,终年54岁,曾是无数人白月光…
近视的孩子有救了!国内最新近视防控矫正技术,不手术,扫码进群即可了解!
克林顿白宫内幕:口述史
生成图片,分享到微信朋友圈
查看原文
其他
Android系统Server自动化安全测试
vivo千镜
2022-11-05
Android中有些应用APP会用到系统Server提供的服务,其中有些Server是android 原生自带的,有些是OEM厂商定制添加的,可以使用service list 命令查看,怎么评估其安全性呢?
这些Server是注册在ServiceManager中,使用android binder机制进行通信,厂商定制的Server常用AIDL的方式编写服务,
所以先对android binder,ServiceManager,AIDL做简单的介绍,
基于上述原理
编
写自动化测试工具辅助安全测试。
01
Android binder架构
Binder 是android系统中使用的IPC进程间通信机制,应用层APP intent通信就是依赖底层Binder机制,它整体机制比较复杂,如下图所示:
简要概况如下:
内核空间主要是binder驱动,它是一个标准的Linux驱动,Binder Driver将自己注册成misc device并向上层提供一个/dev/binder节点,可以提供open(), ioctl(), mmap()等常用文件操作,通过一次内存拷贝实现进程间数据共享。
用户空间分为C/C++和Java两个部分,中间通过JNI进行衔接。其中ServiceManager大部分代码都是用C/C++实现,Java层ServiceManger通过JNI实现了代码复用。
02
ServiceManger
Binder架构以客户端-服务端模型运行,也就是C/S架构。允许多个进程(client)同时调用进程(server)中的多个方法。ServiceManager用来管理注册的Server,给client提供查询Server接口的功能。如下图所示:
ServiceManager内部维护着一个svclist列表,用于存储所有Server相关信息,查询和注册都是基于这个列表展开,并且通过Binder驱动协议与底层Binder驱动通信。
03
AIDL
手工实现一个Binder Server比较麻烦, 有没有更简洁的方式?答案是AIDL , AIDL是Android 接口定义语言(Android interface define language)。用于生成可以在Android设备上两个进程通讯(IPC interprocess communication)的代码, AIDL的优点是:跨进程,多并发。
现在很多集成开发工具如android studio通过创建aidl文件自动生成所需java代码,所以基于AIDL的Binder Server很常见。如下图所示,可见还是基于Binder机制通信
。
Server端实现分三步骤
·
抽象接口,编写aidl文件
·
编写service, 实现接口,处理客户端请求,并将Binder返回
·
Androidmanifest.xml配置Service,将Service暴露
Client端实现
·
将服务端的aidl文件copy过来,放在同一个包下
·
构造intent启动服务端service, 保存服务端返回的Binder
·
通过返回Binder调用服务端方法
整个原理大致如下:
总结就是client序列化数据,Binder传输数据, Server反序列化数据,处理完后返回。
FUZZ测试的时候一般拿不到服务端的aidl文件,该怎么处理呢?根据aidl文件生成的代码
mRemote是android.os.IBinder类型,调用transact函数,通过构造Parcel类型的参数,实现了对Server端setSystemProperty函数的调用,这提供了fuzz思路。
04
自动化测试工具代码编写逻辑
根据以上的原理,自动化测试工具代码编写逻辑如下:
1. 列出所有注册在ServiceManager中的系统服务名
2. 反射获取android.os.ServiceManager对应类及其getService函数
3. 反射调用getService函数传入1步骤获取的系统服务名获取IBinder
4. 通过IBinder获取接口名,通过反射获取接口中Stub内部类,反射获取Stub类中以TRANSACTION_开头的字段,获取其对应值,记为code, 形如static final int TRANSACTION_setUserName = 10, code 等于 10,setUserName认为是函数名。再通过反射获取接口下的方法名、方法参数类型,返回值类型
5. 构造Parcel类型参数,调用IBinder下transact(int code,Parcel data, Parcel reply,int ) 函数,这个函数中有4个参数,第一个参数就是4步骤中的code,服务端会根据code调用相应处理函数。但是4步骤中有可能获取不到code,这里会默认分别尝试[0,20]区间,和[21,1000]中的一个随机值。
第二个参数data是发送数据,首先需要调用writeInterfaceToken填充一下接口名,接着填充函数参数,参数类型就是4步骤中获取的参数类型,这里做两种fuzz策略:
1)精确识别出code, 构建精确的参数类型与个数,进行精准测试,主要用于测试Server提供的服务函数能否被任意调用。
2)精确识别出code,识别不出使用枚举code或随机code, 每次请求只写入int类型“0”或者”1”, String 空类型或者非空,反序列化的对象等。通过返回值,快速识别FUZZ目标的接口是否有拒绝服务。
第三个参数reply是返回值,结合日志,异常等有利于判断问题类型。第四个通常设置为0
05
总结
一般发现问题如下:
·
系统拒绝服务导致手机重启
·
调用敏感函数,提升权限
但也有如下不足之处:
1. 某些系统服务并不能通过反射的方式获取,比如服务端提供的服务代码在native层
2. 基于日志监测结果的FUZZ方法,对于拒绝服务手机重启的情况,不一定能精确定位到系统服务的某个函数,不过对于单台手机每次测试服务次序是线性不变的,可以通过跳过某些系统服务及其函数,和函数FUZZ后及时刷新日志来减少测试时间和精准定位测试函数。
3. 有些Binder Service 并不在ServiceManager中注册,通过其它注册的Server做为中介,有些书中称呼这种叫匿名Binder Service,上述方法没办法测试到。
4. 工具不是万能的,对于C/C++编写的系统服务,目前主要通过安全设计规范与代码审计规避风险。有些系统服务提供的java层函数要用反射的方式手工调用验证,也有fuzz效果不好的服务需通过构造aidl文件,手工验证。
参考文章:
1. https://cloud.tencent.com/developer/article/1058346
2.《深入理解Android内核设计思想》
END
长按关注 最新动态
好文!在看吗?点一下鸭!
您可能也对以下帖子感兴趣
{{{title}}}
文章有问题?点此查看未经处理的缓存