抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

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

image-20230730180250937

准备

漏洞提权

  1. 将仓库OpenWRTInvasion下载或clone到本地。

  2. 使用Python安装目录下依赖:

    pip install -r requirements.txt
  3. 运行漏洞提权工具:

    python remote_command_execution_vulnerability.py
  4. 登录到路由器Web页面,复制链接输入到漏洞提权的工具。

  5. 提权完成后,通过ssh和ftp连接就可以控制路由器了。

备份

进行下一步工作之前,我们需要将原厂的bootloader分区、eeprom分区备份,通过查阅OpenWrtXiaomi-4C的原厂闪存布局得知:

  • mtd1 = bootloader
  • mtd3 = 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.bin
  2. 使用ftp备份到本地(备份前需确认大小是否正确)。

刷入Breed

  1. 将breed.bin文件复制到远端/tmp目录下。

  2. 通过ssh执行下列命令刷入Breed:

    mtd write /tmp/breed.bin Bootloader
  3. 刷入完成后,长按复位键复位路由器。

  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 8000
  2. 使用telnet连接到Breed,再通过wget命令下载局域网的OpenWrt文件:

    wget [.../openwrt.bin]

    image-20230730155131420

    记住这里的两个信息:

    • Length: {Length}
    • Saving to address {save addr}
  3. 运行命令擦除要写入的分区:

    flash erase {start addr} {size}

    这里以firmwire为例,起始地址0x160000,大小0xea0000

    image-20230730161034521

  4. 运行命令刷入openwrt.bin文件:

    flash write {start addr} {save adrr} {size}

    这里以firmwireOpenWrt 22.03.5为例,起始地址0x160000,存储地址为0x80000000,大小为0x5c0139

    image-20230730161344290

  5. 运行命令加载内核:

    boot flash 0x160000

    现在就已经可以正常启动OpenWrt了

  6. 设置OpenWrt自启动:更改环境变量字段,实现自动执行命令加载内核
    env-autoboot

后记

这个路由器系统启动的过程分为以下阶段:**引导加载程序(bootloader)启动并加载内核(kernel),内核运行并挂载文件系统,内核开始执行用户模式程序,内核将权限交给用户模式程序以继续系统执行。**如果直接采用通用Breed的图形界面进行刷机就会导致无限重启。


评论