外观
XiaoMi 4C刷入OpenWrt踩坑
前言:最近不是毕业季嘛,捡垃圾捡了一个小米4C路由器,简单擦洗了一些污垢后直接上电,发现能用。搜了下参数很便宜,但是因为是白嫖的😋,还是准备刷个OpenWrt。目前刷入的是官方版本
22.03.5,在此感谢 @MALossov巨巨(Orz)的帮助,总算是把这个路由器的坑踩完了🥰。

准备
XiaoMi Mi Router 4C路由器- 一根网线
Python环境Breed:https://blog.hackpascal.net/- 漏洞提权工具:https://github.com/acecilia/OpenWRTInvasion
OpenWrt固件:https://downloads.openwrt.org/releases/22.03.5/targets/ramips/mt76x8/openwrt-22.03.5-ramips-mt76x8-xiaomi_mi-router-4c-squashfs-sysupgrade.bin

漏洞提权
1.将仓库OpenWRTInvasion下载或clone到本地。
2.使用Python安装目录下依赖:
pip install -r requirements.txt3.运行漏洞提权工具:
python remote_command_execution_vulnerability.py4.登录到路由器Web页面,复制链接输入到漏洞提权的工具。
5.提权完成后,通过ssh和ftp连接就可以控制路由器了。
备份
进行下一步工作之前,我们需要将原厂的
bootloader分区、eeprom分区备份,通过查阅OpenWrt的Xiaomi-4C的原厂闪存布局得知:
mtd1 = bootloadermtd3 = eeprom
Stock /proc/mtd
dev: size erasesize name
mtd0: 01000000 00010000 "ALL"
mtd1: 00020000 00010000 "Bootloader"
mtd2: 00010000 00010000 "Config"
mtd3: 00010000 00010000 "Factory"
mtd4: 00010000 00010000 "crash"
mtd5: 00010000 00010000 "cfg_bak"
mtd6: 00100000 00010000 "overlay"
mtd7: 00c60000 00010000 "OS1"
mtd8: 00af0000 00010000 "rootfs"
mtd9: 00200000 00010000 "disk"- 以上信息可连接到路由器后,输入
cat /proc/mtd查看
1.将整个磁盘分区命名为all.bin备份到tmp路径:
dd if=/dev/mtd0 of=/tmp/all.bin将Bootloader分区命名为bootloader.bin备份到tmp路径:
dd if=/dev/mtd1 of=/tmp/bootloader.bin将Eeprom分区命名为eeprom.bin备份到tmp路径:
dd if=/dev/mtd2 of=/tmp/eeprom.bin2.使用ftp备份到本地(备份前需确认大小是否正确)。
刷入Breed
1.将breed.bin文件复制到远端/tmp目录下。
2.通过ssh执行下列命令刷入Breed:
mtd write /tmp/breed.bin Bootloader3.刷入完成后,长按复位键复位路由器。
4.通过浏览器访问192.168.1.1进入breed。
刷入OpenWrt
通过阅读OpenWrt的XiaoMi_mi_Router_4C的dts文件
/{your openwrt source location}/openwrt/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4c.dts我们发现,firmwire分区的起始地址为0x160000,大小为0xea0000,即:内核(kernel)位于0x160000起始。
然而,需要注意的是,我们使用的通用breed刷机工具并没有对其进行适配。如果你选择使用图形界面刷机方式,只能选择几个有限的位置,比如0x60000等。这就导致了一个问题:
尽管bootloader能够在0x60000地址正确加载内核,但由于内核中嵌入了dtb文件,而dtb文件定义了文件系统的位置,如果你将OpenWrt刷入0x60000地址,由于整个文件向前移动了,导致文件系统也跟着向前移动。因此,dtb无法找到正确挂载文件系统的位置(标识为magic:D0 0D FE ED),导致整个系统启动过程失败并不断重启。
OpenWrt snapshot /proc/mtd
dev: size erasesize name
mtd0: 00020000 00010000 "bootloader"
mtd1: 00010000 00010000 "config"
mtd2: 00010000 00010000 "factory"
mtd3: 00010000 00010000 "crash"
mtd4: 00010000 00010000 "cfg_bak"
mtd5: 00100000 00010000 "overlay"
mtd6: 00ea0000 00010000 "firmware"
mtd7: 002052ab 00010000 "kernel"
mtd8: 00c9ad55 00010000 "rootfs"
mtd9: 00a10000 00010000 "rootfs_data"为了解决这个问题,我们需要手动将OpenWrt刷入到0x160000起始的闪存位置上:
1.使用Python开一个局域网的共享文件夹:
python -m http.server 80002.使用telnet连接到Breed,再通过wget命令下载局域网的OpenWrt文件:
wget [.../openwrt.bin]
记住这里的两个信息:
- Length:
- Saving to address
3.运行命令擦除要写入的分区:
flash erase {start addr} {size}这里以firmwire为例,起始地址0x160000,大小0xea0000

4.运行命令刷入openwrt.bin文件:
flash write {start addr} {save adrr} {size}这里以
firmwire和OpenWrt 22.03.5为例,起始地址0x160000,存储地址为0x80000000,大小为0x5c0139

5.运行命令加载内核:
boot flash 0x160000现在就已经可以正常启动OpenWrt了
6.设置OpenWrt自启动:更改环境变量字段,实现自动执行命令加载内核 
后记
这个路由器系统启动的过程分为以下阶段:引导加载程序(bootloader)启动并加载内核(kernel),内核运行并挂载文件系统,内核开始执行用户模式程序,内核将权限交给用户模式程序以继续系统执行。如果直接采用通用Breed的图形界面进行刷机就会导致无限重启。
版权所有
版权归属:SAKE
