# 智能设备Wi-Fi快速配置类协议安全

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2015-11-13T03:06:00Z
Canonical: https://wepostx.com/topics/1176

> 乌云历史资料归档
>
> **原始作者：** 唐朝实验室
> **原始编号：** superkieran-wooyundrops:887
> **原始发布时间：** 2015-11-13 11:06
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

# 0x00前言

目前市面上有不少缺乏输入装置但需要连接云端的智能设备，这些设备在加入Wi-Fi前需要得到相关的认证信息，为了便于用户使用，厂商通常在配套的移动端应用中通过类似下方的界面引导用户将Wi-Fi认证信息传输给智能设备。

![原文图片](/media/2016/06/2498e7d38803c64757b292390c753dce)

但在仅借助于已经加密的Wi-Fi通道的条件下，处在Wi-Fi网络内的移动应用端和在网络之外的智能设备间是如何传递这些信息的？各个厂商通过此类快速配置协议绕过这个相悖问题的同时，是否存在协议实现上的安全问题？

# 0x01 风险评估

设想一个场景：某房主和相识的人之间约定将钥匙放在某个地点，但是这一过程被三方知晓并随便复制了钥匙。如果应用和设备之间的传输是三方可以获取并看到明文内容的，那么就面临Wi-Fi认证信息泄露的风险。完整的加密过程需要包含有效的密钥交换，如果所用的密钥为固定或可预测，则算法本身不能保护数据的私密性，所以风险评估需要了解快速配置协议的具体实现。此外这类问题由于借助Wi-Fi路由器传递信息，受影响的攻击范围限定在能够接受Wi-Fi信号的范围内(写字楼或者住宅区)，而时间点定于等待进行配置的过程。

# 0x02 背景IEEE 802.2/802.11

要了解快速配置协议的工作原理，首先需要了解一些相关底层协议IEEE 802.2 与IEEE 802.11的简要信息，这两种标准对应在OSI网络模型层级关系如下：

![原文图片](/media/2016/06/899d027efa4645d13c698370fe50e2b5)

802.11协议簇是IEEE为无线局域网络制定的标准。802.11之上以802.2的逻辑链路控制(LLC)封装来携带IP封包。当设备开启Wi-Fi芯片的混杂模式监听无线信号，并以802.2 SNAP格式从数据链路层截取数据时，就会得到如下图所示的数据包：

![原文图片](/media/2016/06/d96b130003128b71e9c335e66a1059db)

802.2 SNAP 格式数据包
红色部分为Data Link结构，其中DA是目标MAC地址，SA是源MAC地址，Length为包长度。蓝色部分就是802.2 LLC的结构内容，之后跟着SNAP字段，DATA为加密后的IP封包内容，FCS为校验字段。除DATA字段为加密后的数据，其他字段为明文可见，快速配置协议可以通过这些明文可见的字段传输Wi-Fi认证信息。但是现在有一个问题：出于安全的考虑，在IOS和安卓上运行的普通移动端应用并没有权限去直接控制802.2 SNAP包头当中的数据。

# 0x03 数据载体方式一：包长度

