小米智能存储(MINAS RP05)ROOT 破解 + 持久化

2026-11-04 拿 root,11-05 凌晨完成持久化 + 彻底搞懂 mi-shell 机制。目标:奎星阁 192.168.3.125(固件 1.0.9.462.F24C26D24-REL,did 1220307069,米家 uid 98067140,MAC D4:53:2A:C7:9E:7C,主机名 minasc79e7c)。 同账号下还有第二台 RP05 192.168.3.45(同名固件,本次未动,掉线待查)。

2026-11-05 彻底清理(失忆) + 现状 + 按需重拉

11-05 决策:应用中心方向改为基于 Finsys/dockhand(docker 管理 Web UI)自建;旧社区商店(0.1.3,装 /data/plugin/community-store)弃用;SSH 不固化(不持久化,重启即失忆)。当天做了一次彻底清理,把之前塞的所有东西清空,回到纯厂商态。

清理掉(11-05 已删)

/home/rootx(fakemi + .ssh + 整目录)、/etc/dropbear/authorized_keys(公钥)、ssh-fakemi.service+2软链、store-watchdog.service/.timer、/etc/syhotplug/pool/98.ssh-persistence、/data/ssh-persistence/(整目录)、/data/plugin/community-store(43M 社区商店)+ 其 unit/nginx conf;passwd root 的 home 从 /home/rootx 改回 /root;emby / qbittorrent 容器 + 镜像 + /data/apps/{emby,qbittorrent}(用户不要了)。

清理后保留(厂商/用户,绝没动)

容器只剩 miot_central(厂商中枢)+ 镜像 central_software_pack(厂商);共享池 /home/u98067140/pool0/data(我的文档/我的照片/downloads/番剧/百度网盘)完好;mi-shell 仍是原厂二进制(从头没碰)。重启后复核状态全保持(无残留复活)。

现状:干净厂商态 + 按需拉 2323

要 root shell 时按需重拉(不固化,重启即失忆):

cd <xiaomi-nas-ssh-root-tool 目录>      # 现暂在 Mac: ~/.hermes/cache/scratch/xiaomi-nas-ssh-root-tool
venv-minas/bin/python scripts/xiaomi-nas-root.py 192.168.3.125   # ≈2min: 注入 preload+trigger .so + 起 socat 2323 + dropbear 22 + 公钥
nc 192.168.3.125 2323                    # 进真 root shell(uid 0)

⚠️ 工具现在在 scratch,24h 未用会被清——要长期用必须搬到固定目录(如 ~/tools/)。

下一步:基于 dockhand 做小米应用中心

  • 参考 Finsys/dockhand(github.com/Finsys/dockhand;Svelte 前端 + Node/bun 后端 + Drizzle;server.js 是后端核心;docker compose 挂 /var/run/docker.sock)
  • 思路:借 dockhand 的 docker 管理逻辑做后端(建/管容器),小米侧自己补应用中心注册表 icon(/data/plugin/<uid>.list)+ 反向代理
  • 安装层可能要模拟 MTP;待设计。dockhand 源码已 clone 到 ~/.hermes/cache/scratch/dockhand。

产物(11-04 持久化版本,已于 11-05 彻底清理 —— 以下为历史参考)

通道用法重启后
SSH(正经通道)ssh -i ~/.ssh/id_ed25519_minas root@192.168.3.125✅ 可用:dropbear.socket 已 enable + ssh-fakemi.service 自动 bind-mount
root shell(临时)nc 192.168.3.125 2323(socat)❌ 消失,重跑注入脚本 ≈2 分钟可恢复

