浅谈路由器漏洞挖掘

摘要

去年公司买了个华硕路由器,型号为AC86U,我闲来无事尝试挖掘了下,一个月内,从路由器漏洞挖掘零基础到混了三个CVE。在此分享我一些漏洞挖掘思路。

前期准备

首先了解我们的路由器,做一些基础工作。 
登录路由器后台了解基本的一些功能,比如能不能开启ssh连接等等。访问官网看看能不能下到固件等,如果不能下载到固件,则需要考虑硬件dump或者网络截取的方法来获取固件。 
华硕的路由器是可以直接开启ssh登录的,这里打开系统管理有一个服务选项,其中有一个启用SSH的功能。

登录之后就可以做一些基础准备了。

确定挖掘目标

使用netstat -anpt命令,查看路由器有哪些开放的端口,哪些是可以通过外网访问到的,而哪些是只有本地访问到的。

tcp        0      0 0.0.0.0:5152            0.0.0.0:*               LISTEN      294/envrams
tcp        0      0 0.0.0.0:5473            0.0.0.0:*               LISTEN      1846/u2ec
tcp        0      0 0.0.0.0:18017           0.0.0.0:*               LISTEN      1043/wanduck
tcp        0      0 0.0.0.0:36098           0.0.0.0:*               LISTEN      1928/miniupnpd
tcp        0      0 0.0.0.0:3394            0.0.0.0:*               LISTEN      1846/u2ec
tcp        0      0 192.168.50.1:515        0.0.0.0:*               LISTEN      1847/lpd
tcp        0      0 192.168.50.1:1990       0.0.0.0:*               LISTEN      1155/wps_monitor
tcp        0      0 127.0.0.1:47753         0.0.0.0:*               LISTEN      1912/mcpd
tcp        0      0 192.168.50.1:16363      0.0.0.0:*               LISTEN      2111/uuplugin
tcp        0      0 192.168.50.1:9100       0.0.0.0:*               LISTEN      1847/lpd
tcp        0      0 0.0.0.0:7788            0.0.0.0:*               LISTEN      1733/cfg_server
tcp        0      0 127.0.0.1:80            0.0.0.0:*               LISTEN      1644/httpd
tcp        0      0 192.168.50.1:80         0.0.0.0:*               LISTEN      1644/httpd
tcp        0      0 127.0.0.1:38770         0.0.0.0:*               LISTEN      2111/uuplugin
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      1635/dnsmasq
tcp        0      0 192.168.50.1:53         0.0.0.0:*               LISTEN      1635/dnsmasq
tcp        0      0 192.168.50.1:22         0.0.0.0:*               LISTEN      1764/dropbear
tcp        0      0 127.0.0.1:38746         0.0.0.0:*               LISTEN      2117/uuplugin
tcp        0      0 192.168.50.1:3838       0.0.0.0:*               LISTEN      1847/lpd 

使用iptables命令查看规则。众所周知漏洞修复的手法多种多样,常见手法例如,直接修复程序上的漏洞,砍掉整个功能(可怜的公式编辑器),添加防火墙规则。有些的修复手法就是通过添加规则挡掉外部流量来做的。 
使用iptables -nvL --line-number命令来查看规则。

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination          1     118K 7060K DROP       tcp  --  lo     *       127.0.0.1            127.0.0.1            tcp dpt:38770 2        0     0 ACCEPT     tcp  --  br0    *       0.0.0.0/0            0.0.0.0/0            tcp dpt:16363 3        0     0 ACCEPT     2    --  eth0   *       0.0.0.0/0            0.0.0.0/0            4      826  188K INPUT_PING  icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8 5    1846K  433M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED 6     1770 85622 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID 7    4429K  973M PTCSRVWAN  all  --  !br0   *       0.0.0.0/0            0.0.0.0/0            8     202K   22M PTCSRVLAN  all  --  br0    *       0.0.0.0/0            0.0.0.0/0            9       34  1768 DROP       tcp  --  !lo    *       0.0.0.0/0            0.0.0.0/0            tcp dpt:5152 10    202K   22M ACCEPT     all  --  br0    *       0.0.0.0/0            0.0.0.0/0            state NEW 11   4429K  973M ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0            state NEW 12       0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:67 dpt:68 13       0     0 INPUT_ICMP  icmp --  *      *       0.0.0.0/0            0.0.0.0/0            14     378 96645 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            

可以看到有的端口的包是完全丢弃掉的,比如5152端口。 
在剩余的程序中,通过百度或者其他搜索引擎了解它是干什么的,一般来讲应用较广身经百战的项目漏洞比较少且难以发现,并且在网上都是可以查到他是干什么的,例如这里面的miniupnpd,dnsmasq等。而查不到的则很有可能是厂商自己实现的功能也就是我们的目标,其中功能越多越容易出现漏洞。

环境准备

在路由器上安装编译好的gdb,这里我是直接从github上下载编译好的,在本地使用python搭建下载服务,在路由器上使用wget下载下来,需要注意的是,路由器重启之后所有下载的文件就会消失,需要我们重新下载到路由器上,因此非必要的情况下不要重启路由器。

漏洞挖掘

这里以我挖掘危害较轻的一个漏洞为例。这里我选择的是cfg_server。 
由于程序代码量很大,因此我们需要找到最关键的部分,也就是数据处理的部分,这里通过调试对recv,listen,accept等函数下断点,通过跟踪数据流来找到程序处理数据的位置。

这里是根据输入数据的前四字节走入不同的处理函数。 
变量dword_A2F90存放对应功能码以及处理函数。

例如94 8e 05 00地址对应的是功能码1的处理函数。 
定位之后继续对该程序代码分析,发现其实一个TLV格式的报文,TLV 的意思就是Type 类型,Length 长度,Value 值。接下来就是对每个功能进行分析,来找出其中是否存在漏洞,这里需要耐心以及对功能的理解。 
这里以0x1对应的功能为例,正常交互时,会输出程序的公钥。如下图。

当我们设置长度为0xfffffff4的时候会导致服务端出现逻辑错误,进而无限循环不停向客户端发送公钥,此时如果关闭客户端的连接就会导致程序产生SIGPIPE信号进而退出。

该漏洞的漏洞点在于没有对输入的长度进行验证,也就是说不会验证TLV中的L与V的长度是否相等。另一个则是程序的信号处理不够完善,导致程序退出。至此一个简单的拒绝服务漏洞就出现了。 
而官方通过添加验证数据长度的代码进行修复漏洞。

总结

对我而言整个流程总体来说,确定目标,环境准备,漏洞挖掘。其中花的时间大部分在对程序的逆向分析上,一个程序实现的功能越多越复杂就越可能出现漏洞。最终拿了三个CVE,总体而言华硕的漏洞提交体验还是不错的。

目前评论:0 条

发表评论