|
14 | 14 |
|
15 | 15 | static FILE *userspace_interface_file(const char *iface) |
16 | 16 | { |
17 | | - char fname[MAX_PATH], error_message[1024 * 128] = { 0 }; |
18 | | - HANDLE thread_token, process_snapshot, winlogon_process, winlogon_token, duplicated_token, pipe_handle = INVALID_HANDLE_VALUE; |
19 | | - PROCESSENTRY32 entry = { .dwSize = sizeof(PROCESSENTRY32) }; |
20 | | - PSECURITY_DESCRIPTOR pipe_sd; |
21 | | - PSID pipe_sid; |
| 17 | + char fname[MAX_PATH]; |
| 18 | + HANDLE pipe_handle; |
22 | 19 | SID expected_sid; |
23 | | - BOOL ret; |
| 20 | + DWORD bytes = sizeof(expected_sid); |
| 21 | + PSID pipe_sid; |
| 22 | + PSECURITY_DESCRIPTOR pipe_sd; |
| 23 | + bool equal; |
24 | 24 | int fd; |
25 | | - DWORD last_error = ERROR_SUCCESS, bytes = sizeof(expected_sid); |
26 | | - TOKEN_PRIVILEGES privileges = { |
27 | | - .PrivilegeCount = 1, |
28 | | - .Privileges = {{ .Attributes = SE_PRIVILEGE_ENABLED }} |
29 | | - }; |
30 | 25 |
|
31 | | - if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid)) |
32 | | - goto err; |
33 | 26 | if (!CreateWellKnownSid(WinLocalSystemSid, NULL, &expected_sid, &bytes)) |
34 | 27 | goto err; |
35 | 28 |
|
36 | | - process_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); |
37 | | - if (process_snapshot == INVALID_HANDLE_VALUE) |
38 | | - goto err; |
39 | | - for (ret = Process32First(process_snapshot, &entry); ret; last_error = GetLastError(), ret = Process32Next(process_snapshot, &entry)) { |
40 | | - if (strcasecmp(entry.szExeFile, "winlogon.exe")) |
41 | | - continue; |
42 | | - |
43 | | - RevertToSelf(); |
44 | | - if (!ImpersonateSelf(SecurityImpersonation)) |
45 | | - continue; |
46 | | - if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &thread_token)) |
47 | | - continue; |
48 | | - if (!AdjustTokenPrivileges(thread_token, FALSE, &privileges, sizeof(privileges), NULL, NULL)) { |
49 | | - last_error = GetLastError(); |
50 | | - CloseHandle(thread_token); |
51 | | - continue; |
52 | | - } |
53 | | - CloseHandle(thread_token); |
54 | | - |
55 | | - winlogon_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, entry.th32ProcessID); |
56 | | - if (!winlogon_process) |
57 | | - continue; |
58 | | - if (!OpenProcessToken(winlogon_process, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &winlogon_token)) |
59 | | - continue; |
60 | | - CloseHandle(winlogon_process); |
61 | | - if (!DuplicateToken(winlogon_token, SecurityImpersonation, &duplicated_token)) { |
62 | | - last_error = GetLastError(); |
63 | | - RevertToSelf(); |
64 | | - continue; |
65 | | - } |
66 | | - CloseHandle(winlogon_token); |
67 | | - if (!SetThreadToken(NULL, duplicated_token)) { |
68 | | - last_error = GetLastError(); |
69 | | - CloseHandle(duplicated_token); |
70 | | - continue; |
71 | | - } |
72 | | - CloseHandle(duplicated_token); |
73 | | - |
74 | | - snprintf(fname, sizeof(fname), "\\\\.\\pipe\\ProtectedPrefix\\Administrators\\WireGuard\\%s", iface); |
75 | | - pipe_handle = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); |
76 | | - last_error = GetLastError(); |
77 | | - if (pipe_handle == INVALID_HANDLE_VALUE) |
78 | | - continue; |
79 | | - last_error = GetSecurityInfo(pipe_handle, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pipe_sid, NULL, NULL, NULL, &pipe_sd); |
80 | | - if (last_error != ERROR_SUCCESS) { |
81 | | - CloseHandle(pipe_handle); |
82 | | - continue; |
83 | | - } |
84 | | - last_error = EqualSid(&expected_sid, pipe_sid) ? ERROR_SUCCESS : ERROR_ACCESS_DENIED; |
85 | | - LocalFree(pipe_sd); |
86 | | - if (last_error != ERROR_SUCCESS) { |
87 | | - CloseHandle(pipe_handle); |
88 | | - continue; |
89 | | - } |
90 | | - last_error = ERROR_SUCCESS; |
91 | | - break; |
92 | | - } |
93 | | - RevertToSelf(); |
94 | | - CloseHandle(process_snapshot); |
95 | | - |
96 | | - if (last_error != ERROR_SUCCESS || pipe_handle == INVALID_HANDLE_VALUE) |
| 29 | + snprintf(fname, sizeof(fname), "\\\\.\\pipe\\ProtectedPrefix\\Administrators\\WireGuard\\%s", iface); |
| 30 | + pipe_handle = CreateFileA(fname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); |
| 31 | + if (pipe_handle == INVALID_HANDLE_VALUE) |
97 | 32 | goto err; |
| 33 | + if (GetSecurityInfo(pipe_handle, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pipe_sid, NULL, NULL, NULL, &pipe_sd) != ERROR_SUCCESS) |
| 34 | + goto err_close; |
| 35 | + equal = EqualSid(&expected_sid, pipe_sid); |
| 36 | + LocalFree(pipe_sd); |
| 37 | + if (!equal) |
| 38 | + goto err_close; |
98 | 39 | fd = _open_osfhandle((intptr_t)pipe_handle, _O_RDWR); |
99 | 40 | if (fd == -1) { |
100 | | - last_error = GetLastError(); |
101 | 41 | CloseHandle(pipe_handle); |
102 | | - goto err; |
| 42 | + return NULL; |
103 | 43 | } |
104 | 44 | return _fdopen(fd, "r+"); |
105 | | - |
| 45 | +err_close: |
| 46 | + CloseHandle(pipe_handle); |
106 | 47 | err: |
107 | | - if (last_error == ERROR_SUCCESS) |
108 | | - last_error = GetLastError(); |
109 | | - if (last_error == ERROR_SUCCESS) |
110 | | - last_error = ERROR_ACCESS_DENIED; |
111 | | - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error_message, sizeof(error_message) - 1, NULL); |
112 | | - fprintf(stderr, "Error: Unable to open IPC handle via SYSTEM impersonation: %ld: %s\n", last_error, error_message); |
113 | 48 | errno = EACCES; |
114 | 49 | return NULL; |
115 | 50 | } |
|
0 commit comments