RSS Feed
更好更安全的互联网

华硕路由器9999端口远程命令执行研究报告 V1

2015-01-14

本文PDF下载:华硕路由器9999端口远程命令执行研究报告 V1

漏洞概要

2014年10月3日,国外安全研究员Joshua J. Drake在他github(https://github.com/jduck)提交了针对华硕路由器的一个远程命令执行漏洞poc(https://github.com/jduck/asus-cmd)。该漏洞随后被编号为CVE-2014-9583。

知道创宇安全研究团队在第一时间对该命令执行漏洞进行了研究和分析。

a)     漏洞描述

华硕路由器R系列路由器使用开源路由器系统Asuswrt(https://github.com/RMerl/asuswrt-merlin),开源代码给我们随后的漏洞分析带来很多方便,不用逆向分析。在Asuswrt中存在infosvr(https://github.com/RMerl/asuswrt-merlin/tree/master/release/src/router/infosvr)进程,该进程监听在0.0.0.0 IP上,监听本机任何IP的9999 UDP端口。Infosvr自身的授权机制不完整,在infosvr处理用户提交的数据时也没有适合的过滤,而且使用了system()函数执行部分请求,最终导致远程命令执行漏洞。

b)     漏洞影响

据Joshua J. Drake在github上的分析,受影响的版本如下:

1

不过,开源路由器系统Asuswrt项目支持如下所有路由器硬件型号,所以建议如下型号路由器用户检测是否存在漏洞:

  • RT-N16
  • RT-AC56U
  • RT-N66U
  • RT-AC66U
  • RT-AC68U
  • RT-AC68P
  • RT-AC87U

 c)     漏洞分析

代码文件:

在代码162行处,infosvr绑定到了0.0.0.0 IP的9999 UDP端口上,如图:

image003

 

在代码186行处,infosvr对传入的请求交给processReq()函数处理,如图:

image005

processReq()函数的功能就是接收512字节的请求数据,并在代码227行处把数据交给processPacket()函数处理,如图:

image007

 

processPacket()函数位于文件:

https://github.com/RMerl/asuswrt-merlin/blob/34b5933112d7164b68add63fee63f007a0569309/release/src/router/infosvr/common.c

processPacket()函数在代码202行处把512字节的请求数据(pdubuf字符指针)转换成IBOX_COMM_PKT_HDR结构(phdr),攻击者如果想触发漏洞,需要按照这个数据结构来发送数据包,如图:

image009

IBOX_COMM_PKT_HDR结构在文件:

https://github.com/RMerl/asuswrt-merlin/blob/34b5933112d7164b68add63fee63f007a0569309/release/src/router/infosvr/iboxcom.h.wirelesshd

IBOX_COMM_PKT_HDR结构在代码81行处定义,如图:

image011

想要进入触发漏洞的关键代码区域,需要通过common.c文件代码207行处的if判断,如图:

image013

所以,我们要设定攻击代码的前两字节分别为常量NET_SERVICE_ID_IBOX_INFO和NET_PACKET_TYPE_CMD的值,即:\x0C\x15(十进制是12和21),如图:

image015

来到common.c文件代码222行处,infosvr作者应该是想对随后能执行system()函数代码的数据做个授权,或者验证。该处作者使用了MAC验证(代码227行处)和密码验证,不过不知为何密码验证代码被注释掉了(代码240行处),而针对MAC验证的代码也属于摆设状态,代码如图:

image017

在验证前,需要把512字节数据pdubuf转换成IBOX_COMM_PKT_HDR_EX数据结构,IBOX_COMM_PKT_HDR_EX结构包含了MAC字段和密码字段,如图:

image019

为什么说MAC验证是摆设呢?因为在common.c文件代码227行处,代码只是把MacAddress的前6字节拷贝到了字符数组mac处,返回是指向mac地址的指针,不会等于0,所以该验证毫无任何用处,如图:

image021

大胆猜测作者可能是想用memcmp()函数,结果用错了,不得而知。

继续前进,在common.c文件代码251行处进入switch()函数判断阶段,针对不同OpCode执行不同的分支代码,而当OpCode为NET_CMD_ID_MANU_CMD常量值(十进制51,十六进制33)时,才能执行system()函数代码,所以,我们要设定攻击代码的前四字节为\x0C\x15\x33\x00,如图:

image023

image025

在common.c文件NET_CMD_ID_MANU_CMD分值代码中,代码440行出代码把pdubuf减去IBOX_COMM_PKT_HDR_EX结构的数据,剩余部分转换成PKT_SYSCMD结构,作为命令执行数据,PKT_SYSCMD结构如图:

image027

最终,在common.c文件代码514行处,syscmd结构中cmd字段被赋值给cmdstr,在代码515行处,cmdstr作为命令被system()函数执行,如图:

image029

d)     漏洞重现

漏洞测试脚本:

 http://www.exploit-db.com/exploits/35688/ 

下载存在漏洞的华硕路由固件:

http://dlsvr04.asus.com/pub/ASUS/wireless/RT-AC66U/FW_RT_AC66U_30043763626.zip

binwalk解压文件:

31

image033

 

模拟运行,如图:

image035

攻击infosvr程序,如图:

image037

命令执行成功,如图:

image039

e)     漏洞修复

开源路由器系统Asuswrt已经2015年1月10号下午修复了漏洞,修复漏洞的办法是直接注释掉了触发命令执行漏洞的关键部分,如图:

image041

华硕官方也推出相应的固件升级,想要修复漏洞的用户可以去下载相关路由器型号的升级固件:

例如RT-AC66U型号路由器2015年1月12号推出的升级版本,如图:

image043

 

ZoomEye检测报告

由于此次华硕路由器命令执行漏洞难以使用无损探测方法探测,我们仅根据版本型号去推测漏洞的影响范围。把受影响的华硕路由器型号放在ZoomEye(http://www.zoomeye.org)中检索,我们得到以下数据:

10

RT-AC66U,21776个,如图:

image045

RT-N66U,37156个,如图:

222222

RT-AC87U,1314个,如图:

image049

RT-N56U,23974个,如图:

image051

路由器系统管理端口正常情况下是不会暴漏在公网上的,我们检索到的只是暴漏在公网上开放管理端口路由器设备的,相信还有更多的设备隐藏在背后。所以,建议使用者尽快升级华硕路由器系统。

相关资源链接

作者:刘 开水 | Categories:技术分享 | Tags:

一条评论

  1. Alex说道:

    请问文中提到模拟运行,是指改一下infosvr代码,编译后在本机运行吗?还是用qemu运行固件?

发表评论