既然不能直接控制底层包头中的内容，开发人员便想到可以通过发送不同长度的数据包，使包的长度本身作为一种信息载体（限于MTU的大小，每次传送~8Bit的数据），之后再将各个包长度携带信息重新组合成各家快速配置协议中定义的数据结构。从德州仪器的Ti CC3000芯片支持的第一种快速配置协议SmartConfig开始，到近期腾讯推广的Air Kiss协议来看，多是通过此种方法。可以在网上找到这些协议的详细分析或官方文档，例如SmartConfig协议：
[http://depletionregion.blogspot.com/2013/10/cc3000-smart-config-transmitting-ssid.html](http://depletionregion.blogspot.com/2013/10/cc3000-smart-config-transmitting-ssid.html)
这里就不再详细描述以长度为载体的协议实现方式了。

# 0x04 数据载体方式二：目标MAC地址

通过长度本身作为数据载体是个非常不错的思路，是否有其他的方式？在测试中尝试了小米智能摄像头，抓取到配置过程中的网络报文如下：

![原文图片](/media/2016/06/b48314f3f62f276cc70af807515a4cf9)

发现从开始到配置成功，之间每个报文的长度都是4字节，并且内容固定为miio。

![原文图片](/media/2016/06/01d2389b6ff8f146b12f61fa0ee7f290)

看来不是以长度为载体传递信息。细看这些发送的报文，似乎另有玄机。

## 0x04.1IP-MAC转换与组播
如之前提到，普通应用因为权限原因无法直接控制底层包头中的数据，那能否有迂回的方式能够更改其中DA的值(目标MAC地址)？一般情况下，上层应用在使用类似Socket编程时填入目标IP进行网络通信，之后操作系统会查询维护的路由表和ARP表，并确定底层网络包中需要填入的MAC地址。如果是同局域网目标将直接填入查询到的MAC地址，如果需要路由转发的则填入路由的MAC地址。要将DA(MAC地址)作为信息传递的载体就需要确定某种形式的IP-MAC的映射，但ARP表的变更也同样需要权限。是否还存在某种可行的方式进行IP-MAC间的映射？
单播(Unicast)，组播(Multicast)和广播(Broadcast)是IP网络传输的三种模式。其中组播在发送者和每一接收者之间实现单点对多点网络连接，该模式的出发点是节约网络传输带宽。组播有一个重要的特性就是IP地址和MAC地址是存在固定映射关系的：

![原文图片](/media/2016/06/00364607c468aa6dafa8f8d79ec50936)

从上面的图我们可以看到组播模式下IP-MAC之间可以完成23bits的数据映射。举一个简单的例子：如果应用向IP地址224.126.0.1发包，那么系统会自动将对应的MAC地址01:00:5e:7e:00:01填入底层包头结构中。

## 0x04.2 小米快速配置协议传输
回到截取到的在配置Wi-Fi认证给摄像头过程中的数据包，可以看到移动设备所发送网络报文的目标IP地址都是224.126开头的。其中IP-MAC的映射只使用了后16bit的内容，以224.126.X.Y为例，X字节被用作编号，而Y字节则是加载的数据。
使用底层包头DA字段(MAC地址)作为数据载体，并通过组播定义的IP-MAC地址映射实现应用层的数据控制就是小米系智能设备所使用快连协议的实现基础，这种实现方式相当的简洁清晰。

## 0x04.3 小米快速配置协议加密方式
小米所采用的协议和其他快速配置协议一样，没有直接明文传输认证信息。要解出明文传递的Wi-Fi认证信息，就需要逆向应用得到具体的加密方式。这里给出在完成逆向后得到的数据加密方式（简略版）：

- 将SSID，Wi-Fi密码，MAC地址和无线网络加密类型四个数据变形聚合(MiioLocalAPI)

- 通过System. currentTimeMillis()获取当前时间作为seed值，和上一步获取的聚合数据一起作为两个参数传入libmiio.so下的smencrypt函数

- 在smencrypt函数中，用seed值对一个固定16字节长的magic数组做一个字节的变形，之后连同聚合数据一同传入AES_cbc_encrypt函数进行AES128加密。AES算法所使用的Key和IV都来源于这个magic数组：

```text
Key = MD5_hash(magic_data, 16) IV = MD5_hash(Key + magic_data, 32)
```
magic_data的内容为：

```text
0x20, 0x59, 0x5C, 0xD3, 0x24, 0x10, 0x5D, 0x54, 0x14, 0xC6, 0xD4, 0xE3, 0xC8, 0x80, 0xC6, 0xF0
```

这样就得到了加密后的数据，解密需要反向操作。由此可以看到，在密钥和时间已知的情况下，如果使用默认的传输方式，三方可以获取明文的Wi-Fi认证信息。

# 0x05 应对

对于此类快速配置协议，在密钥的选择上最好做到每个设备有不同的密钥。交换密钥的方式可以是将密钥以二维码的方式粘贴在设备上(设备内已保存有一份)，配置时用移动端应用去扫描获取，完成密钥交换。或者直接使用范围更小的通信方式交换Wi-Fi认证信息。

# 0xFF 版权

本文独家首发于乌云知识库(drops.wooyun.org)。本文并没有对任何单位和个人授权转载。如本文被转载，一定是属于未经授权转载，属于严重的侵犯知识产权，本单位将追究法律责任。

## Replies
