修复路由器程序运行环境+远程调试 前言 当搭建好了QEMU环境后,就会想到运行路由器中的程序(如路由器中的web服务器),但可能会遇到路由器相关硬件模块缺失导致应用程序启动失败的情况
本文将以D-Link DIR-605L(FW_113)路由器中的web应用程序boa为例子。
修复路由器程序的执行流程大致如下。
运行程序,定位导致程序异常的函数
分析导致异常的函数,编写一个具有相同功能的函数,在函数中伪造执行流程和数据,并将编写的函数封装成一个新的动态库
使用LD_PRELOAD
环境变量加载新的动态库来劫持目标程序中的异常函数,使目标程序执行动态库中的函数
固件分析 首先下载固件
使用binwalk提取固件中的文件系统,然后提取/bin/boa文件到桌面
1 2 3 4 iot@research:~/Desktop/DIR/DIR605/DIR-605L_FIRMWARE_1.13$ binwalk -Me dir605L_FW_113.bin iot@research:~/Desktop/DIR/DIR605/DIR-605L_FIRMWARE_1.13$ ls dir605L_FW_113.bin _dir605L_FW_113.bin.extracted iot@research:~/Desktop/DIR/DIR605/DIR-605L_FIRMWARE_1.13$ cp _dir605L_FW_113.bin.extracted/squashfs-root-0/bin/boa ~/Desktop/
编写劫持函数动态库 获取错误信息,定位异常函数。初次运行boa的错误提升信息如下
1 2 3 4 iot@research:~/Desktop/DIR/DIR605/DIR-605L_FIRMWARE_1.13/fmk/rootfs$ qemu-mips -L . ./bin/boa ./bin/boa: cache '/etc/ld.so.cache' is corrupt Initialize AP MIB failed! Could not chdir to "/etc/boa" : aborting
使用IDA pro对boa进行分析,搜索错误提升字符串"Initialize AP MIB failed!"
,在执行puts函数前下断点,发现在调用apmib_init
函数的时候,如果返回值为0,就会报错
1 2 if ( !apmib_init() ) return puts ("Initialize AP MIB failed!" );
分析发现函数apmib_init
来自于动态链接库apmib.so。
1 2 3 4 5 6 iot@research:~/Desktop/DIR/DIR605/DIR-605L_FIRMWARE_1.13/fmk/rootfs$ grep -r apmib_init Binary file apmib-ld.so matches Binary file bin/boa matches Binary file bin/flash matches Binary file bin/setfirewall matches Binary file lib/apmib.so matches
然后ida打开apmib.so,分析apmib_init函数,通过静态反编译和动态调试对函数代码进行分析,apmib_init函数内的代码处理流程对模糊测试没有影响,因此,可以伪造apmib_init函数直接返回值1,让程序正常执行下去
根据对异常函数apmib_init的分析,编写新的apmib_init函数,代码如下:
1 2 3 4 5 6 7 8 #define MIB_IP_ADDR 170 #define MIB_HW_VER 0x250 #define MIB_CAPTCHA 0x2c1 #include <stdio.h> #include <stdlib.h> int apmib_init (void ) { return 1 ; }
使用如下命令编译生成动态库apmib-ld.so
1 mips-linux-gcc -Wall -fPIC -shared apmib.c -o apmib-ld.so
运行测试 将编译好的apmib-ld.so动态链接库复制到路由器的根目录文件系统下
使用LD_PRELOAD环境变量加载apmib-ld.so,劫持apmib.so 中的apmib_init函数,命令如下
1 2 3 4 5 iot@research:~/Desktop/DIR/DIR605/DIR-605L_FIRMWARE_1.13/fmk/rootfs$ sudo chroot . ./qemu-mips-static -E LD_PRELOAD="/apmib-ld.so" ./bin/boa Create chklist file error! Create chklist file error! qemu: uncaught target signal 11 (Segmentation fault) - core dumped Segmentation fault
报错Create chklist file error!
可以看到尽管我们修复了"Initialize AP MIB failed!"
,但程序还是崩溃。在apmib_init函数那里下断点,用IDA远程调试或者GDB调试,发现在程序执行到apmib_get()
函数的时候程序崩溃
因此我们还需要劫持apmib_get
函数,查看apmib.so中的apmib_get 函数的汇编代码,通过分析代码,将要劫持的函数整理如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define MIB_IP_ADDR 170 #define MIB_HW_VER 0x250 #define MIB_CAPTCHA 0x2c1 void apmib_get (int code,int *value) { switch (code){ case MIB_HW_VER: *value = 0xf1 ; break ; case MIB_IP_ADDR: *value = 0x7f000001 ; break ; case MIB_CAPTCHA: *value =1 ; break ; } return ; }
为了方便调试,我们吧boa中的fork函数一起劫持掉,形成最终的劫持代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #define MIB_IP_ADDR 170 #define MIB_HW_VER 0x250 #define MIB_CAPTCHA 0x2c1 #include <stdio.h> #include <stdlib.h> int apmib_init (void ) { return 1 ; } int fork (void ) { return 0 ; } void apmib_get (int code,int *value) { switch (code){ case MIB_HW_VER: *value = 0xf1 ; break ; case MIB_IP_ADDR: *value = 0x7f000001 ; break ; case MIB_CAPTCHA: *value =1 ; break ; } return ; }
使用命令编译最终的apmib.c生成apmib-ld.so
1 mips-linux-gcc -Wall -fPIC -shared apmib.c -o apmib-ld.so
将生成的apmib-ld.so复制到根目录下,然后使用下面命令运行
1 sudo chroot . ./qemu-mips-static -E LD_PRELOAD="/apmib-ld.so" ./bin/boa
然后可以看到boa已经开始运行了,并且打开了一个80端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Create chklist file error! Create chklist file error! hard ver is Create f/w version file error! Create chklist file error! boa: server version Boa/0.94.14rc21 boa: server built May 25 2012 at 13:03:21. boa: starting server pid=44549, port 80 Unsupported ioctl: cmd=0x89f0 device ioctl:: Function not implemented Unsupported ioctl: cmd=0x89f0 device ioctl:: Function not implemented smart 404 ---------------------------------- Unsupported ioctl: cmd=0x89f0 device ioctl:: Function not implemented Unsupported ioctl: cmd=0x89f0 device ioctl:: Function not implemented Unsupported ioctl: cmd=0x89f0 device ioctl:: Function not implemented Unsupported ioctl: cmd=0x89f0
1 2 3 4 5 6 7 8 9 10 11 12 iot@research:~/Desktop/DIR/DIR605/DIR-605L_FIRMWARE_1.13/fmk/rootfs$ netstat -ano | grep 80 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN off (0.00/0/0) unix 2 [ ACC ] STREAM LISTENING 55827 /var/run/docker/libnetwork/680160b12e88.sock unix 2 [ ACC ] STREAM LISTENING 56099 /run/containerd/s/9e47177e2200ecf7b6b185485055824fbcfc68077754130259948bfa27002005 unix 3 [ ] STREAM CONNECTED 75809 unix 3 [ ] STREAM CONNECTED 74801 /run/user/1000/bus unix 3 [ ] STREAM CONNECTED 49380 unix 3 [ ] STREAM CONNECTED 112808 unix 3 [ ] STREAM CONNECTED 76480 unix 3 [ ] STREAM CONNECTED 75380 unix 3 [ ] STREAM CONNECTED 45807 unix 3 [ ] STREAM CONNECTED 75780
IDA+qemu远程调试 在虚拟机运行下面代码即可打开一个可以供ida链接的远程端口
1 sudo chroot . ./qemu-mips-static -E LD_PRELOAD="/apmib1-ld.so" -g 12345 ./bin/boa
然后IDA在对应的地址下断点
然后调试器选择
在Debug->process option选择对应虚拟机的IP和端口还有程序
然后F9运行,F4运行到断点,就能成功下断点了