Hotdry.
ai-security

逆向工程小米加湿器云服务协议:实现本地控制与隐私保护

通过固件提取、网络协议逆向与本地API重实现,将小米加湿器从云端依赖中解放,实现完全本地控制与隐私保护的技术实践。

引言:云依赖的困境与本地化需求

小米智能家居设备以其高性价比和丰富的生态链赢得了大量用户,但随之而来的是对云端服务的深度依赖。以小米加湿器为例,用户需要通过米家 App 连接小米云服务才能实现远程控制、定时设置和状态监控。这种架构带来了三个核心问题:隐私风险(设备数据上传至云端)、可用性依赖(断网即失能)和服务寿命限制(厂商停止服务即变砖)。

逆向工程小米加湿器的云服务协议,实现本地控制,不仅是对设备所有权的重新主张,更是对智能家居数据主权的实践。根据 dustcloud 项目的经验,小米设备通常使用 MIoT(小米物联网)协议进行通信,支持局域网和云端两种模式,这为本地化改造提供了技术基础。

固件提取:三种技术路径的工程实践

1. 串口调试接口访问

大多数小米设备都保留了 UART 串口调试接口,这是最直接的固件提取路径。以 Aquara 智能摄像头为例,逆向工程师发现设备在启动过程中会输出详细的调试信息。通过识别 TX、RX 和 GND 引脚,使用 USB 转 TTL 适配器连接,可以在设备启动时中断引导过程,进入恢复模式。

关键参数

  • 波特率:115200 bps(小米设备常用)
  • 数据位:8 位
  • 停止位:1 位
  • 奇偶校验:无

在 JFFS2 文件系统未正确清理的情况下,设备可能泄露 root 凭证。如 Hackaday 文章所述,"由于 JFFS2 文件系统在 MCU 上未正确清理,大量凭证信息泄露,这足以通过 telnet 获取 root 权限。"

2. FEL 模式与 MMC 数据线短路

对于采用 Allwinner 芯片的小米设备(如部分扫地机器人),可以利用 FEL(Flash and Execute Loader)模式进行固件提取。这种方法需要物理接触设备主板:

  1. 识别 MMC 闪存芯片:通常为 eMMC 或 NAND 闪存
  2. 短路数据线:在设备启动时短路 CLK 和 CMD 引脚,迫使芯片进入 FEL 模式
  3. 使用 sunxi-tools 工具:通过 USB 连接,使用sunxi-fel命令读取闪存内容

安全阈值:短路时间控制在 100-500ms 之间,避免永久性硬件损坏。成功进入 FEL 模式后,可以使用sunxi-fel dump命令将整个闪存镜像导出为二进制文件。

3. OTA 更新漏洞利用

部分早期小米设备在 OTA(Over-the-Air)更新机制中存在输入验证不足的问题。如某款 WiFi 网络音箱,"在 HTTP 固件更新中未发现输入验证 —— 没有签名,信息打包为 XML 格式"。这使得攻击者可以构造恶意更新包,在设备下载时拦截并替换为自定义固件。

检测方法

  • 使用 Burp Suite 或 mitmproxy 拦截 OTA 更新请求
  • 分析更新包结构(通常为加密的二进制或 XML 格式)
  • 检查签名验证机制是否存在

网络协议逆向:从抓包到 MIoT 协议解析

抓包工具链配置

网络协议逆向的第一步是捕获设备与云端之间的通信流量。推荐的工具链配置:

  1. 网络拓扑:将加湿器连接到专用 WiFi 网络,使用路由器镜像端口或 ARP 欺骗将流量重定向到分析主机
  2. 抓包工具:Wireshark(图形界面)或 tcpdump(命令行)
  3. 解密支持:如果使用 TLS 加密,需要配置 SSLKEYLOGFILE 环境变量捕获会话密钥

关键过滤规则

# 过滤小米相关域名
host miio-api.mijia.com or host api.io.mi.com or host de.ot.io.mi.com

# 过滤设备通信端口
tcp.port == 54321 or udp.port == 54321

MIoT 协议结构分析

小米物联网协议(MIoT)采用 JSON-RPC over HTTP/HTTPS 架构,主要包含以下组件:

  1. 设备发现:UDP 广播在 54321 端口,消息格式为{"id":123,"method":"miIO.info"}

  2. 认证流程

    • 设备首次连接时从云端获取 token
    • 后续通信使用 token 进行签名验证
    • 签名算法:sign = md5(data + token)
  3. 属性操作

    {
      "id": 12345,
      "method": "set_properties",
      "params": [{
        "did": "humidity",
        "siid": 2,
        "piid": 1,
        "value": 60
      }]
    }
    

协议字段映射表

字段 说明 示例值
did 设备 ID 1234567890
siid 服务 ID 2(加湿器服务)
piid 属性 ID 1(目标湿度)
method 操作方法 get_properties / set_properties

加湿器特定协议分析

通过分析小米加湿器的网络流量,可以识别出以下关键操作:

  1. 湿度控制:设置目标湿度值(范围 40%-80%)
  2. 模式切换:静音模式、睡眠模式、自动模式
  3. 状态查询:当前湿度、水温、滤芯寿命
  4. 定时设置:开启 / 关闭定时任务

