在虚拟机上用qemu运行腾达路由器的网站固件会遇到无法识别网络的问题,这篇主要是破解这个功能,使腾达路由器成功在虚拟机上运行,方便漏洞复现
本次用到的腾达路由器版本:
https://www.tenda.com.cn/download/detail-3683.html
下载完后,是一个压缩包,解压进入文件夹
解压后有两个文件,.bin文件就是路由器主要的固件,我们可以使用binwalk工具提取固件里的文件
binwalk -eM 固件名称.bin
提取后会在当前目录生成一个文件夹
进入文件夹,在squashfs-root目录下是路由器主要运行的一些东西
需要分析的固件在bin目录下,bin/httpd这个程序就是路由器主要运行的固件
直接用qemu运行程序的话会卡住
什么是MISP
MIPS汇编语言是用于编写MIPS(Microprocessor without Interlocked Pipeline Stages)架构微处理器指令的低级语言,常见于路由器,MIPS架构是一种典型的精简指令集计算机(RISC)体系结构,最初由斯坦福大学的John Hennessy在1980年代初期设计,目的是为了实现高性能的处理器设计,通过使用简单的指令集来加速指令的执行速度。MIPS架构和汇编语言被广泛用于各种设备和应用中,包括嵌入式系统、路由器、微控制器以及视频游戏控制器等
MISP常见的一些寄存器
zero 常数零
$at 汇编器保留
$v0,$v1 子程序返回值
$a0-$a3 子程序参数
$t0-$t7 临时寄存器(调用者保存)
$s0-$s7 保存寄存器(被调用者保存)
$t8,$t9 临时寄存器(调用者保存)
$k0,$k1 操作系统保留
$gp 全局指针
$sp 栈指针
$fp 帧指针
$ra 返回地址
MISP常见指令
加法
addu rd,rs,rt rd = rs + rt(溢出时不产生异常)
add rd,rs,rt rd = rs + rt(溢出时产生异常)
减法
subu rd,rs,rt d = rs-rt(溢出时不产生异常)
sub rd,rs,t d = rs-rt(溢出时产生异常)
乘法
mult rd,rt hilo = rd * rt(有符号数)
multu rd,rt hilo = rd * rt(无符号数)
除法
div rd,rt lo = rd / rt; hi = rd % rt(有符号数)
divu rd,rt lo = rd / rt; hi = rd % rt(无符号数)
数据传输指令
lw rt,immediate(rs) rt = memory[rs + immediate]
sw rt,immediate(rs) memory[rs + immediate] = rt
lh rt,immediate(rs) rt = memory[rs + immediate]
lhu rt,immediate(rs) rt = memory[rs + immediate](零扩展)
sh rt,immediate(rs) memory[rs + immediate] = rt
lb rt,immediate(rs) rt = memory[rs + immediate]
lbu rt,immediate(rs) rt = memory[rs + immediate](零扩展)
sb rt,immediate(rs) memory[rs + immediate] = rt
lui rt,immediate rt = immediate * 2^16
无条件跳转指令
j address goto address * 4
jal address $ra = PC + 4; goto address * 4
jr register goto register
回到正题
腾达路由器检测环境功能破解
用ida打开这个程序,shift+f12查看这个程序的字符串
ctrl+f 定位welcone to字符串位置
双击,进入rodata段,交叉定位跳转到调用这个字符串的地址
程序在这里进入了死循环,代码的最后部分包含了一个条件跳转指令bnez(如果不等于零则跳转),这个跳转指令依赖于GetValue函数的返回值。如果GetValue返回非零值,程序将跳转到loc_43B828,在loc_43B828最后,又会跳回loc_43872c处,和while函数类似
用ghidra打开程序,定位到这个地方查看伪代码
可以看到,这里while函数会一直循环,我们在虚拟机上运行的,和路由器网络环境不一样,所以永恒为true
什么是NOP指令
NOP指令,全称"No Operation"指令,是一种在多种编程语言和汇编语言中存在的特殊指令。如其名所示,NOP指令的执行不会对程序的状态或机器的执行环境产生任何影响,也就是说,它不执行任何操作。在CPU执行NOP指令时,除了指令计数器(PC)会前进到下一条指令外,其他的寄存器值、内存状态和处理器的状态都不会改变
也就是说,我们可以用nop指令把while函数给覆盖掉,使程序不执行while函数
回到ida pro,我们可以把这两个跳转的地方用nop指令给覆盖掉
把鼠标放到第一个红框的地址处,点击一下,然后在ida pro上面的任务栏里选择
Edit->Patch program->change byte
将前4位都改成0,点击ok,就能换成nop指令了
继续更改第二个跳转指令,点击跳转地址的地方,然后在ida pro上面的任务栏里选择
Edit->Patch program->change byte
继续将前四个值改成0
点击ok,完成程序修改
现在导出程序,还是在ida pro上面的任务栏里选择
Edit->Patch program->Apply patches to input file
点击ok,现在程序已经被我们修改了,退出ida pro,将修改后的文件覆盖虚拟机里的源文件,然后给程序赋权
chmod 777 httpd
最后添加新的网卡,运行程序
brctl addbr br0
brctl addif br0 eth0
ifconfig br0 up
dhclient br0
qemu-mipsel-static -L . ./bin/httpd
成功在虚拟机里访问路由器