July 2024 Windows Updates brought a patch for CVE-2024-38077,
a memory corruption vulnerability in Remote Desktop Licensing Service that could potentially allow an attacker in a Windows network to remotely execute arbitrary code on a computer running this service.
Security researchers Lewis Lee, Chunyang Han and Zhiniang Peng found this vulnerability and reported it to Microsoft. On August 9 they also published an article (subsequently deleted) with some details about this vulnerability and an incomplete pseudo-code POC. We had confirmed that said POC was not working as-is but combining various sources, we were able to create our own working POC.
The Vulnerability
The vulnerability resides in the Remote Desktop Licensing Service, a service only running on Windows Servers and not installed by default: one has to add the "Remote Desktop Licensing" role to have it installed.
The flaw is in a fixed-size buffer being used for user-supplied data, which can result in a buffer overflow. Careful selection of user-supplied data could potentially lead to execution of arbitrary code on the server hosting the Remote Desktop Licensing Service, running as Local System.
Microsoft's patch checks for the buffer overflow and exits the affected function with error before it occurs.
Our Micropatch
Our micropatch is simpler but logically equivalent to Microsoft's.
Here's the source code of our micropatch.
;XX-2326
MODULE_PATH "..\AffectedModules\lserver.dll_6.3.9600.18226_Server-2012_64-bit_u2023-1\lserver.dll"
PATCH_ID 1000002
PATCH_FORMAT_VER 2
VULN_ID 7834
PLATFORM win64
patchlet_start
PATCHLET_ID 1
PATCHLET_TYPE 2
PATCHLET_OFFSET 0x7bb8f
N_ORIGINALBYTES 5
JUMPOVERBYTES 0
PIT lserver.dll!0x7bbf5,kernel32.dll!GetModuleHandleA
code_start
push rax
push rcx
push rdx
push r8
push r9 ;push all the volatile registers to save the initial state
push r10
push r11
push r12
mov r11, 0x0 ;move a 0x0 flag to r11
mov r12, rax ;save the current counter value to r12
call STR1 ;load the current module name to stack so we can call GetModuleHandle
db 'lserver.dll',0
STR1:
pop rcx ;pop the string pointer to the first arg
sub rsp, 0x20 ;create the shadowspace
call PIT_GetModuleHandleA ;call GeModuleHandle to get the current module base address
add rsp, 0x20 ;delete the shadowspace
cmp rax, 0x0 ;check if the call succeeded
je EXIT ;if GetModuleHandle call failed jump out of the patch without doing anything
cmp r12d, dword[rax+0xa873c] ;compare the current counter value to the size of the buffer
;that is saved in a global variable on base address + 0xa873c
jb EXIT ;if the counter is less then the buffer size skip the flag setting instruction
mov r11, 0x1 ;otherwise set the flag and continue
EXIT:
cmp r11, 0x1 ;check the flag so we can use a conditional jump after restoring registers
pop r12
pop r11
pop r10
pop r9 ;restore the original register states
pop r8
pop rdx
pop rcx
pop rax
je PIT_0x7bbf5 ;if the flag was set jump to the error block as an overflow is
;about to occur- else continue normally
code_end
patchlet_end
The video below shows our micropatch in action: first, the target server (on the left) has 0patch disabled, and running our POC against it from another machine in the domain causes the Remote Desktop Licensing Service to crash. The same test with 0patch enabled - and therefore our micropatch applied - does not lead to the crash.
Micropatch Availability
Micropatches were written for the following security-adopted versions of Windows with all available Windows Updates installed:
- Windows Server 2008 R2 - no ESU, ESU 1-4
- Windows Server 2012 - no ESU
- Windows Server 2012 R2 - no ESU
Vulnerabilities like these get discovered on a regular basis, and
attackers know about them all. If you're using Windows that aren't
receiving official security updates anymore, 0patch will make sure these
vulnerabilities won't be exploited on your computers - and you won't
even have to know or care about these things.
If you're new to 0patch, create a free account in 0patch Central, start a free trial, then install and register 0patch Agent. Everything else will happen automatically. No computer reboot will be needed.
We would like to thank Lewis Lee, Chunyang Han and Zhiniang Peng for sharing their analysis, which made it possible for us to create a
micropatch for this issue.