From 0ad058645afc60aa2e76e39bfcc0cc223b93a019 Mon Sep 17 00:00:00 2001 From: Tu Dinh Date: Fri, 28 Mar 2025 22:58:50 +0000 Subject: Secure Xencons monitor named pipes * Create monitor named pipes under the \\.\pipe\ProtectedPrefix\Administrators prefix to prevent unprivileged users from creating named pipe instances under the same path; * Assign a restrictive security descriptor to monitor named pipes to prevent unprivileged users from reading console inputs; * Set PIPE_REJECT_REMOTE_CLIENTS to prevent monitor named pipes from being exposed to the network. This is part of XSA-468 / CVE-2025-27462. Signed-off-by: Tu Dinh Reviewed-by: Owen Smith --- src/monitor/monitor.c | 36 ++++++++++++++++++++++++++++-------- src/tty/tty.c | 2 +- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 59e6ab6aee78..ec8a638638f8 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -93,7 +94,9 @@ typedef struct _MONITOR_CONNECTION { static MONITOR_CONTEXT MonitorContext; -#define PIPE_BASE_NAME "\\\\.\\pipe\\xencons\\" +#define PIPE_BASE_NAME "\\\\.\\pipe\\ProtectedPrefix\\Administrators\\xencons\\" +// FILE_GENERIC_ALL for SYSTEM and Builtin\Administrators, nothing for the rest +#define PIPE_SDDL "D:(A;;FA;;;SY)(A;;FA;;;BA)" #define MAXIMUM_BUFFER_SIZE 1024 @@ -436,6 +439,7 @@ ServerThread( DWORD Object; PMONITOR_CONNECTION Connection; HRESULT Error; + SECURITY_ATTRIBUTES SecurityAttributes; Log("====> %s", Console->DeviceName); @@ -460,17 +464,26 @@ ServerThread( Log("%s", PipeName); + ZeroMemory(&SecurityAttributes, sizeof(SECURITY_ATTRIBUTES)); + SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + SecurityAttributes.bInheritHandle = FALSE; + if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(PIPE_SDDL, + SDDL_REVISION_1, + &SecurityAttributes.lpSecurityDescriptor, + NULL)) + goto fail3; + for (;;) { Pipe = CreateNamedPipe(PipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS, PIPE_UNLIMITED_INSTANCES, MAXIMUM_BUFFER_SIZE, MAXIMUM_BUFFER_SIZE, 0, - NULL); + &SecurityAttributes); if (Pipe == INVALID_HANDLE_VALUE) - goto fail3; + goto fail4; (VOID) ConnectNamedPipe(Pipe, &Overlapped); @@ -488,7 +501,7 @@ ServerThread( Connection = (PMONITOR_CONNECTION)malloc(sizeof(MONITOR_CONNECTION)); if (Connection == NULL) - goto fail4; + goto fail5; __InitializeListHead(&Connection->ListEntry); Connection->Console = Console; @@ -500,24 +513,31 @@ ServerThread( 0, NULL); if (Connection->Thread == NULL) - goto fail5; + goto fail6; } + LocalFree(&SecurityAttributes.lpSecurityDescriptor); + CloseHandle(Overlapped.hEvent); Log("<==== %s", Console->DeviceName); return 0; +fail6: + Log("fail6"); + + free(Connection); + fail5: Log("fail5"); - free(Connection); + CloseHandle(Pipe); fail4: Log("fail4"); - CloseHandle(Pipe); + LocalFree(&SecurityAttributes.lpSecurityDescriptor); fail3: Log("fail3"); diff --git a/src/tty/tty.c b/src/tty/tty.c index c3b6f8e18345..08d372435772 100644 --- a/src/tty/tty.c +++ b/src/tty/tty.c @@ -44,7 +44,7 @@ typedef struct _TTY_STREAM { HANDLE Write; } TTY_STREAM, *PTTY_STREAM; -#define PIPE_NAME TEXT("\\\\.\\pipe\\xencons\\default") +#define PIPE_NAME TEXT("\\\\.\\pipe\\ProtectedPrefix\\Administrators\\xencons\\default") #define MAXIMUM_BUFFER_SIZE 1024 typedef struct _TTY_CONTEXT { -- 2.47.1