小米路由器固件提取仿真
文章目录
- 小米路由器提取 && 仿真
- 提取文件系统
- 仿真
- 内核与最小文件系统选择:
- 模拟平台脚本编写:
- 最终效果:
- 网络配置:
- 如何传输 文件系统?
- 模拟运行 && uhttpd 启动
- 启动流程探索 && uhttpd 启动
小米路由器提取 && 仿真
鉴于在 6 月份的时候,因为那小米路由器的flash;导致摧毁了一块芯片。上次在实验室的时候依旧没有敢把那块芯片给使用吹分机给吹下来。但是,我的爱玩的好师兄们。在网上淘到了一块不需要吹下来,使用夹子夹的编程器(由于没以为能模拟成功,所以,没有拍照片)和另一位同学将固件给读了出来,于是借着这次机会,试一试学了好几个月的
qemu仿真的水平到底怎么样,并为停滞不前的老项目renode仿真找找灵感和思路。固件提取的部分,我们将会跳过;(后续有机会拍到照片的时候将再重新补充)
- 大致的思路:
- 文件提取文件系统
- qemu-system-* 仿真平台的搭建
- 最小文件系统的选择 && 内核的选择 (这里有大坑!!!)
- 模拟平台脚本编写;
- 细节处理 && 最终结果展示
- 网络配置 && ping 通宿主机
- 查看启动项,成功启动
uhttpd&& 为什么要去启动uhttpd
提取文件系统
这个部分应该是我们做的最轻松的一个部分了;
将提取好的固件,使用scp传到我们的虚拟机中,并使用binwalk -e xiaomi.bin将对应的固件解压即可;
对应的效果如下:
最后,使用:file bin/busybox查看当前的设备使用的平台类型(这个平台是mipsel)
仿真
内核与最小文件系统选择:
这个是花费了最长时间的地方,并且踩了很多的坑:对应的官方网站如下:
官方网站
最初的选择:kernel: vmlinux.elf ;最小文件系统:rootfs.cpio.gz (❌ 有坑)
后面的选择:kernel: vmlinux.elf;最小文件系统:rootfs.img
因为,知道最小文件系统的重要性;所以,这次选择去官网上找对应的官方版本,深度理解各个版本之间的不同区别,有些坑是得自己亲自跳进去的(其实就是傻,找的借口)
在使用最初的选择的时候,rootfs.cpio.gz 使用的是24.10.2的版本。就是 24年10月份的版本;这个版本在进行模拟仿真的时候,qemu不会去解压我们的最小文件系统:rootfs.cpio.gz。
为什么呢?新的kernel不会去关注;因为新 的kernel 处理定位rootfs.cpio.gz的位置和老的方法不一样了(rd_start和rd_size);他定位的方式不是通过偏移值和大小来定位的;所以,当使用这个文件的时候,内核定位不到他。就会一直循环的寻找,并且报错;
但是,去了官网上看了一下,只有24年之后的mips才出了小端序的版本;以往的版本只有bl;于是,这两点加在一起,我不得不放弃了最初的选择。
所以,最终,我们选择了:后面的选择。
模拟平台脚本编写:
这里最主要的参数就是:
-append相关的参数。细节很多;
1#/usr/bin/bash23echo"------------------ Emulator ---------------------"4echo"-- --"5echo"-- Progress Start --"6echo"-- --"7echo"-------------------------------------------------"8echo"Openwrt mirrors webSite: "9echo" https://mirror.sjtu.edu.cn/openwrt/releases/24.10.2/"10echo"author: Jiafeng"111213qemu-system-mipsel\14-Mmalta\15-m512\16-kernel./vmlinux.elf\17-hda./rootfs.img\18-append"root=/dev/sda rootfstype=squashfs rootwait ro console=ttyS0,115200"\19-nographic\20-netdevtap,id=net0,ifname=tap0,script=no,downscript=no\21-devicepcnet,netdev=net02223# -append params is very important. and then rootfstype=squashfs秀一下,我的vim配色,哈哈哈,也是捣鼓了好一阵子;
最终效果:
网络配置:
这个也是一个坑,我们首先宿主加上需要配置简单的 tap 口;来保证和客户机之间的通信;
宿主机上的配置:
# 宿主机上的配置:sudoiptuntapaddmode tap tap0 user"$USER"2>/dev/nullsudoipaddr flush dev tap0sudoipaddradd192.168.10.1/24 dev tap0sudoiplinksettap0 up客户机上的配置:
一定要将 eth0 网卡从桥接中拿出来!!!这个问题,在以往的配置中都没有遇见过;
# 客户机上的网卡配置iplinksetbr-lan down2>/dev/nulliplinkseteth0 nomaster2>/dev/nullipaddr flush dev eth0ipaddradd192.168.10.9/24 dev eth0iplinkseteth0 up /etc/init.d/firewall stopping192.168.10.1【Tips】:Linux 上使用 tcpdump 的网络抓包技巧:sudo tcpdump -i <interface-name> -n 'arp or icmp'通过这样的方式,来看当前的网络通信持续到了哪一步;
如何传输 文件系统?
这个是一个被忽略的问题,最小的文件系统上没有提供相关的关于 ssh 的服务的指令;所以,宿主机上不可能使用 scp 指令将文件传到客户机上,这该怎么办呢?
方案:
- 将文件系统先打包
- python 运行http服务
- 最小文件系统使用 wget 来下载
对应的原理就如上述所说的那样 ,下面开始实际操作:
# 打包操作:tar-czf./squashfs-root.tar.gz squashfs-root# Python 3python-mhttp.server8000# wget 下来wgethttp://<-ip地址->:8000/<path>/squashfs-root.tar.gz# 解压:tar-xzvfsquashfs-root.tar.gz# 删除rmsquashfs-root.tar.gz模拟运行 && uhttpd 启动
模拟运行部分就是相当简单了:使用三段式入手:
cdsquashfs-rootmount--bind/proc procmount--bind/dev devchroot./bin/sh
模拟运行后的结果,如下图所示:
等我们进入后,发现,哎呀!我们的/sbin/init启动不起来啊 !!!!
好的这个就是下面的故事了;
启动流程探索 && uhttpd 启动
Linux 的服务脚本一般存放在 :
/etc/init.d/*而,初始化的服务放在:/etc/rc.d/*
所以,思路很明确,去看看/etc/re.d/这个目录下面都有些什么!
【注】:S开头的就是 启动的时候会进行的;K 开头的就是关机的时候需要注意的;
S11sysctl——>S11timezone——>S11ubus(需要修复一下文件目录)——> netconfig(可以不启动, 内部已经实现了互通) ——>S50uhttpd
UHTTP启动:
/usr/sbin/uhttpd-f-h/www-p0.0.0.0:8080&再配一次网络(因为启动netconfig服务,之前的服务失效了)测试网络的连通性
最终,可以发现,通过虚拟机上的浏览器,可以访问到页面了(后面别的相关的问题,漏洞,慢慢再找把…)