
SonicWall Capture Labs Threat Research Team became aware of the threat CVE-2023-34048 (a vCenter Server out-of-bounds write vulnerability), assessed its impact, and developed mitigation measures for the vulnerability.
VMware vCenter Server is a centralized management platform for VMware vSphere environments, designed to provide a unified and efficient administration experience. It allows IT administrators to manage virtualized hosts and virtual machines across multiple physical servers from a single console. vCenter Server plays a crucial role in resource provisioning, monitoring and performance evaluation of virtual infrastructures.
The identified vulnerability in VMware's vCenter Server is a critical security flaw stemming from an out-of-bounds write issue in its implementation of the Distributed Computing Environment / Remote Procedure Call (DCERPC) protocol. This protocol is used for inter-process communication, and the vulnerability arises due to improper handling of certain inputs. Consequently, a malicious actor with network access to vCenter Server can exploit this vulnerability to execute an out-of-bounds write operation.
This type of vulnerability can be particularly dangerous as it may allow the attacker to write data outside the bounds of allocated memory buffers, potentially leading to remote code execution. Such an exploit could provide the attacker with unauthorized control over the vCenter Server, posing a significant risk to the security and integrity of the virtualized environment managed by vCenter.
Our research concluded that the most feasible outcome of such an attack is the creation of a Denial of Service (DoS) condition on the server, and it is highly unlikely remote execution can be achieved. This vulnerability underscores the need for stringent security measures and prompt patching of software components in enterprise virtualization infrastructures. To mitigate this vulnerability, we recommend that you update to the latest version of VMware vCenter Server.
The affected versions are:
This vulnerability has been assigned the Common Vulnerabilities and Exposures (CVE) identifier CVE-2023-34048.
The overall CVSS score is 9.8 (CVSS:3.1/ AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:X/RL:X/RC:X).
The base score is 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), based on the following metrics:
In DCE/RPC, there are several packet types (as seen in Figure 1), each serving a specific purpose in the communication process. These packet types are defined as part of the protocol and are used to manage various aspects of RPC communication, such as establishing connections, transmitting data and handling errors.

Figure 1 - Packet Types
The packet types numbered 11 through 19 are of particular interest when assessing this vulnerability. The descriptions of each packet type are listed below:
Delving further into the “libdcerpc.so” library to understand how vCenter Server manages RPC network communication is crucial. This exploration is key to comprehending the complexities of the vulnerability. The group of functions shown in Figure 2, within this library, play a vital role in regulating data flow, safeguarding security and upholding the communication process's integrity. Working collaboratively, the following functions address different facets of network interaction, each with its distinct function.

Figure 2 - Simple Overview of Nested Functions
To further our understanding, it is essential to delve into two key foundational concepts:
In 64-bit systems, pointers usually have an 8-byte (64-bit) size, enabling them to address a vast memory space. Manipulating these pointers for memory navigation involves a linear process. Consider a pointer defined as “long long *ptr = (long long *)0x7fff5fbffec0,” which points to an 8-byte long long integer. Moving this pointer is accomplished in increments equal to the size of the data type it references.
To advance the pointer to the next long long integer, you increment it: ptr++, which adds 8 bytes to the address, making it point to 0x7fff5fbffec8. Similarly, decrementing the pointer with ptr-- moves it back by 8 bytes to 0x7fff5fbffec0.
This linear movement can be extended to skip multiple elements, like ptr += 2 to move forward 16 bytes, or ptr -= 2 to move back 16 bytes. This approach allows for effective traversal and manipulation of memory locations, but it requires careful handling to avoid errors like accessing invalid memory areas.

Figure 3 - Pointer Example
In the context of a debugger's memory window, which typically displays memory in a linear, byte-oriented format, moving a pointer as demonstrated in the example reflects a vertical traversal through memory addresses. The memory window is often organized in rows and columns, with each row representing a contiguous block of memory addresses. When the pointer long long *ptr = (long long *)0x7fff5fbffec0; is incremented (ptr++), it moves 'down' to the next memory block, shifting from 0x7fff5fbffec0 to 0x7fff5fbffec8.
This is because each increment steps through 8 bytes (the size of a long long in a 64-bit system), effectively descending to the next row in the memory window. Conversely, decrementing the pointer (ptr--) moves it 'up' to the previous memory block. Adjustments like ptr += 2 or ptr -= 2 result in moving two rows down or up, respectively.
In the debugger's memory window, this movement appears vertical, navigating through the memory rows, while each column within a row typically represents a single byte. This visualization aids in understanding how pointers access and manipulate specific locations in the system's memory space.
Viewing memory as linear or vertical from above, we can now understand the “rpc_cn_fragbuf_s_t” structure in C as seen Figure 4. This structure, with its specific memory alignment and field layout, is designed to manage fragment buffers in RPC communication. The structure begins with an 'rpc_list_t' link, occupying 16 bytes, which serves as a linked list node. This allows the fragment buffer to be part of a list, with pointers to the next and previous elements. Following this is a 4-byte 'unsigned32 freebuf', a flag indicating whether the buffer should be freed. Another 4-byte 'unsigned32' field, 'max_data_size', specifies the maximum data capacity of the fragment buffer.