持久化组件(全部落在持久区,备份在 /data/ssh-persistence/):

  • /home/rootx/fakemi(28 字节:#!/bin/sh + exec /bin/sh "$@",/home 是 overlay、upper 在 /data/home/upper)
  • /etc/systemd/system/ssh-fakemi.service(enabled):boot 时 ① 补 dropbear.socket 的 enable 软链 ② bind-mount fakemi 盖住 /usr/sbin/mi-shell
  • dropbear.socket:systemctl enable 过(sockets.target.wants 软链,/etc overlay 持久)
  • /etc/passwd root 行:root:x:0:0:root:/home/rootx:/usr/sbin/mi-shell(home 是我们改的;shell 保持厂商"祝福值"以通过白名单检查)

★ mi-shell 机制(11-05 搞懂的核心,推翻此前所有猜测)

厂商在 dropbear 二进制里硬编码了(tr -c '[:print:]' '\n' < dropbearmulti | sort -u 提取):

  1. 认证通过后 无条件 exec /usr/sbin/mi-shell(那个 ASCII logo + [MINAS] 菜单),无视 /etc/passwd 的 shell 字段
  2. 新增 /etc/shells 白名单检查,字符串:User '%s' has invalid shell, rejected——用户 shell 不在名单里直接拒登录

关键坑:

  • 厂商把所有文件日期伪造成 2011-04-06(dropbearmulti 看着像 2011 版,实际支持 ed25519,是近期版本)
  • 补丁字符串被混淆过:grep 'mi-shell' 查不到,必须用 tr 提取可打印串
  • /etc/shells 里有:/bin/sh、/usr/bin/bash、/usr/sbin/mi-shell

解法(不用构建任何东西):mount --bind /home/rootx/fakemi /usr/sbin/mi-shell。 补丁去 exec /usr/sbin/mi-shell → 内核命中 bind-mount → 跑 28 字节的 fakemi → exec /bin/sh = 真 root shell。 (此前白折腾了半宿:构建干净的 dropbearmulti 2026.94 静态版——完全不必要,因为不用换 dropbear,换 exec 的目标文件就行。)

设备文件系统布局(重要前提)

  • / = erofs 只读(base image,一切 /usr /bin 不可写,只能 bind-mount 盖)
  • /etc = overlay(lower=erofs,upper=/data/etc/upper)→ 可写 + 重启持久
  • /home = overlay(upper=/data/home/upper,9.7G)→ 可写 + 持久
  • /data = ext4(持久数据分区)
  • /var = tmpfs(重启即清 → cron 不可用于持久化,别想)
  • 厂商配置同步机制会删除 manifest 之外的 /etc 目录(实测回收了 /etc/syhotplug,upper 里留 whiteout 残留)→ 我们新造的 unit 文件理论上也可能被回收,/data/ssh-persistence/ 有全套备份可救

攻击链(kid0114/xiaomi-nas-ssh-root-tool,固件 1.0.9.462 专用)

  1. mTLS 客户端证书 → get_pool_info 拿 WebDAV 凭据(443/5000)
  2. WebDAV MKCOL 换行怪名目录 + add_samba_account uci heredoc 注入 → user_force=root 的 /etc SMB 共享
  3. 经 SMB 写 /etc/ld.so.preload + aarch64 触发 .so(固定机器码)→ cron 每分钟 root 任务 → socat 2323 + dropbear 22 + authorized_keys
  4. 成功后自动 disarm(preload/共享/staging/临时账号),公钥保留

踩坑实录

  1. Ed25519 客户端密钥:系统 Python 3.9.6 + LibreSSL 加载不了 → 用 Homebrew python3.13(或项目 venv scratch/venv-minas)。证书在 /Applications/小米智能存储.app/Contents/Resources/extraResources/cert/。
  2. 小米中间 CA 的 Basic Constraints 没标 critical:OpenSSL 3.x 严格拒绝 → 补丁:CERT_NONE 握手 + 手工链验证(SPKI 钉 6f8610da…3ae3)。
  3. 2511 = 共享已存在(设备被注入过、uci 残留)→ user_force 没落盘 → del_samba_account 删除后重新 add 一次通。set 接口的 user_force 参数会被静默忽略。
  4. syhotplug 机制在这台固件上不存在(全盘 grep 0 命中)→ 工具仓库文档里的 98 pool 钩子是空操作,别再用;systemd unit(After=local-fs + RequiresMountsFor)才是正解。
  5. 2323 socat 通道:命令含怪字符(换行/引号)时先 base64 再 | base64 -d | sh,输出等 marker。
  6. 改 root shell 会触发 /etc/shells 检查:shell 设成不在名单里的路径 → 直接 Permission denied (publickey,password)(曾误判为"key 坏了")。

重跑 / 恢复 / 抹除

  • 2323 临时通道:重跑主脚本 ≈2 分钟(venv python + 已打补丁的 xiaomi-nas-ssh-root-tool)。
  • 厂商同步吞了 unit(重启后 22 行为异常时):cp /data/ssh-persistence/ssh-fakemi.service /etc/systemd/system/ && cp /data/ssh-persistence/fakemi /home/rootx/ && systemctl daemon-reload && systemctl enable --now ssh-fakemi dropbear.socket。
  • 彻底抹除(失忆):umount /usr/sbin/mi-shell;删 /home/rootx/fakemi、/etc/systemd/system/ssh-fakemi.service + 两个 enable 软链、/etc/dropbear/authorized_keys、/home/rootx/.ssh/authorized_keys;passwd 里 root 的 home 改回 /root;/data/ssh-persistence 整个删。
  • 不要在 2323 会话里 systemctl restart(D-Bus 死锁),用 SSH。

操作纪律(血泪)

  • 卸载 SMB 挂载只卸自己创建的确切路径(mount | grep smbfs 会列出用户正在用的 番剧/我的照片——曾误卸导致用户拷贝中断)。
  • 动 NAS 注入前先问(审批门);不可逆/批量破坏性操作先列清单等授权。
  • 小米 mitee_tool rpmb set 是交互式 challenge-response,无官方凭证,别碰。

TODO

  • 重启验收一次(boot_id 变化后 ssh 应直接进真 shell;2323 会消失属正常)
  • .45(第二台 RP05)掉线原因排查
  • 需要 Docker/插件生态时再开(nijez/xiaomi-nas-plugin-market 需 root + 自备私钥)