FANS: Fuzzing Android Native System Services via Automated Interface Analysis

主要解决什么问题

将Fuzzing技术应用到Android Native system services 面临的问题有:

  • android native system services 通过特殊的程序间通信机制调用,即名为binder的机制,它通过服务特定的接口调用服务。因此Fuzzer 需要辨识所有接口,自动化地生成特定接口的测试用例
  • 有效的测试用例应该满足所有接口的接口模型
  • 测试用例也应该满足语义要求,包括变量依赖性和接口依赖性

Android 系统中system services 要注册到 Service Manger。用户app 通过查询manger 获得访问目标services 的接口(封装在代理绑定器对象中 Proxy Binder object),然后通过形如IBinder::transact(code,data,reply,flags)的统一远程过程调用(RPC)接口,调用该接口提供的不同事务。code决定要调用的事务,data是事务的输入的序列化形式。因此,我们可以利用这个统一的IPC方法来测试所有的系统服务。为了彻底测试目标服务,我们可以首先找到所有接口和可用的事务,然后用满足该服务特定的格式和语义要求的输入数据来调用它们。具体而言,有三个挑战需要应对:

  • 多级接口识别
  • 接口模型提取
  • 生成语义正确的输入

propose a generation-based fuzzing solution FANS to address the aforementioned challenges.

在https://github.com/iromise/fans.开源了FANS的原型

总结本文做出的贡献:

  • 我们系统地研究了Android native system services 中接口之间的依赖关系,挖掘了更深的多层接口。
  • 提出了一种自动提取输入接口模型和语义的解决方案。这种方法也可以应用于其他基于接口的程序。
  • 我们提出了一个解决方案,通过在序列化和反序列化pair中利用 变量名和类型知识 来推断事务间的依赖关系。
  • 我们实现了一个FANS原型来系统地模糊Android本地系统服务,并发现了30个独特的本地漏洞和138个独特的Java异常

使用的方法

FANS.png

上图展示了我们的解决方案FANS的设计概述。首先,接口收集器(第3.3节)收集目标服务中的所有接口,包括顶级接口和多级接口。然后接口模型提取器(第3.4节)为这些接口中的每个候选事务提取输入和输出格式以及变量语义,即变量名和类型。提取器还收集与变量相关的结构、枚举和类型别名的定义。接下来,依赖推断器(第3.5节)推断接口依赖,以及事务内和事务间变量依赖。最后,基于上述信息,模糊引擎(第3.6节)随机生成事务,并调用相应的接口来模糊本地系统服务。fuzzer引擎还有一个管理器,负责同步主机和被测手机之间的数据。

3.3Interface Collector

顶层或多层接口都有调度事务的onTransact方法。因此,我们可以利用这个特性来识别接口。不过,我们并不直接扫描AOSP代码库中的C/C文件来获取onTransact方法。相反,我们检查在AOSP编译命令中作为源出现的每个C/C文件,以便我们可以收集在编译期间由AIDL工具动态生成的接口,否则这些接口将被忽略。

3.4Interface Model Extractor

Design Choices

RPC-centric testing:以RPC(remote procedure call)为中心的测试,攻击者必须通过IPC接口与目标service交互,并且只能产生有限数量的事件。为了减少误报,选择通过RPC接口测试目标服务。

Generation-based fuzzing:基于生成的fuzzing比mutation-based fuzzing 有更高的代码覆盖率,更好的语义,更少的漏报等优点。

Learn input model from code:大意就是:基于生成的模糊测试器依赖于输入模型知识来生成有效的测试用例。FANS是通过分析Android 源码自动化构建输入模型。

Interface Model Extractor

  • 从服务端代码中提取接口
  • 先将AIDL文件转为C++文件,然后使用AST提取接口模型

Transaction Code Identification

通过分析AST中的switch-case的case节点,就可以轻松的分析出接口的所有事务,并识别出相关的常量事务代码(constant transaction code)

Input and Output Variable Extraction

识别出事务代码以后,需要从向每个事务传递的参数data中提取输入的反序列化。此外,由于我们想推断事务的内部依赖,我们也需要提取事务的输出,输入是被序列化到reply的数据

事务中使用的变量有三种可能的类别:

  • Sequential Variables 这种类型的变量没有任何前提条件。
  • Conditional Variables 这种类型的变量取决于一些条件。如果不满足这些条件,变量可能为空,或者不出现在数据中,甚至与满足条件时的类型不同
  • Loop Variables 这种类型的变量在循环甚至嵌套循环中被反序列化

