openvpn: fix multiple CVEs

CVE-2024-24974:
Previously, the VPN tool’s Windows implementation allowed remote access to
its service pipe, posing a security risk. Using compromised credentials, a
threat actor could communicate with OpenVPN to orchestrate attacks.

CVE-2024-27903:
OpenVPN has mitigated the risk by restricting plugin load. Plugins can
now only be loaded from the software’s install directory, the Windows
system directory, and the plugin_dir directory under the software’s installation.

CVE-2024-27459:
This vulnerability affects the interactive service component, potentially leading
to local privilege escalation when triggered by an oversized message.To mitigate
this risk, the VPN solution now terminates connections upon detecting excessively
large messages, preventing stack overflow exploits.

References:
https://openvpn.net/security-advisory/ovpnx-vulnerability-cve-2024-27903-cve-2024-27459-cve-2024-24974/
https://socradar.io/openvpn-fixed-multiple-vulnerabilities-on-windows/
https://community.openvpn.net/openvpn/wiki/CVE-2024-27903
https://community.openvpn.net/openvpn/wiki/CVE-2024-27459
https://community.openvpn.net/openvpn/wiki/CVE-2024-24974

Signed-off-by: Meenali Gupta <meenali.gupta@windriver.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
This commit is contained in:
Meenali Gupta 2024-06-21 06:35:37 +00:00 committed by Armin Kuster
parent 38a07ce40e
commit cfcc9f9945
4 changed files with 272 additions and 1 deletions

View File

