修复路由器程序运行环境
修复路由器程序执行流程大致如下:
--运行程序,定位导致程序异常的函数
--分析导致异常的函数,编写一个具有相同功能的函数,在函数中伪造执行流程和数据,并将编写的函数封装成一个新的动态库
--使用LD_PRELOAD环境变量加载新的动态库来劫持目标程序中的异常函数,使目标程序执行动态库中的函数
以dir605为例子进行分析:
固件提取
sudo wget ftp://ftp2.dlink.com/PRODUCTS/DIR-605L/REVA/DIR-605L_FIRMWARE_1.13.ZIP
启动程序
sudo chroot . ./qemu-mips-static ./bin/boa
通过ida动态调试发现
执行了这个语句就导致程序崩溃 使得web服务器启动失败
然后关键点在这个apmib_init
查找apmib_init()函数在哪个库文件的方法是先查看httpd程序加载了哪些库文件,然后使用nm或者objdump -x命令查看so文件的符号表,即可找到定义apmib_init()函数的库文件;如果so文件没有符号表,可以使用grep搜索字符串apmib_init,也可以找到对应的so文件;
通过对这个函数进行分析apmib_init函数内的代码处理流程对模糊测试是没有影响的,因此可以伪造apmib_init直接返回值1 也可以直接从boa进行patch但我们今天侧重前一种。当然这里肯定不能只是说书上说没影响就没影响,我们肯定要找到源码自己审一下
源码地址:https://github.com/Saturn49/wecb/blob/master/rtl819x/users/boa/apmib/apmib.c
这里借用一下ba1100n师傅对这个源码的解读:
- 检查有没有wlanMacChain,wifi串联
- RTK_MESH(一种类似于蓝牙的网络)的配置
- HOME_GATEWAY,家庭网关的那些东西,初始化了端口前置的表,看起来就是Vpn那些东西
- QoS rules table,初始化了用于改善服务质量规则的表
- static route table,初始化了静态路由表
- TLS加密传输相关
- VLAN相关配置
- pMib几个参数的初始化
我们编写一个新的
#include<stdio.h>
#include<stdlib.h>
int apmib_init(void)
{
return 1;
}
sudo mips-linux-gnu-gcc -Wall -fPIC -shared apmib.c -o apmib-ld.so
因为这里的函数是用交叉编译下的环境编译i的 因此我们要使用LD_PRELOAD环境变量加载apmib-ld.so 劫持apmib.so中的apmib_init()函数
sudo chroot ./ ./qemu-mips-static -E LD_PRELOAD="/apmib-ld.so" ./bin/boa
这个时候就修复了
但是程序还是崩溃了 我们去调试一下看看什么原因
发现进入apmib_get出现了问题,因此我们还需要劫持apmib_get这个函数
那么真正的难题来了,怎么改写apmib_get呢?这段代码看起来有点吓人
这里有一个简单的改写逻辑,这里全都改写为1 是不会影响后续程序正常执行的
#include<stdio.h>
#include<stdlib.h>
int apmib_init(void)
{
return 1;
}
int apmib_get()
{
return 1;
}
int fork(void)
{
return 0;
}
书上的改写部分 我看的不是很明白 审了几天的代码 没审清楚 后续找到了源码研究后再补上
发现虽然很多报错 但是至少web服务启动了 但是只要一在本地登录就会出现报错 在web服务已经启动了的情况下 就尽量不要往逆向的方面去思考了,可以从web的角度去看一下
发现每次登录127.0.0.1的时候都会自动跳转到http://127.0.0.1/Basic/Wizard_Easy_LangSelect.asp 这就是问题所在,我们要想办法把这个自动跳转的地址改掉
find ./ | grep "asp"
通过这个定位文件夹为web界面:
grep -r "Basic/Wizard_Easy_LangSelect.asp" ./web/
然后通过这个指令 去查询 在整个代码文件夹中搜索包含重定向或跳转相关的关键字
改掉之后再次执行:
就成功启动了 书上那部分源码我实在是没审明白,希望有明白怎么来的师傅可以教一下我。
以上就是对路由器固件修复的全过程
这里贴一下书上改写的apmib.c
void apmib_get(int code,int *value)
{
switch(code)
{
case 0x250:
*value=0xf1;
break;
case 170:
*value=0xf1;
break;
case 0x2c1:
*value=0xf1;
break;
}
}
参考文献:
参考书:《揭秘家用路由0day漏洞挖掘技术》