本地 API 重实现:dustcloud 架构与集成方案

dustcloud 项目架构

dustcloud 项目提供了完整的小米云服务仿真方案,其核心组件包括:

  1. dummycloud:模拟小米云服务,响应设备请求
  2. miio_client:实现 MIoT 协议客户端库
  3. 设备适配层:针对不同设备类型的特定实现

部署架构

设备 <-> 本地网络 <-> dummycloud (模拟云端) <-> Home Assistant/自定义控制端

本地 API 服务器实现

基于 dustcloud 的经验,实现本地 API 服务器需要以下组件:

  1. 设备发现服务

    import socket
    import json
    
    def discover_devices():
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.bind(('0.0.0.0', 54321))
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        
        # 发送发现请求
        message = json.dumps({"id": 1, "method": "miIO.info"})
        sock.sendto(message.encode(), ('255.255.255.255', 54321))
    
  2. 命令处理引擎

    class MiIoHandler:
        def __init__(self, device_token):
            self.token = device_token
            
        def verify_signature(self, data, signature):
            import hashlib
            expected = hashlib.md5((data + self.token).encode()).hexdigest()
            return expected == signature
        
        def handle_set_properties(self, params):
            # 解析并执行设备控制命令
            for prop in params:
                siid = prop['siid']
                piid = prop['piid']
                value = prop['value']
                self._apply_to_device(siid, piid, value)
    
  3. 状态同步机制:定期轮询设备状态,或实现设备主动上报

Home Assistant 集成配置

将本地化的小米加湿器集成到 Home Assistant 中,实现统一管理:

  1. 自定义组件配置

    # configuration.yaml
    xiaomi_humidifier_local:
      host: 192.168.1.100
      token: "设备token"
      name: "卧室加湿器"
    
  2. 自动化规则示例

    automation:
      - alias: "自动调节湿度"
        trigger:
          platform: numeric_state
          entity_id: sensor.bedroom_humidity
          below: 40
        action:
          service: humidifier.set_humidity
          target:
            entity_id: humidifier.bedroom
          data:
            humidity: 50
    

安全考量与风险控制

隐私保护实现

  1. 数据本地化:所有传感器数据仅在本地网络处理,不上传云端
  2. 通信加密:即使在本地区域网络,也应使用 TLS 加密通信
  3. 访问控制:实现基于角色的访问控制(RBAC),限制设备操作权限

风险评估矩阵

风险类型 可能性 影响程度 缓解措施
设备变砖 备份原始固件,保留恢复能力
保修失效 评估保修价值与本地化收益
安全漏洞 定期安全审计,及时更新补丁
兼容性破坏 保持协议兼容性,支持回滚

监控与告警配置

建立本地化设备的健康监控体系:

  1. 设备状态监控:心跳检测,离线告警
  2. 性能指标收集:响应时间、错误率、资源使用率
  3. 安全事件日志:异常访问尝试、协议违规记录

工程实践清单

硬件准备清单

  • USB 转 TTL 串口适配器(CP2102 或 CH340 芯片)
  • 万用表(用于引脚识别)
  • 焊接工具(可选,用于稳定连接)
  • SD/TF 卡读卡器(用于闪存镜像读写)

软件工具清单

  • sunxi-tools(Allwinner 设备)
  • binwalk(固件分析)
  • Wireshark/tcpdump(网络抓包)
  • Python 3.8+(开发环境)
  • dustcloud 项目源码

实施步骤检查表

  1. 设备型号确认与兼容性验证
  2. 原始固件完整备份
  3. 串口调试接口识别与连接
  4. 引导过程分析与中断点确定
  5. 文件系统挂载与文件提取
  6. 网络协议抓包与分析
  7. 本地 API 服务器开发与测试
  8. 集成测试与功能验证
  9. 监控告警系统部署
  10. 文档编写与知识传递

结语:从消费者到建设者

逆向工程小米加湿器的过程,本质上是从被动消费者到主动建设者的转变。通过深入理解设备的工作原理、通信协议和系统架构,我们不仅获得了对设备的完全控制权,更重要的是建立了对智能家居技术的深刻认知。

这种技术实践的价值不仅限于单个设备的解放,更为整个智能家居生态的开放性和互操作性提供了参考路径。当更多用户和技术爱好者参与到设备本地化的实践中,将推动厂商重新思考产品架构,在便利性与用户主权之间找到更好的平衡点。

正如 dustcloud 项目所展示的,开源社区的力量能够破解封闭系统的壁垒,为智能家居的真正智能化 —— 即用户完全控制下的智能化 —— 奠定技术基础。小米加湿器的本地化改造,只是这个宏大叙事中的一个小小章节,但每一个这样的章节都在推动着整个行业向着更加开放、透明和用户友好的方向发展。


资料来源

  1. dustcloud 项目 - Xiaomi Smart Home Device Reverse Engineering and Hacking (https://github.com/dgiese/dustcloud)
  2. Reverse-Engineering Xiaomi IoT Firmware - Hackaday (https://hackaday.com/2019/10/24/reverse-engineering-xiaomi-iot-firmware/)
  3. MiService 小米云服务完整使用教程
  4. Xiaomi Home Integration for Home Assistant 开发者指南
查看归档