@ -0,0 +1,49 @@
From 2c1de0f0803360c0a6408f754066bd3a6fb28237 Mon Sep 17 00:00:00 2001
From: Lev Stipakov <lstipakov@gmail.com>
Date: Tue, 19 Mar 2024 17:16:07 +0200
Subject: [PATCH] interactive.c: disable remote access to the service pipe
Remote access to the service pipe is not needed and might
be a potential attack vector.
For example, if an attacker manages to get credentials for
a user which is the member of "OpenVPN Administrators" group
on a victim machine, an attacker might be able to communicate
with the privileged interactive service on a victim machine
and start openvpn processes remotely.
CVE: 2024-24974
Microsoft case number: 85925
Reported-by: Vladimir Tokarev <vtokarev@microsoft.com>
Change-Id: I8739c5f127e9ca0683fcdbd099dba9896ae46277
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Heiko Hund <heiko@openvpn.net>
Message-Id: <20240319151723.936-2-lev@openvpn.net>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28419.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
CVE:CVE-2024-24974
Upstream-Status: Backport [https://github.com/OpenVPN/openvpn/commit/2c1de0f0803360c0a6408f754066bd3a6fb28237]
Signed-off-by: Meenali Gupta <meenali.gupta@windriver.com>
---
src/openvpnserv/interactive.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c
index 3b120ae..5e3ff12 100644
--- a/src/openvpnserv/interactive.c
+++ b/src/openvpnserv/interactive.c
@@ -1994,7 +1994,7 @@ CreateClientPipeInstance(VOID)
openvpn_sntprintf(pipe_name, _countof(pipe_name), TEXT("\\\\.\\pipe\\" PACKAGE "%s\\service"), service_instance);
pipe = CreateNamedPipe(pipe_name, flags,
- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS,
PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, NULL);
if (pipe == INVALID_HANDLE_VALUE)
{
--
2.40.0

View File

@ -0,0 +1,99 @@
From 989b22cb6e007fd1addcfaf7d12f4fec9fbc9639 Mon Sep 17 00:00:00 2001
From: Lev Stipakov <lstipakov@gmail.com>
Date: Tue, 19 Mar 2024 17:27:11 +0200
Subject: [PATCH] interactive.c: Fix potential stack overflow issue
When reading message from the pipe, we first peek the pipe to get the size
of the message waiting to be read and then read the message. A compromised
OpenVPN process could send an excessively large message, which would result
in a stack-allocated message buffer overflow.
To address this, we terminate the misbehaving process if the peeked message
size exceeds the maximum allowable size.
CVE: 2024-27459
Microsoft case number: 85932
Reported-by: Vladimir Tokarev <vtokarev@microsoft.com>
Change-Id: Ib5743cba0741ea11f9ee62c4978b2c6789b81ada
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Heiko Hund <heiko@openvpn.net>
Message-Id: <20240319152803.1801-2-lev@openvpn.net>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28420.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
CVE:CVE-2024-27459
Upstream-Status: Backport [https://github.com/OpenVPN/openvpn/commit/989b22cb6e007fd1addcfaf7d12f4fec9fbc9639]
Signed-off-by: Meenali Gupta <meenali.gupta@windriver.com>
---
src/openvpnserv/interactive.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c
index 5e3ff12..f613b99 100644
--- a/src/openvpnserv/interactive.c
+++ b/src/openvpnserv/interactive.c
@@ -111,6 +111,18 @@ typedef struct {
HANDLE device;
} ring_buffer_handles_t;
+typedef union {
+ message_header_t header;
+ address_message_t address;
+ route_message_t route;
+ flush_neighbors_message_t flush_neighbors;
+ block_dns_message_t block_dns;
+ dns_cfg_message_t dns;
+ enable_dhcp_message_t dhcp;
+ register_ring_buffers_message_t rrb;
+ set_mtu_message_t mtu;
+ wins_cfg_message_t wins;
+} pipe_message_t;
static DWORD
AddListItem(list_item_t **pfirst, LPVOID data)
@@ -1444,18 +1456,7 @@ static VOID
HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_handles,
DWORD bytes, DWORD count, LPHANDLE events, undo_lists_t *lists)
{
- DWORD read;
- union {
- message_header_t header;
- address_message_t address;
- route_message_t route;
- flush_neighbors_message_t flush_neighbors;
- block_dns_message_t block_dns;
- dns_cfg_message_t dns;
- enable_dhcp_message_t dhcp;
- register_ring_buffers_message_t rrb;
- set_mtu_message_t mtu;
- } msg;
+ pipe_message_t msg;
ack_message_t ack = {
.header = {
.type = msg_acknowledgement,
@@ -1465,7 +1466,7 @@ HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_
.error_number = ERROR_MESSAGE_DATA
};
- read = ReadPipeAsync(pipe, &msg, bytes, count, events);
+ DWORD read = ReadPipeAsync(pipe, &msg, bytes, count, events);
if (read != bytes || read < sizeof(msg.header) || read != msg.header.size)
{
goto out;
@@ -1884,6 +1885,13 @@ RunOpenvpn(LPVOID p)
break;
}
+ if (bytes > sizeof(pipe_message_t))
+ {
+ /* process at the other side of the pipe is misbehaving, shut it down */
+ MsgToEventLog(MSG_FLAGS_ERROR, TEXT("OpenVPN process sent too large payload length to the pipe (%lu bytes), it will be terminated"), bytes);
+ break;
+ }
+
HandleMessage(ovpn_pipe, proc_info.hProcess, &ring_buffer_handles, bytes, 1, &exit_event, &undo_lists);
}
--
2.40.0

View File

@ -0,0 +1,119 @@
From aaea545d8a940f761898d736b68bcb067d503b1d Mon Sep 17 00:00:00 2001
From: Lev Stipakov <lstipakov@gmail.com>
Date: Tue, 19 Mar 2024 15:53:45 +0200
Subject: [PATCH] win32: Enforce loading of plugins from a trusted directory
Currently, there's a risk associated with allowing plugins to be loaded from
any location. This update ensures plugins are only loaded from a trusted
directory, which is either:
- HKLM\SOFTWARE\OpenVPN\plugin_dir (or if the key is missing,
then HKLM\SOFTWARE\OpenVPN, which is installation directory)
- System directory
Loading from UNC paths is disallowed.
Note: This change affects only Windows environments.
CVE: 2024-27903
Change-Id: I154a4aaad9242c9253a64312a14c5fd2ea95f40d
Reported-by: Vladimir Tokarev <vtokarev@microsoft.com>
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Selva Nair <selva.nair@gmail.com>
Message-Id: <20240319135355.1279-2-lev@openvpn.net>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28416.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
CVE:CVE-2024-27903
Upstream-Status: Backport [https://github.com/OpenVPN/openvpn/commit/aaea545d8a940f761898d736b68bcb067d503b1d]
Signed-off-by: Meenali Gupta <meenali.gupta@windriver.com>
---
src/openvpn/plugin.c | 18 +++++++++++++++---
src/openvpn/win32.c | 21 +++++++++------------
2 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/src/openvpn/plugin.c b/src/openvpn/plugin.c
index ed5d7c0..f7315f4 100644
--- a/src/openvpn/plugin.c
+++ b/src/openvpn/plugin.c
@@ -279,11 +279,23 @@ plugin_init_item(struct plugin *p, const struct plugin_option *o)
#else /* ifndef _WIN32 */
- rel = !platform_absolute_pathname(p->so_pathname);
- p->module = LoadLibraryW(wide_string(p->so_pathname, &gc));
+ WCHAR *wpath = wide_string(p->so_pathname, &gc);
+ WCHAR normalized_plugin_path[MAX_PATH] = {0};
+ /* Normalize the plugin path, converting any relative paths to absolute paths. */
+ if (!GetFullPathNameW(wpath, MAX_PATH, normalized_plugin_path, NULL))
+ {
+ msg(M_ERR, "PLUGIN_INIT: could not load plugin DLL: %ls. Failed to normalize plugin path.", wpath);
+ }
+
+ if (!plugin_in_trusted_dir(normalized_plugin_path))
+ {
+ msg(M_FATAL, "PLUGIN_INIT: could not load plugin DLL: %ls. The DLL is not in a trusted directory.", normalized_plugin_path);
+ }
+
+ p->module = LoadLibraryW(normalized_plugin_path);
if (!p->module)
{
- msg(M_ERR, "PLUGIN_INIT: could not load plugin DLL: %s", p->so_pathname);
+ msg(M_ERR, "PLUGIN_INIT: could not load plugin DLL: %ls", normalized_plugin_path);
}
#define PLUGIN_SYM(var, name, flags) dll_resolve_symbol(p->module, (void *)&p->var, name, p->so_pathname, flags)
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
index e91e742..1e61ffa 100644
--- a/src/openvpn/win32.c
+++ b/src/openvpn/win32.c
@@ -1532,27 +1532,24 @@ openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const for
return (len >= 0 && len < size);
}
-static BOOL
-get_install_path(WCHAR *path, DWORD size)
+bool
+get_openvpn_reg_value(const WCHAR *key, WCHAR *value, DWORD size)
{
WCHAR reg_path[256];
- HKEY key;
- BOOL res = FALSE;
+ HKEY hkey;
openvpn_swprintf(reg_path, _countof(reg_path), L"SOFTWARE\\" PACKAGE_NAME);
- LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &key);
+ LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &hkey);
if (status != ERROR_SUCCESS)
{
- return res;
+ return false;
}
- /* The default value of REG_KEY is the install path */
- status = RegGetValueW(key, NULL, NULL, RRF_RT_REG_SZ, NULL, (LPBYTE)path, &size);
- res = status == ERROR_SUCCESS;
+ status = RegGetValueW(hkey, NULL, key, RRF_RT_REG_SZ, NULL, (LPBYTE)value, &size);
- RegCloseKey(key);
+ RegCloseKey(hkey);
- return res;
+ return status == ERROR_SUCCESS;
}
static void
@@ -1561,7 +1558,7 @@ set_openssl_env_vars()
const WCHAR *ssl_fallback_dir = L"C:\\Windows\\System32";
WCHAR install_path[MAX_PATH] = { 0 };
- if (!get_install_path(install_path, _countof(install_path)))
+ if (!get_openvpn_reg_value(NULL, install_path, _countof(install_path)))
{
/* if we cannot find installation path from the registry,
* use Windows directory as a fallback
--
2.40.0

View File

@ -10,7 +10,11 @@ inherit autotools systemd update-rc.d
SRC_URI = "http://swupdate.openvpn.org/community/releases/${BP}.tar.gz \
file://openvpn \
file://openvpn@.service \
file://openvpn-volatile.conf"
file://openvpn-volatile.conf \
file://CVE-2024-24974.patch \
file://CVE-2024-27459.patch \
file://CVE-2024-27903.patch \
"
UPSTREAM_CHECK_URI = "https://openvpn.net/community-downloads"