Skip to content

Instantly share code, notes, and snippets.

@hugsy
Created September 10, 2020 22:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugsy/daa04d3d1298dc6904a091a63d176aa4 to your computer and use it in GitHub Desktop.
Save hugsy/daa04d3d1298dc6904a091a63d176aa4 to your computer and use it in GitHub Desktop.
dll payload to execute code from session 0 to first interactive session
#include <windows.h>
#include <wtsapi32.h>
#include <Userenv.h>
#include <TlHelp32.h>
#include <Lmcons.h>
#include <iostream>
#pragma comment(lib, "Wtsapi32.lib")
#pragma comment(lib, "Userenv.lib")
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "user32.lib")
/**
*
* dll to run a command in a different (interactive) session
* typically for sess0 -> sess2
*
**/
DWORD FindFirstActiveSession()
{
PWTS_SESSION_INFOW Sessions;
DWORD SessionCount = 0;
DWORD dwSessId = (DWORD)-1;
auto bRes = ::WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &Sessions, &SessionCount);
if (!bRes)
return false;
for(auto i=0; i<SessionCount; i++)
{
if(Sessions[i].State == WTSActive)
{
dwSessId = Sessions[i].SessionId;
break;
}
}
::WTSFreeMemory(Sessions);
return dwSessId;
}
void RunProcessInInteractiveSession()
{
std::wstring CommandLine = L"c:\\windows\\system32\\notepad.exe";
do
{
HANDLE hLoggedOnUserPrimaryToken = nullptr;
HANDLE hDuplicatedToken = nullptr;
LPVOID lpEnvironment = nullptr;
DWORD ActiveSessionId = FindFirstActiveSession();
if (ActiveSessionId == -1)
break;
auto bRes = ::WTSQueryUserToken(ActiveSessionId, &hLoggedOnUserPrimaryToken);
if (!bRes)
break;
bRes = ::DuplicateTokenEx(
hLoggedOnUserPrimaryToken,
TOKEN_ALL_ACCESS,
nullptr,
SecurityImpersonation,
//SecurityIdentification,
TokenPrimary,
&hDuplicatedToken
);
::CloseHandle(hLoggedOnUserPrimaryToken);
if (!bRes)
break;
bRes = ::SetTokenInformation(hDuplicatedToken, TokenSessionId, &ActiveSessionId, sizeof(ActiveSessionId));
if(!bRes)
break;
bRes = ::CreateEnvironmentBlock(&lpEnvironment, hDuplicatedToken, false);
if(!bRes)
break;
PROCESS_INFORMATION pi = {0,};
STARTUPINFOEX si = {0,};
si.StartupInfo.cb = sizeof(STARTUPINFOW);
bRes = ::CreateProcessAsUserW(
hDuplicatedToken,
nullptr,
(LPWSTR)CommandLine.c_str(),
nullptr,
nullptr,
false,
CREATE_NEW_CONSOLE,
nullptr,
::_wgetenv(L"USERPROFILE"),
(LPSTARTUPINFOW)&si,
&pi
);
if(!bRes)
break;
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
}
while(false);
}
__declspec(dllexport) extern "C" void DllRun()
{
RunProcessInInteractiveSession();
}
extern "C" BOOL APIENTRY DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DllRun();
break;
case DLL_THREAD_ATTACH:
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment