作者:Jiongyi Chen, Wenrui Diao, Qingchuan Zhao, Chaoshun Zuo, Zhiqiang Lin, XiaoFeng Wang,Wing Cheong Lau, Menghan Sun, Ronghai Yang, and Kehuan Zhang

单位:The Chinese University of Hong Kong, Jinan University, The University of Texas at Dallas, Indiana University Bloomington

出处:NDSS 2018

资料: PDF, Slides, Video


Abstract

现有的针对IoT设备的安全分析工作都是基于固件来展开的,这样会引入如何获取固件以及如何分析固件的问题。

考虑到设备以及架构的多样性,作者借助IoT设备的移动端App设计了一个黑盒模糊测试工具来避开这类问题以分析IoT设备上的内存错误漏洞。

作者设计并实现了IOTFUZZER并测试了17个不同的IoT设备,最终发现15个内存错误漏洞,其中包括了8个未知的漏洞。

INTRODUCTION & BACKGROUND

Motivation

基于固件对IoT设备进行系统地安全分析有以下困难: 1. Firmware Acquisition

- 网络爬虫获取:许多厂商并不提供固件下载
- 通过调试端口获取:越来越多的厂商禁用调试端口
  1. Firmware Unpacking

    • 许多固件是压缩甚至加密过
  2. Executable Analysis

为了降低功耗和成本,不同厂商会使用的不同的架构来开发特定功能的设备

- 二进制文件静态分析会耗费大量的人工分析,例如调整load offset、处理反汇编error之类操作
- 目前自动化地静态分析则是使用模式匹配,这样会导致精确度较低
- 如果在设备上动态分析,则有部分设备禁用了调试端口(e.g. UART, JTAG)
- 在模拟器上动态分析,则需要绕过没有NVRAM触发的异常等问题

Approach

image-20190527151312428

作者认为,对于IoT设备来说,用户所在移动端设备上安装的操作App可以提供许多丰富的交互信息,那么可以利用它们可以发送测试数据。 这样可以明显降低在分析漏洞时逆向可执行文件的困难度和工作量。 因此,作者设计一个基于移动应用程序的模糊测试框架。

Challenges & Solutions

鉴于当前并没有IoT通用或领域特定的协议,这就导致各个设备的网络协议都是私有的。而且有些厂商在对协议中数据进行加密时使用的还不是标准的加密函数,所以需要生成分析协议的格式以及加密算法,以生成协议导向并包含加密相关的信息。现有的AutoForge只能处理HTTP流量以及私有加解密函数。

A Running Example

image-20190527160140423

image-20190527160151887

这是 TP-Link Kasa设备所支持的App中代码片段,此App用来控制TP-Link生产的多个智能家居设备,包括Wi-Fi智能插头,智能灯泡,Wi-Fi扩展器等。图中有两个函数:一个用于构造请求消息以设置IoT设备; 第17行的另一个函数用于加密输出消息。

最终会发送如下Json类型数据到服务器

image-20190527160526042

在Fuzz时,作者希望修改systemset_dev_location之类的字段以便测试。对于XML,HTTP以及Json之类通用协议来说十分方便。 但是,这种方法不能用于未知协议。

Challenges

Mutating fields in networking messages

识别协议中的哪些数据是可以被用来修改为mutation的,通用协议较为方便,难点在于私有协议

Handling encrypted messages

有些协议的字段甚至全部协议本身是加密的,所以需要以相同的方式加密的包含数据(Mutated)的协议消息。

Monitoring crashes

还需要监控设备的状态,因为IoT设备大多没有显示器,需要使用一种不接触设备为前提的方法检测设备是否Crash。

Solutions

Mutating protocol fields at data sources

针对未知协议的逆向比较花费精力,所以作者选择在数据源处对协议中所使用的数据进行修改。作者使用了数据流分析,这里数据源其实就是Source

Reusing cryptographic functions at runtime

因为修改了Source,所以对于加密函数不需要重新实现,只要重用即可,作者使用了Xposed hook这些函数

Detecting liveness with heartbeat mechanism.

发送心跳包以检测状态

DETAILED DESIGN

image-20190527162356435

A. UI Analysis

UI分析的目的是识别出与网络消息发送相关的事件以便于后续数据流分析和fuzz。

首先使用Androguard构建CFG,对于隐式的控制流转换(例如thread.start和thread.run的回调)使用EdgeMiner分析并添加到CFG上,以分析出那些操作会触发网络消息事件

然后使用Monkeyrunner构建出什么样的UI触发顺序可以触发相应的网络事件,例如,先点击Text框,然后输入数据点击发送Button以发送消息。

B. Data-flow Analysis

为了识别那些数据与要发送到IoT设备的消息内容(例如,字符串常量,系统API的返回值等)从选定元素中跟踪数据流以确定影响某些消息字段的内容。 然后,这些数据会被改变字段的内容以进行fuzz。使用TainDroid实现

  • Taint Sources:system APIs;UI Input
  • Taint Propagation:修改传播规则,可以保存任意数量的污点tag
  • Taint Sinks:networking APIs; encryption functions

启发式选择包含算术和按位运算的函数作为加密相关函数

C. Runtime Mutation

优势: 1. 协议字段可以在加密或者编码之前修改 2. 未知协议也在不逆向协议细节的情况下fuzz

使用xposed在数据流分析出sink为目标sinks的source生成处进行hook并修改其值。

Fuzzing Scheduling

并不是全部修改所有的source,因为这样更容易触发设备的异常导致粒度不够细。

Fuzzing Policy

  • 使用’A’扩展字符串的长度以测试堆栈溢出和数组越界
  • 修改int、double、float值以测试堆栈溢出和数组越界
  • 修改数据类型或者空值以测试misinterpretation或者未初始化漏洞

D. Response Monitoring

用心跳包检测设备的状态以判断是否发生了Crash

  • Expected Response
    • not interested
  • Unexpected Response
    • untreated errors
  • No Response
    • Dos or dead loops
  • Disconnection
    • Crash

EVALUATION

选择了17个测试作为样本

image-20190527181640836

通过IOTFUZZER(每台设备运行24小时)对17台IoT设备进行fuzz,一共在9台设备中发现了15个严重漏洞(内存错误)。 从表II中可以看出,这些包括5个栈溢出,2个堆溢出,4个空指针解引用和4个崩溃。

image-20190527182816190

其中有7个(46.7%)可以远程利用。例如,攻击者可以在知道Brother打印机IP的情况下使其拒绝服务或使TP-Link Smart插头崩溃。

image-20190527182927761

表III将IOTFUZZER与默认配置的开源网络协议fuzzer进行比较:Sulley和BED。

Case Studies

HS110是普联的 Wi-Fi智能插头,可以通过官方app读取实时功耗数据。 可以通过本地Wi-Fi网络或Internet访问此设备。 攻击者可以通过打开/关闭Wi-Fi智能插头来打开/关闭设备。 作者通过UI分析和污点跟踪开始测试,然后IOTFUZZER开始执行Fuzzer。 为了显示原始消息和Fuzz消息,作者在加密函数之前输出消息的明文。 43分钟后,IOTFUZZER发生了崩溃,并显示以下输出消息:

image-20190527191047792

原始App发出消息如下:

image-20190527191054767

然后设备开始亮起红灯,作者通过手工分析固件相应代码,发现此处有一个使用未初始化的指针触发的漏洞。

代码如下:

image-20190527191349234

这里在第14行,strncpy() 被调用(参数为a1和a0)。但是在调用strncpy() 之前,在第12行,参数a1为地址v0+0x10的内存内容,这是一个指向CJSON结构中预期字符串的指针。 当传入的是int 0而不是字符串(例如“lights on”)时,则不会初始化指针 [0x10($v0)]。 因此,将在函数strncpy() 中触发NPE。

Belkin WeMo Switch

Belkin Wemo Switch是一个用户可以在App上配置的交换机。 当输入以下数据时候crash:

image-20190527193539594

就是说,当SetSmartDevInfo内没有数据时,会崩溃。作者通过使用调试端口发现,SetSmartDevInfo中硬要要有<SmartDevURL>对象。 如果没有<SmartDevURL>,数据结构中的指针不会被初始化,然后读取0x00000000处的内容导致Crash。