by Mitja Kolsek, the 0patch Team
June 2022 Windows Updates brought a fix for a local privilege escalation in Local Security Authority Subsystem Service (LSASS), discovered by James Forshaw of Google Project Zero. James published details and a POC on July 14.
The vulnerability allows a local non-admin attacker to use a certain type of impersonation (specifically, impersonating a token at identification level) to get the service running as Local System to enumerate the ticket cache not only for the requesting user but also for the Local System account. With this information, the attacker could elevate their privileges on the local system.
Microsoft assigned this issue CVE-2022-30166 and fixed it by creating an "anonymous" impersonation when the original attempt at impersonation fails; as a result, a malicious request ends up returning only requesting user's ticket cache.
Our micropatch with 18 CPU instructions is logically equivalent to Microsoft's:
MODULE_PATH "..\AffectedModules\lsasrv.dll_10.0.19041.1415_Win10-2004_64-bit_u202112\lsasrv.dll"
PATCH_ID 1017
PATCH_FORMAT_VER 2
VULN_ID 7441
PLATFORM win64
patchlet_start
PATCHLET_ID 1
PATCHLET_TYPE 2
PATCHLET_OFFSET 0x2e302
N_ORIGINALBYTES 5
JUMPOVERBYTES 5
PIT lsasrv!0x145f0,ntdll!NtClose
code_start
mov byte[rdi+0x11], 1 ;original overwritten code
mov [rdi+0x14], eax ;original overwritten code
cmp eax, 1 ;check current tokens impersonation level. 1 == ANONYMOUS
jne END ;if it is ANONYMOUS nothing needs to be done and we
;skip the patch
mov rcx, [rbx+0x0c0] ;move current token handle to rcx so we can close it
sub rsp, 0x20 ;create shadowspace with additional 0x8 bytes to
;align the stack
call PIT_NtClose ;close the token handle
add rsp, 0x20 ;delete the created shadowspace
mov qword[rbx+0x0c0], 0x0 ;overwrite the old handle with 0x0
mov rcx, rdi ;move SECPKG_CLIENT_INFO_EX to rcx
lea rdx, [rbx+0x0c0] ;move new handle pointer to rdx for output
mov qword[rcx], 0x3e6 ;move LsapAnonymousLogonId to rcx pointer
push 0x000003e6 ;push LsapAnonymousLogonId to stack so we can use the
;pointer
lea rcx, [rsp] ;move the pointer to LsapAnonymousLogonId into rcx
sub rsp, 0x28 ;create shadowsapce
call PIT_0x145f0 ;call LsapOpenTokenByLogonId to get a new anonymous
;token
add rsp, 0x30 ;clear shadowspace and account for the push
mov rax, 1 ;move 1 to eax as some versions of this dll need it
;and we don't need the return value
END:
code_end
patchlet_end
This video demonstrates the effect of our micropatch. With 0patch disabled, the POC obtains and displays the token cache of both the current user and Local System; with 0patch enabled, only user's token cache is accessible to the local non-admin user.
Our micropatch was written for the following Windows versions that don't receive official patches from Microsoft:
- Windows 10 v1803 updated to May 2021
- Windows 10 v1809 updated to May 2021
- Windows 10 v1903 updated to May 2021
- Windows 10 v1909 updated to May 2021
- Windows 10 v2004 updated to December 2021
- Windows 7 updated with ESU year 2, ESU year 1 or updated to January 2020
- Windows Server 2008 R2 updated with ESU year 2, ESU year 1 or updated to January 2020
We'd like to thank James Forshaw for publishing their analysis and providing a proof-of-concept that allowed us to reproduce the vulnerability and create a micropatch. We also encourage security researchers to privately share their analyses with us for micropatching.
Article Link: 0patch Blog: Micropatches for Local Privilege Escalation in LSASS (CVE-2022-30166)