这三类变量恰好对应程序中的三类语句,即顺序语句、条件语句和循环语句。因此,我们将主要在AST中处理这类语句。

Type Definition Extraction

除了提取事务中的输入和输出变量,我们还提取类型定义。它有助于丰富变量语义,以便生成更好的输入。有三种类型需要分析:

  • Structure-like Definition 这种类型包括联合和结构
  • Enumeration Definition 提取所有给定的(常量)枚举值
  • Type Alias

3.5Dependency Inferer

在提取接口模型后,我们推断出两种依赖关系:

(1)接口依赖。即如何识别和生成多级接口。它还暗示了一个接口如何被其他接口使用。

(2)变量依赖。事务中的变量之间存在依赖关系。以往的研究很少考虑这些依赖性。

具体的依赖识别方法就不赘述了

3.6Fuzzer Engine

首先,fuzzer管理器会将fuzzer程序的二进制文件、接口模型和依赖同步到手机上,并在手机上启动fuzzer。然后Fuzzer将生成一个测试用例,即一个事务及其相应的接口来模糊测试远程代码。同时,fuzzer管理器将定期同步手机上的崩溃日志。

结果评估

Experimental Setup As shown in Fig Overview-of-FANS, we implement the first three components on Ubuntu 18.04 with i9-9900K CPU, 32 GB memory, 2.5 T SSD. As for test devices, we use the following Google’s Pixel series products: Pixel * 1, Pixel 2XL * 4, and Pixel 3XL * 1. We flash systems of these smartphones with AOSP build number PQ3A.190801.002, i.e., android-9.0.0_r46, which is a recent version supporting these devices when writing this paper. Although the Android release versions are the same, the source code can be slightly different for different Pixel models. For the following two sections (Section 5.1, Section 5.2), we report the experiment results carried out on Pixel 2XL.

How many interfaces have been found? What is the relationship between them? (Section 5.1)

FANS1.png

FANS2.png

What does the extracted interface model look like? Is the model complete and precise? (Section 5.2)

FANS3.png

虽然不能做到完全精确和完整,但是足够好了

How effective is FANS in discovering vulnerabilities of Android native system services? (Section 5.3)

为了评估FANS的有效性,我们在六部智能手机上断断续续运行了大约30天。我们已经从FANS报告的成千上万的崩溃中发现了30个独特的错误,下表列出了所有30个漏洞。除了在Android原生系统服务中发现的22个漏洞之外,在作为Android原生系统服务中的公共库的libcutils.so、libutils.so和libgui.so库中还有5个漏洞。此外,我们在Linux系统组件中发现了三个漏洞。例如,我们在iptables-restore中发现了一个堆栈溢出。这个程序是firewallconfiguration提供的用户空间程序。这些漏洞证明了FANS生成的输入可以在复杂的约束下驱动控制流进入深层路径。

FANS4.png

此外,虽然我们的目标是发现用C++实现的Android原生系统服务中的漏洞,但我们触发了138个Java异常,如FileNotFoundException、DateTimeException、NoSuchElementException和NullPointerException。这可以归因于Java应用程序有时依赖Android原生系统服务的事实。一些本地服务也调用Java方法。由于健壮性和稳定性对于Android原生系统服务很重要,所以这些Java异常应该不会发生。应该实施更严格的检查来解决这个问题。

我们已经向谷歌报告了所有本地漏洞。其中20个被确认,18个被给予安卓身份证,其中三个与未披露的漏洞报告重复。到目前为止,谷歌已经给安卓ID 143895055和143899228分配了中等严重度。谷歌还将CVE-2019-2088分配给安卓标识143895055,并将在未来将我们放入他们的确认页面。正在提交Java异常。

对我有什么启发

此前没了解过Fuzzing技术,借此文章进行学习。同时,也尝试从不同角度了解android 系统原理。文中提到的Native Services, Services Manager 等技术可以参考文末链接。

论文链接:https://www.usenix.org/conference/usenixsecurity20/presentation/liu

参考文章:

Service与Android系统设计(6)— Native Service https://blog.csdn.net/21cnbao/article/details/8087328

Service与Android系统设计(4)-- ServiceManager https://blog.csdn.net/21cnbao/article/details/8087304

Service与Android系统设计(2)-- Parcel https://blog.csdn.net/21cnbao/article/details/8086619

Android系统服务(SystemService)简介 https://blog.csdn.net/geyunfei_/article/details/78851024