Figure 4 - Structure Layout
The rpc_cn_fragbuf_dealloc_fn_t fragbuf_dealloc is an 8-byte function pointer for deallocating the fragment buffer. Next is an 8-byte pointer_t data_p, pointing to the actual data stored in the fragment buffer. The unsigned32 data_size field, 4 bytes long, records the current size of the data. An additional 4-byte unsigned8 overhead_area is reserved for miscellaneous use or overhead information.
Finally, a 1-byte unsigned8 data_area array is a flexible array member used to reference the start of the data region, typically used to access the packet data (pkt_p pointer) stored in the buffer. The structure is aligned to 8 bytes, ensuring optimal access on 64-bit systems and maintaining compatibility with different compilers through conditional compilation directives (__declspec(align(8)) for MSVC and __attribute__((aligned(8))) for GCC/others).
Identified in Figure 5 as the start of the vulnerability, this code manipulates pointers and memory within a network packet structure, specifically within an RPC binding header. Initially, the variable authlen is assigned the value of the auth_len field from the packet's common header. An offset is then calculated, which is set to authlen + 8.
The pointer ppDealloc is set to point to a specific location within the packet, calculated by subtracting this offset from the address at the end of the fragment (frag_len from the packet's start). The value at ppDealloc is then accessed and stored in pDealloc. Following this, the code performs a byte swap operation on the 4 bytes immediately following ppDealloc.

Figure 5 - epilogue of rpc__cn_unpack_hdr()
The reason behind why this works is the following formula:
ppDealloc = pkt_p + (frag_len - (auth_len + 8))
The math in the round brackets (frag_len – offset) creates a negative number result, which moves the pkt_p pointer upward to the fragbuf_dealloc pointers address when added together (in other words, subtracted because of the negative number).
In the disassembly of the RPC communication process, shown in Figure 6, a sequence of operations is performed on the “rpc_cn_fragbuf_s_t” structure. The operations reveal intricate aspects of vulnerability exploitation. The steps are as follows:

Figure 6 - Disassembly of rpc__cn_unpack_hdr()
Due to the vulnerability involving a byte-swap of the base address, it is important to note that an attacker lacks control over the final, byte-swapped base address. This limitation is critical because it restricts the attacker's ability to execute arbitrary code or manipulate the server's operations in a specific, intended manner.
Instead, the most feasible outcome of such an attack is the creation of a Denial of Service (DoS) condition on the server. In a DoS scenario, the attacker can disrupt the normal functioning of the server, potentially causing it to crash or become unresponsive, but cannot directly control or alter the server's behavior beyond causing this disruption. This limitation stems from the inability to predict or influence the final state of the memory after the byte swap, making it highly unlikely to execute precision attacks like injecting or executing specific malicious code. As a result, the attack vector, while serious, is likely confined to causing service interruptions rather than enabling direct system compromise or data theft.
Figure 7 below involves checking packet information and determining an event type based on the packet information. Execution returns to the calling function receive_dispatch, and it then follows with a check on the “class” member of the “packet_info_table” at index “ptype” (packet type) which is true (non-zero). This area of code assigns v14 the value of fragbuf_p and returns from the if else statement calling rpc_cn_assoc_eval_network_event().

Figure 7 - Receive_Dispatch()
Once inside the rpc_cn_assoc_eval_network_event function, an attempt is made to deallocate the fragment buffer. However due to an invalid function pointer, the application will crash at the call to “fragbuf_dealloc(fragbuf),” suggesting the pointer has been manipulated from the above swap of the base address.

Figure 8 - RPC_CN_ASSOC_EVAL_NETWORK_EVENT()
The following packet, in Figure 9, produces a Denial-of-Service (DoS) crash or segment fault:

Figure 9 - Attack Packet
This demo video below demonstrates the results of the packet in Figure 9 being sent to the vulnerable version VMWare vCenter Server 8.0U1c. As explained in Figure 8, a crash occurs on a jmp rax instruction, since rax now has an invalid pointer stored within it.
Figure 10 - Video of attack packet causing crash
To ensure SonicWall customers are prepared for any exploitation that may occur due to this vulnerability, the following signatures have been released:
The risks posed by this vulnerability can be mitigated or eliminated by:
Share This Article

An Article By
An Article By
Security News
Security News