IOT漏洞挖掘 | 路由器固件仿真配置​(三)

安全入门
2023-02-22 18:24
107159

1.相关琐碎

上两节中使用的系统仿真方法相对来说比较简单,这一次选择使用一种更通用的固件服务仿真方法。

2.工具准备

IDA

下载地址链接: https://pan.baidu.com/s/12NG9mOtbV6WDk_Xz8T-HLA

提取码: 8cp4

IDAPro(简称IDA)是DataRescue公司( www.datarescue.com)出品的一款交互式反汇编工具,它功能强大、操作复杂。IDA最主要的特性是交互和多处理器。操作者可以通过对IDA的交互来指导IDA更好地反汇编,IDA并不自动解决程序中的问题,但它会按用户的指令找到可疑之处,用户的工作是通知IDA怎样去做。比如人工指定编译器类型,对变量名、结构定义、数组等定义等。这样的交互能力在反汇编大型软件时显得尤为重要。多处理器特点是指IDA支持常见处理器平台上的软件产品。IDA支持的文件类型非常丰富,除了常见的PE格式,还支持Windows,DOS,UNIX,Mac,Java,.NET等平台的文件格式。

Tenda固件

Tenda AC15下载地址:https://github.com/VulnTotal-Team/IoT-vulhub/tree/master/Tenda/CVE-2018-5767/firmware

binwalk

安装教程:https://blog.csdn.net/qq_50854790/article/details/123391951

binwalk是用于搜索给定二进制镜像文件以获取嵌入的文件和代码的工具。具体来说,binwalk是一个固件的分析工具,旨在协助研究人员对固件非分析,提取及逆向工程用处。简单易用,完全自动化脚本,并通过自定义签名,提取规则和插件模块,还重要一点的是可以轻松地扩展。

网上很多安装教程,安装时注意要成功安装.deps.sh 脚本中的binwalk依赖,否则提取出的固件会不完整。

qemu-arm-static

安装命令:apt install qemu-user-static

3.开始实验

使用binwalk提取固件中的文件系统

命令:
binwalk -Me US_AC15V1.0BR_V15.03.1.16_multi_TD01.bin

image.png

在提取出的文件夹中,即可找到固件的文件系统

image.png

尝试开启固件网络服务

首先查询固件的系统架构,命令如下:

file ./bin/busybox

image.png

发现是32位,小端,arm架构,使用qemu-arm-static进行模拟Tenda路由器的网络服务一般是名称为/bin/httpd,开启命令如下:

sudo chroot ./ ./qemu-arm-static  ./bin/httpd

image.png

发现服务开启失败,需要对httpd二进制程序进行逆向patch

动态调试并patch httpd服务

将httpd拉入ida32中进行分析,定位到sub_2CEA8函数即为main函数

image.png

image.png

在main函数中加入断点,在ubuntu系统中使用qemu-arm-static开启httpd服务,并-g 指定调试接口,命令如下:

sudo chroot ./ ./qemu-arm-static -g 23946 ./bin/httpd

使用ida远程链接,选中ida菜单栏中的Debuger选项,Select Debuger,选中remote GDB debugger

image.png

然后点击绿色运行按钮,填入ubuntu虚拟机的正确ip地址后,即可开启远程调试,按F9键程序开始运行,并断在刚才所打的断点处,F8单步步过,F7单步步入

image.png

分析后发现httpd服务开启有两个检测条件:

1.check_network()<=0时则会陷入sleep循环

2.ConnectCFM() 不符合条件则会提示"connect cfm failed"

image.png

使用ida的key_patch对这两处判断进行修改,可以进行绕过

image.png

修改成如下结果即可

image.png

修改完成之后ip依旧有问题

image.png

于是根据关键字符串“httpd listen ip",寻找问题源头,定位到sub_1A36C函数中

image.png

使用gdb 跟踪定位一下,开启调试端口

sudo chroot ./ ./qemu-arm-static -g 23946 ./bin/httpd_patch

然后gdb连接,按c直接运行到sub_1A36C函数

gdb-multiarch      
set architecture arm     
b *0x1A36C     
target remote :23946

image.png

输入bt指令即可查看sub_1A36C函数调用链

image.png

定位到283e0附近的SUB_28338函数,分析得知sub_28030调用了此函数

image.png

重复上面的步骤,可以得到具体的调用链为:sub_2CEA8(main函数)-> sub_2D3F0(initWebs函数) -> sub_28030 -> sub_28338 -> sub_1A36C

接下来分析printf的ip参数v8进行跟踪:v8关联到s.sa_data[2],s.sa_data[2]关联到a1,a2

image.png

a1关联到g_lan_ip函数,最终回溯到主函数中

image.png

image.png

可以看到ip的值与s和v19有关

此处我们进行详细分析,根据函数名猜测getIfIp的作用的是获取ip地址,进入函数查看具体实现。

getIfIp为外部导入函数,对函数名进行搜索,查找存在的动态链接库

#查看可执行程序需要的动态链接库
  readelf -d ./bin/httpd | grep NEEDED
#列出所有的函数名,与要寻找的函数对比
  nm -D ./lib/libcommon.so

发现getlflp函数的本体存在于libcommon.so中

image.png

image.png

大致分析伪代码,可以看到一个系统调用ioctl(fd, 0x8915u, dest),查看这个系统调用所实现的功能

一般来讲ioctl在用户程序中的调用是:

ioctl(int fd,int command, (char*)argstruct)

ioctl调用与网络编程有关,文件描述符fd实际上是由socket()系统调用返回的。参数command的取值由/usr/include/linux/sockios.h 所规定。第三个参数是ifreq结构,在/usr/include/linux/if.h中定义。

参考:https://www.cnblogs.com/zxc2man/p/9511856.html

到头文件中查看,可以发现,第二个参数实现的功能正是获取IP地址

image.png

第三个参数的含义需要进一步分析,先看函数整体的流程,应该就是成功获取ip地址返回v2,v2的值为0的话,在main函数中的判断就不会进入if循环,而ip地址的值则由v19决定。进一步跟进v19,就是在getIfIp函数中的a2,由系统调用获取ip地址后赋给a2即main函数中的v19。那么想让函数按我们分析的执行,还需要分析第三个参数的含义。第三个参数与main函数的v7有关,进一步分析,与getLanIfName函数有关,依照上面的步骤发现getLanIfName函数依然存在于libcommon.so中,查看函数的本体。

image.png

image.png

getLanlfName函数进一步关联到get_eth_name函数,且参数写死为0。依照上面的步骤发现get_eth_name函数依然存在于libChipApi.son中,查看函数的本体,函数返回v1,即网卡的名称,上述系统调用的第三个参数也就清楚了。

image.png

至此,我们可以梳理一下整个流程。在main函数中,首先调用getLanIfName函数进而调用get_eth_name函数获取网卡名称。然后将网卡名称作为参数输入到getIfIp中,函数功能为寻找网卡名称为br0的ip地址并传递给V17。

所以,想让二进制程序监听正确的ip地址需要新建一个名为br0的网卡。

sudo brctl addbr br0
sudo ifconfig br0 192.168.20.12/24

重新启动,找到了名为br0的网卡并获取了ip地址:

image.png

4.开启服务

将webroot_ro中的文件复制到web_root目录下,最后就可以在本机中访问模拟出的路由器网站

image.png

image.png

参与评论

0 / 200

全部评论 3

L0st1amb的头像
666
2023-03-30 09:10
zebra的头像
学习大佬思路
2023-03-19 12:15
wz0187的头像
666
2023-03-06 14:13
投稿
签到
联系我们
关于我们