逆向PT632 G2光猫固件
国庆回老家,看到爷爷一个人看IPTV的时候,遥控按错了就看不了电视了,爷爷年纪大了,耳朵也不好使了,给他买的智能手机也不会打电话,只懂得发起微信视频,我打回去还不懂如何接,有时候真是有话都说不清楚。趁着放假几天,我就逆向了PT632 G2光猫的固件,实现远程控制家里的所有联网设备,以后再跟我说电视看不了,我直接远程操作一下就可以了。
测试发现佛山电信使用的公网IP,不用使用云服务器进行远程端口映射,只需要使用动态域名解析就可以访问路由器,PT632这个光猫自带了ez-ipupdate这个软件,但是并不支持3322的动态域名解析服务,而且这个功能也并不能通过WEB管理页面开启。使用ssh管理路由器,可以对要控制的设备进行端口映射,随时随地都能管理网关内的设备。
博主vasvir提供了破解ZTE-H108NS路由器的思路,PT632_G2使用的是tclinux,我是通过关键词tclinux找到这个博客的,博主写了三篇博文详细叙述了他的破解过程。每一篇我都反复阅读和调试,才确认他的思路同样可以应用到PT632这个系列的光猫上。但存在一些不同的地方,毕竟不是一样的路由器,比如提取固件的方法,他是直接在官网下载的,我是用netcat dump出来的;固件的头部有不一样的地方,有三个信息点必须填上,不然就算通过了CRC校验算法,也会刷机失败的;还有就是压缩和解包工具不同,使用的文件系统版本不同。
bootloader分区就不要轻易去碰,变砖了就要把Flash吹下来上编程器。动手之前需要了解光猫的基本信息:
- CPU是Ralink MT751020 SOC,64M内存,64M闪存,分区情况如下表所示
- Bootloader、Web界面管理的中国电信超级用户名:telecomadmin,密码:nE7jA%5m
- TTL Text Console、Telnet的用户名:admin,密码:1234或TeleCom_1234
启用Telnet服务的方法:登录Web管理后台,在地址栏输入http://192.168.1.1/cgi-bin/telnet.asp,勾选启用。
dev: | size | erasesize | name | 说明 |
mtd0: | 40000 | 20000 | bootloader | 最好别碰,小心变砖 |
mtd1: | 40000 | 20000 | romfile | 保存配置文件 |
mtd2: | 001614eb | 20000 | kernel | 内核1 |
mtd3: | 006d0000 | 20000 | rootfs | 根文件系统1 |
mtd4: | 1000000 | 20000 | tclinux | 保存固件1 |
mtd5: | 001614eb | 20000 | kernel_slave | 内核2 |
mtd6: | 006d0000 | 20000 | rootfs_slave | 根文件系统2 |
mtd7: | 1000000 | 20000 | tclinux_slave | 保存固件2 |
mtd8: | 400000 | 20000 | jffs2 | |
mtd9: | 001c0000 | 20000 | reservearea |
1 提取固件
这型号的光猫是不带USB口的,提取固件需要用netcat实时传到本地主机。darkerego提供了多个常用的mips架构的程序。 假如本机地址为192.168.1.2
git clone https://github.com/darkerego/mips-binaries |
# 路由器地址192.168.1.1 |
保险起见,可以把所有分区都备份下来,万一把光猫刷挂了,可以随时恢复过来。 提取到tclinux.bin之后,就相当于拿到官方的固件,这个bin文件是分区的镜像,并非官方固件,用010 Editor可以看到固件的实际大小为0x855A86。
2 解包固件
博主vasvir逆向分析出了tclinux使用的CRC算法,写了个叫tcrevenge程序放到了github上,我也用IDA Pro分析了一下反汇编代码,算法是一致的,我们可以通过该程序计算提取到的固件的校验码,比对固件中的校验码,检查一下CRC算法是否正确,结果发现原程序缺少了三个信息点,导致生成的校验码不一致。
用010 Editor查看提取到的根文件系统1614EB.squashfs,发现它是使用默认参数压缩生成的。但是我原封不动,仅仅使用默认参数进行压缩,打包出来的squashfs-root.sq比原来的大,原本的根文件系统差不多把分区都占满了,如果重新打包文件大了,就塞不下其他任何软件了,这让我纠结了好久。尝试使用squashfs各个版本的压缩工具去打包根文件系统,都没有发现能打包成同样大小的。我选择了squashfs 3.0文件系统工具去打包,打包出来的文件就比原来的小一点,我觉得旧的压缩格式可能也能兼容,但很不幸刷进去就挂掉了,最终还是摆脱不了使用调试线救砖。
有了调试线的帮助,在添加软件定制固件前,可以大胆地先进行一些验证性的试验:
- 用提取到的根文件系统1614EB.squashfs、kernel和tcrevenge生成header重新打包固件,比对二进制数据是否一致,验证tcrevenge程序的正确性。
使用不同的压缩参数重新打包根文件系统,用修改好的tcrevenge程序生成新的固件,试刷固件,验证定制固件的可行性。
dd if=tclinux.bin of=tclinux.bin.orig bs=1 count=$((0x855A86))
sudo apt-get install binwalk squashfs-tools
#需要用root权限执行,解包的根文件系统中包含设备文件
sudo binwalk -e tclinux.bin.orig
#提取kernel
cd _tclinux.bin.org.extracted
#生成的压缩文件跟原来的不一致,尝试过多个版本的压缩工具,没有找到压缩结果一致的,这一步纠结了很久
mksquashfs squashfs-root squashfs-root.sq -comp lzma
#重新打包固件
dd if=../tclinux.bin.orig of=kernel skip=256 count=`binwalk ../tclinux.bin.orig | awk '/Squash/ {print $1 - 256;}'` bs=1
tcrevenge -k kernel -s 1614EB.squashfs -o header
#用010 Editor对比生成的固件和提取的固件,发现了校验头文件中少3个信息点,修改tcrevenge程序
cat header kernel squashfs-root.sq padding > tclinux.bin.new
#用压缩比更高的参数压缩根文件系统,生成新的固件,成功刷入光猫中
mksquashfs squashfs-root squashfs-root.sq -comp lzma -b 524288
tcrevenge -k kernel -s squashfs-root.sq -o header
cat header kernel squashfs-root.sq padding > tclinux.bin.new
3 解压根文件系统
特别要注意,解压根文件系统的时候,会创建设备文件,需要root权限,在上一步中忘记使用root权限运行binwalk -e命令,可以把squashfs-root文件夹删掉,用unsquashfs重新解压根文件系统。
sudo rm -rf squashfs-root sudo unsquashfs 1614EB.squashfs
4 添加软件
根文件系统的空间十分有限,我只为路由器添加用于动态域名解析的ez-ipupdate和用于sshd服务的dropbear,光猫上自带了ez-ipupdate程序,却无法通过WEB管理界面启用ddns服务,而且不支持3322动态域名解析服务,需要自己编译3322提供的ez-ipupdate源代码。我也懒得修改cgi程序以支持Web管理,直接把配置信息放在了固件当中。根文件系统实在没有空间放下sshd,只能使用功能稍弱一点的dropbear,有了这两个软件就已经能满足我的需求了。
4.1 ez-ipupdate
设置交叉编译工具链很麻烦,uClibc.org提供了包含mips,arm,amd64等多种Qemu的虚拟机镜像,系统里包含完整的编译工具链,免去设置环境变量的麻烦,缺点就是编译的速度稍慢。
wget https://uclibc.org/downloads/binaries/0.9.30/system-image-mips.tar.bz2 |
4.2 dropbear
cd /home/wing/Workspace/pt632_g2/_tclinux.bin.orig.extracted/squashfs-root/usr |
5 打包固件
# 压缩根文件系统 |
6 刷机