S
Sagar R. Kapadia
Guest
I am trying to launch a process from a windows service [running under local system account] with credentials of the interactive user but administrator privileges. This works if I start the PC and log in to an adminstrator user. However, it fails on normal users, as described below.
On some previous installations of Windows 10, I had faced the problem While trying to launch a process with credentials of the interactive user, GetTokenInformation returns error code 1312 on Windows 7 and some installations of windows 10 if UAC is turned off. I got the solution to that in While trying to launch a process with credentials of the interactive user, GetTokenInformation returns error code 1312 on Windows 7 and some installations of windows 10 if UAC is turned off
I dont remember whether I tried the above solution with a non-administrator user. But at present,
I am facing a similar problem with a non-adminstrator user, in which GetTokenInformation fails with error 1312.
The code and log output are below.
The method GetTokenForProcessId fails on GetTokenInformation with error 1312, and SetTokenInformation fails with error 1375
GetProcessIdByNameAndSessionId
Method: LaunchProcessElevated
Process Name: ProcessMonitor-X64.exe
Explorer ProcessId: 10724
Winlogon ProcessId: 1820
Method: GetTokenForProcessId
GetTokenForProcessId::10724
OpenProcess reurned Handle:464
OpenProcessToken reurned Handle:468
Token Inf Length:44
Failed to Get Primary Token:1312
Explorer hTokenDst: 468
Method: GetTokenForProcessId
GetTokenForProcessId::1820
OpenProcess reurned Handle:472
OpenProcessToken reurned Handle:476
Token Inf Length:28
Failed to Get Primary Token:1312
Winlogn hTokenSrc: 476
Method: CopyPrivileges
CopyPrivileges: Original Tokens:476:468
GetImpersonationToken reurned Handle:476
DuplicateToken reurned Handle:480
GetImpersonationToken reurned Handle:468
DuplicateToken reurned Handle:484
CopyPrivileges: Impersonated Tokens:480:484
GetTokenPrivileges Buffer size:256
Privilege Count:5
Adjust Privileges Succeeded
SetTokenInformation succeded
Failed to SetTokenInformation:Error: 1375
Method: CreateProcessWithToken
Failed to start Process Monitor Process
STDMETHODIMP CProcessManager::LaunchProcessElevated(BSTR commandLine, DWORD* dwProcessId)
{
logger->ClearLog();
ZeroMemory(buffer, sizeof(buffer));
CComBSTR temp(commandLine);
LPWSTR lpszProcessName = temp.operator LPWSTR();
Report(L"Process Name: %s", (LPCWSTR)lpszProcessName);
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
DWORD dwProcessIdExplorer = GetProcessIdByNameAndSessionId(L"explorer.exe", dwSessionId);
Report(L"Explorer ProcessId: %d", dwProcessIdExplorer);
DWORD dwProcessIdWinLogon= GetProcessIdByNameAndSessionId(L"winlogon.exe", dwSessionId);
Report(L"Winlogon ProcessId: %d", dwProcessIdWinLogon);
HANDLE hTokenDst = GetTokenForProcessId(dwProcessIdExplorer);
Report(L"Explorer hTokenDst: %d", hTokenDst);
HANDLE hTokenSrc = GetTokenForProcessId(dwProcessIdWinLogon);
Report(L"Winlogn hTokenSrc: %d", hTokenSrc);
if (CopyPrivileges(hTokenSrc, hTokenDst)) {
if (!SetTokenInformation(hTokenDst, TokenSessionId, &dwSessionId, sizeof(dwSessionId)))
{
Report(L"Failed to SetTokenInformation:Error: %d", GetLastError());
return S_FALSE;
}
//Report(lpszProcessName);
DWORD dwProcessIdNew = 0;
if (CreateProcessWithToken(hTokenDst, lpszProcessName, (DWORD*)& dwProcessIdNew))
{
*dwProcessId = dwProcessIdNew;
return S_OK;
}
else
{
Report(L"Failed to CreateProcessWithToken: Error: %d", GetLastError());
return S_FALSE;
}
}
else
{
Report(L"Failed to Copy Privileges:Error: %d", GetLastError());
return S_FALSE;
}
}
HANDLE CProcessManager::GetTokenForProcessId(UINT dwProcessId)
{
ZeroMemory(buffer, sizeof(buffer));
_ltow_s(dwProcessId, buffer, len, 10);
Report(L"GetTokenForProcessId::%d", dwProcessId);
HANDLE hProcess = 0;
HANDLE hToken = 0;
hProcess = OpenProcess(MAXIMUM_ALLOWED, 0, dwProcessId);
if (hProcess == NULL) {
Report(L"OpenProcess Returned Null: %d", GetLastError());
}
ZeroMemory(buffer, sizeof(buffer));
_ltow_s((long)hProcess, buffer, len, 10);
Report(L"OpenProcess reurned Handle:%s", buffer);
// obtain a handle to the access token of the winlogon process
if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS | TOKEN_READ | TOKEN_WRITE | TOKEN_EXECUTE, &hToken))
{
ZeroMemory(buffer, sizeof(buffer));
Report(L"OpenProcesToken Returned Null: %d", GetLastError());
CloseHandle(hProcess);
return 0;
}
ZeroMemory(buffer, sizeof(buffer));
Report(L"OpenProcessToken reurned Handle:%d", hToken);
DWORD TokenInfLength = 0;
//-http://www.microsoft-questions.com/microsoft/Platform-SDK-Security/35984508/how-to-run-a-process-with-elevated-privileges-run-as-administrat.aspx
// first call gets lenght of TokenInformation
GetTokenInformation(hToken, TokenUser, 0, TokenInfLength, &TokenInfLength);
Report(L"Token Inf Length:%d", TokenInfLength);
HANDLE* TokenInformation = (HANDLE*)LocalAlloc(LMEM_ZEROINIT, TokenInfLength);
TokenInfLength = sizeof(HANDLE);
if (!GetTokenInformation(hToken, TokenLinkedToken, TokenInformation, TokenInfLength, &TokenInfLength))
{
DWORD err = GetLastError();
Report(L"Failed to Get Primary Token:%d", err);
return hToken;
}
else {
HANDLE hPrimaryToken = *TokenInformation;
Report(L"Primary Token:%d", hPrimaryToken);
return hPrimaryToken;
}
return NULL;
}
DWORD GetProcessIdByNameAndSessionId(LPCWSTR lpszProcessName, DWORD sessionId)
{
//LaunchDebugger();
wchar_t* p = 0;
wchar_t* q = 0;
wchar_t* ProcessNameW = (wchar_t*)lpszProcessName;
DWORD processId = 0;
wchar_t lowerCaseInputProcess[512];
ZeroMemory(lowerCaseInputProcess, sizeof(lowerCaseInputProcess));
//Convert InputProcess to lower case
p = ProcessNameW;
q = lowerCaseInputProcess;
for (; *p; ++p, ++q) * q = tolower(*p);
//wprintf(L"Target:%s\n", lowerCaseInputProcess);
NTSTATUS status;
PVOID buffer;
PSYSTEM_PROCESS_INFO spi;
buffer = VirtualAlloc(NULL, 1024 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // We need to allocate a large buffer because the process list can be large.
if (!buffer)
{
// Report(L"\nError: Unable to allocate memory for process list: %d\n", GetLastError());
return -1;
}
//Report(L"\nProcess list allocated at address %#x\n", buffer);
spi = (PSYSTEM_PROCESS_INFO)buffer;
if (!NT_SUCCESS(status = NtQuerySystemInformation(SystemProcessInformation, spi, 1024 * 1024, NULL)))
{
//Report(L"\nError: Unable to query process list (%#x)\n", status);
VirtualFree(buffer, 0, MEM_RELEASE);
return -1;
}
wchar_t imageName[512];
wchar_t lowerCaseImageName[512];
cout << "ok";
while (spi->NextEntryOffset)
{
// Loop over the list until we reach the last entry.
//The following wsprintf is necessary because any access , include wcslen , other than wprintf causes an exception
//So copied buffer to another buffer for further processing.
//Report(lowerCaseImageName, L"%s", spi->ImageName.Buffer);
cout << spi->ImageName.Buffer << endl;
p = spi->ImageName.Buffer;
q = lowerCaseImageName;
ZeroMemory(lowerCaseImageName, sizeof(lowerCaseImageName));
if (p) {
for (; *p; ++p, ++q) * q = tolower(*p);
}
//Compare Names
if ((StrCmpCW(lowerCaseInputProcess, lowerCaseImageName)) == 0) {
processId = (DWORD)spi->ProcessId;
DWORD dwSessionId = 0;
if (ProcessIdToSessionId(processId, &dwSessionId))
{
if (sessionId == dwSessionId) {
//Report(L"Found a Match:%s\d", processId);
VirtualFree(buffer, 0, MEM_RELEASE); // Free the allocated buff
return processId;
}
}
}
spi = (PSYSTEM_PROCESS_INFO)((LPBYTE)spi + spi->NextEntryOffset); // Calculate the address of the next entry.
}
processId = 0;
VirtualFree(buffer, 0, MEM_RELEASE); // Free the allocated buffer.
return processId;
}
BOOL CProcessManager::CreateProcessWithToken(HANDLE hToken, LPCWSTR lpszCommandLine, DWORD* dwProcessId)
{
_ltow_s((long)hToken, buffer, len, 10);
wstring entry = wstring(L"CreateProcessWithToken:");
entry += lpszCommandLine;
Report(entry.c_str(), buffer);
// By default CreateProcessAsUser creates a process on a non-interactive window station, meaning
// the window station has a desktop that is invisible and the process is incapable of receiving
// user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
// interaction with the new process.
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.lpDesktop = L"winsta0\\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop
// flags that specify the priority and creation method of the process
UINT dwCreationFlags = (int)(NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE);
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
LPWSTR szCmdLine = _tcsdup(lpszCommandLine);
Report(szCmdLine);
//LPCWSTR commandLine = CharToWideChar(lpszCommandLine);
// MessageBox(0, lp, L"Path", MB_OK);
BOOL result = CreateProcessAsUser(hToken, // client's access token
0, // command line
szCmdLine, // file to execute
&sa, // pointer to process SECURITY_ATTRIBUTES
&sa, // pointer to thread SECURITY_ATTRIBUTES
0, // handles are not inheritable
dwCreationFlags, // creation flags
0, // pointer to new environment block
0, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
);
if (!result) {
//_ltow_s((DWORD)GetLastError(), buffer, len, 10);
//MessageBoxA(0, "OpenProces Returned Null",buffer, MB_OK);
Report(L"CreateProcessAsUser Returned Null. Error:%d", GetLastError());
}
*dwProcessId = pi.dwProcessId;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return result;
}
BOOL CProcessManager::CopyPrivileges(HANDLE hTokenSrc, HANDLE hTokenDst)
{
_ltow_s((long)hTokenSrc, buffer, len, 10);
wstring entry = wstring(buffer);
_ltow_s((long)hTokenDst, buffer, len, 10);
entry += wstring(L":") + wstring(buffer);
Report(L"CopyPrivileges: Original Tokens:%s", entry.c_str());
hTokenSrc = GetImpersonationToken(hTokenSrc);
hTokenDst = GetImpersonationToken(hTokenDst);
_ltow_s((long)hTokenSrc, buffer, len, 10);
entry = wstring(buffer);
_ltow_s((long)hTokenDst, buffer, len, 10);
entry += wstring(L":") + wstring(buffer);
Report(L"CopyPrivileges: Impersonated Tokens:%s", entry.c_str());
TOKEN_PRIVILEGES Priv;
ZeroMemory(&Priv, sizeof(Priv));
DWORD dwLen = 0;
GetTokenInformation(hTokenSrc, TokenPrivileges, &Priv, sizeof(TOKEN_PRIVILEGES), &dwLen);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
/**///)
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"GetTokenPrivileges First Call Failed with Error:%d", GetLastError());
return(0);
}
//_ltow_s(dwLen, buffer, len, 10);
Report(L"GetTokenPrivileges Buffer size:%d", dwLen);
PTOKEN_PRIVILEGES pPriv = (PTOKEN_PRIVILEGES)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLen * 10);
if (!GetTokenInformation(hTokenDst, TokenPrivileges, (LPVOID)pPriv, dwLen * 10, &dwLen)) {
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"GetTokenPrivileges Failed with Error:%d", GetLastError());
return(0);
}
//_ltow_s(pPriv->PrivilegeCount, buffer, len, 10);
Report(L"Privilege Count:%d", pPriv->PrivilegeCount);
if (!AdjustTokenPrivileges(hTokenDst, FALSE, pPriv, dwLen, NULL, NULL)) {
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"AdjustTokenPrivileges Failed with Error:%d", GetLastError());
return false;
}
LUID luid;
ZeroMemory(&luid, sizeof(luid));
if (!LookupPrivilegeValue(0, SE_TCB_NAME, &luid))
{
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"LookupPrivilegeValue Failed with Error:%d", GetLastError());
return false;
}
TOKEN_PRIVILEGES tp;
ZeroMemory(&tp, sizeof(tp));
tp.PrivilegeCount = 1;
tp.Privileges->Luid.HighPart = luid.HighPart;
tp.Privileges->Luid.LowPart = luid.LowPart;
DWORD dwReturn = 0;
if (!AdjustTokenPrivileges(hTokenDst, SE_PRIVILEGE_ENABLED, &tp, sizeof(tp), 0, &dwReturn))
{
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"AdjustTokenPrivileges for TCB_NAME Failed with Error:%d", GetLastError());
return false;
}
Report(L"Adjust Privileges Succeeded");
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
if (!SetTokenInformation(hTokenDst, TokenSessionId, &dwSessionId, sizeof(dwSessionId)))
{
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"SetTokenInformation Failed with Error:%d", GetLastError());
return false;;
}
Report(L"SetTokenInformation succeded");
return true;
}
Continue reading...
On some previous installations of Windows 10, I had faced the problem While trying to launch a process with credentials of the interactive user, GetTokenInformation returns error code 1312 on Windows 7 and some installations of windows 10 if UAC is turned off. I got the solution to that in While trying to launch a process with credentials of the interactive user, GetTokenInformation returns error code 1312 on Windows 7 and some installations of windows 10 if UAC is turned off
I dont remember whether I tried the above solution with a non-administrator user. But at present,
I am facing a similar problem with a non-adminstrator user, in which GetTokenInformation fails with error 1312.
The code and log output are below.
The method GetTokenForProcessId fails on GetTokenInformation with error 1312, and SetTokenInformation fails with error 1375
GetProcessIdByNameAndSessionId
Method: LaunchProcessElevated
Process Name: ProcessMonitor-X64.exe
Explorer ProcessId: 10724
Winlogon ProcessId: 1820
Method: GetTokenForProcessId
GetTokenForProcessId::10724
OpenProcess reurned Handle:464
OpenProcessToken reurned Handle:468
Token Inf Length:44
Failed to Get Primary Token:1312
Explorer hTokenDst: 468
Method: GetTokenForProcessId
GetTokenForProcessId::1820
OpenProcess reurned Handle:472
OpenProcessToken reurned Handle:476
Token Inf Length:28
Failed to Get Primary Token:1312
Winlogn hTokenSrc: 476
Method: CopyPrivileges
CopyPrivileges: Original Tokens:476:468
GetImpersonationToken reurned Handle:476
DuplicateToken reurned Handle:480
GetImpersonationToken reurned Handle:468
DuplicateToken reurned Handle:484
CopyPrivileges: Impersonated Tokens:480:484
GetTokenPrivileges Buffer size:256
Privilege Count:5
Adjust Privileges Succeeded
SetTokenInformation succeded
Failed to SetTokenInformation:Error: 1375
Method: CreateProcessWithToken
Failed to start Process Monitor Process
STDMETHODIMP CProcessManager::LaunchProcessElevated(BSTR commandLine, DWORD* dwProcessId)
{
logger->ClearLog();
ZeroMemory(buffer, sizeof(buffer));
CComBSTR temp(commandLine);
LPWSTR lpszProcessName = temp.operator LPWSTR();
Report(L"Process Name: %s", (LPCWSTR)lpszProcessName);
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
DWORD dwProcessIdExplorer = GetProcessIdByNameAndSessionId(L"explorer.exe", dwSessionId);
Report(L"Explorer ProcessId: %d", dwProcessIdExplorer);
DWORD dwProcessIdWinLogon= GetProcessIdByNameAndSessionId(L"winlogon.exe", dwSessionId);
Report(L"Winlogon ProcessId: %d", dwProcessIdWinLogon);
HANDLE hTokenDst = GetTokenForProcessId(dwProcessIdExplorer);
Report(L"Explorer hTokenDst: %d", hTokenDst);
HANDLE hTokenSrc = GetTokenForProcessId(dwProcessIdWinLogon);
Report(L"Winlogn hTokenSrc: %d", hTokenSrc);
if (CopyPrivileges(hTokenSrc, hTokenDst)) {
if (!SetTokenInformation(hTokenDst, TokenSessionId, &dwSessionId, sizeof(dwSessionId)))
{
Report(L"Failed to SetTokenInformation:Error: %d", GetLastError());
return S_FALSE;
}
//Report(lpszProcessName);
DWORD dwProcessIdNew = 0;
if (CreateProcessWithToken(hTokenDst, lpszProcessName, (DWORD*)& dwProcessIdNew))
{
*dwProcessId = dwProcessIdNew;
return S_OK;
}
else
{
Report(L"Failed to CreateProcessWithToken: Error: %d", GetLastError());
return S_FALSE;
}
}
else
{
Report(L"Failed to Copy Privileges:Error: %d", GetLastError());
return S_FALSE;
}
}
HANDLE CProcessManager::GetTokenForProcessId(UINT dwProcessId)
{
ZeroMemory(buffer, sizeof(buffer));
_ltow_s(dwProcessId, buffer, len, 10);
Report(L"GetTokenForProcessId::%d", dwProcessId);
HANDLE hProcess = 0;
HANDLE hToken = 0;
hProcess = OpenProcess(MAXIMUM_ALLOWED, 0, dwProcessId);
if (hProcess == NULL) {
Report(L"OpenProcess Returned Null: %d", GetLastError());
}
ZeroMemory(buffer, sizeof(buffer));
_ltow_s((long)hProcess, buffer, len, 10);
Report(L"OpenProcess reurned Handle:%s", buffer);
// obtain a handle to the access token of the winlogon process
if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS | TOKEN_READ | TOKEN_WRITE | TOKEN_EXECUTE, &hToken))
{
ZeroMemory(buffer, sizeof(buffer));
Report(L"OpenProcesToken Returned Null: %d", GetLastError());
CloseHandle(hProcess);
return 0;
}
ZeroMemory(buffer, sizeof(buffer));
Report(L"OpenProcessToken reurned Handle:%d", hToken);
DWORD TokenInfLength = 0;
//-http://www.microsoft-questions.com/microsoft/Platform-SDK-Security/35984508/how-to-run-a-process-with-elevated-privileges-run-as-administrat.aspx
// first call gets lenght of TokenInformation
GetTokenInformation(hToken, TokenUser, 0, TokenInfLength, &TokenInfLength);
Report(L"Token Inf Length:%d", TokenInfLength);
HANDLE* TokenInformation = (HANDLE*)LocalAlloc(LMEM_ZEROINIT, TokenInfLength);
TokenInfLength = sizeof(HANDLE);
if (!GetTokenInformation(hToken, TokenLinkedToken, TokenInformation, TokenInfLength, &TokenInfLength))
{
DWORD err = GetLastError();
Report(L"Failed to Get Primary Token:%d", err);
return hToken;
}
else {
HANDLE hPrimaryToken = *TokenInformation;
Report(L"Primary Token:%d", hPrimaryToken);
return hPrimaryToken;
}
return NULL;
}
DWORD GetProcessIdByNameAndSessionId(LPCWSTR lpszProcessName, DWORD sessionId)
{
//LaunchDebugger();
wchar_t* p = 0;
wchar_t* q = 0;
wchar_t* ProcessNameW = (wchar_t*)lpszProcessName;
DWORD processId = 0;
wchar_t lowerCaseInputProcess[512];
ZeroMemory(lowerCaseInputProcess, sizeof(lowerCaseInputProcess));
//Convert InputProcess to lower case
p = ProcessNameW;
q = lowerCaseInputProcess;
for (; *p; ++p, ++q) * q = tolower(*p);
//wprintf(L"Target:%s\n", lowerCaseInputProcess);
NTSTATUS status;
PVOID buffer;
PSYSTEM_PROCESS_INFO spi;
buffer = VirtualAlloc(NULL, 1024 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // We need to allocate a large buffer because the process list can be large.
if (!buffer)
{
// Report(L"\nError: Unable to allocate memory for process list: %d\n", GetLastError());
return -1;
}
//Report(L"\nProcess list allocated at address %#x\n", buffer);
spi = (PSYSTEM_PROCESS_INFO)buffer;
if (!NT_SUCCESS(status = NtQuerySystemInformation(SystemProcessInformation, spi, 1024 * 1024, NULL)))
{
//Report(L"\nError: Unable to query process list (%#x)\n", status);
VirtualFree(buffer, 0, MEM_RELEASE);
return -1;
}
wchar_t imageName[512];
wchar_t lowerCaseImageName[512];
cout << "ok";
while (spi->NextEntryOffset)
{
// Loop over the list until we reach the last entry.
//The following wsprintf is necessary because any access , include wcslen , other than wprintf causes an exception
//So copied buffer to another buffer for further processing.
//Report(lowerCaseImageName, L"%s", spi->ImageName.Buffer);
cout << spi->ImageName.Buffer << endl;
p = spi->ImageName.Buffer;
q = lowerCaseImageName;
ZeroMemory(lowerCaseImageName, sizeof(lowerCaseImageName));
if (p) {
for (; *p; ++p, ++q) * q = tolower(*p);
}
//Compare Names
if ((StrCmpCW(lowerCaseInputProcess, lowerCaseImageName)) == 0) {
processId = (DWORD)spi->ProcessId;
DWORD dwSessionId = 0;
if (ProcessIdToSessionId(processId, &dwSessionId))
{
if (sessionId == dwSessionId) {
//Report(L"Found a Match:%s\d", processId);
VirtualFree(buffer, 0, MEM_RELEASE); // Free the allocated buff
return processId;
}
}
}
spi = (PSYSTEM_PROCESS_INFO)((LPBYTE)spi + spi->NextEntryOffset); // Calculate the address of the next entry.
}
processId = 0;
VirtualFree(buffer, 0, MEM_RELEASE); // Free the allocated buffer.
return processId;
}
BOOL CProcessManager::CreateProcessWithToken(HANDLE hToken, LPCWSTR lpszCommandLine, DWORD* dwProcessId)
{
_ltow_s((long)hToken, buffer, len, 10);
wstring entry = wstring(L"CreateProcessWithToken:");
entry += lpszCommandLine;
Report(entry.c_str(), buffer);
// By default CreateProcessAsUser creates a process on a non-interactive window station, meaning
// the window station has a desktop that is invisible and the process is incapable of receiving
// user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
// interaction with the new process.
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.lpDesktop = L"winsta0\\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop
// flags that specify the priority and creation method of the process
UINT dwCreationFlags = (int)(NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE);
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
LPWSTR szCmdLine = _tcsdup(lpszCommandLine);
Report(szCmdLine);
//LPCWSTR commandLine = CharToWideChar(lpszCommandLine);
// MessageBox(0, lp, L"Path", MB_OK);
BOOL result = CreateProcessAsUser(hToken, // client's access token
0, // command line
szCmdLine, // file to execute
&sa, // pointer to process SECURITY_ATTRIBUTES
&sa, // pointer to thread SECURITY_ATTRIBUTES
0, // handles are not inheritable
dwCreationFlags, // creation flags
0, // pointer to new environment block
0, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
);
if (!result) {
//_ltow_s((DWORD)GetLastError(), buffer, len, 10);
//MessageBoxA(0, "OpenProces Returned Null",buffer, MB_OK);
Report(L"CreateProcessAsUser Returned Null. Error:%d", GetLastError());
}
*dwProcessId = pi.dwProcessId;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return result;
}
BOOL CProcessManager::CopyPrivileges(HANDLE hTokenSrc, HANDLE hTokenDst)
{
_ltow_s((long)hTokenSrc, buffer, len, 10);
wstring entry = wstring(buffer);
_ltow_s((long)hTokenDst, buffer, len, 10);
entry += wstring(L":") + wstring(buffer);
Report(L"CopyPrivileges: Original Tokens:%s", entry.c_str());
hTokenSrc = GetImpersonationToken(hTokenSrc);
hTokenDst = GetImpersonationToken(hTokenDst);
_ltow_s((long)hTokenSrc, buffer, len, 10);
entry = wstring(buffer);
_ltow_s((long)hTokenDst, buffer, len, 10);
entry += wstring(L":") + wstring(buffer);
Report(L"CopyPrivileges: Impersonated Tokens:%s", entry.c_str());
TOKEN_PRIVILEGES Priv;
ZeroMemory(&Priv, sizeof(Priv));
DWORD dwLen = 0;
GetTokenInformation(hTokenSrc, TokenPrivileges, &Priv, sizeof(TOKEN_PRIVILEGES), &dwLen);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
/**///)
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"GetTokenPrivileges First Call Failed with Error:%d", GetLastError());
return(0);
}
//_ltow_s(dwLen, buffer, len, 10);
Report(L"GetTokenPrivileges Buffer size:%d", dwLen);
PTOKEN_PRIVILEGES pPriv = (PTOKEN_PRIVILEGES)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLen * 10);
if (!GetTokenInformation(hTokenDst, TokenPrivileges, (LPVOID)pPriv, dwLen * 10, &dwLen)) {
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"GetTokenPrivileges Failed with Error:%d", GetLastError());
return(0);
}
//_ltow_s(pPriv->PrivilegeCount, buffer, len, 10);
Report(L"Privilege Count:%d", pPriv->PrivilegeCount);
if (!AdjustTokenPrivileges(hTokenDst, FALSE, pPriv, dwLen, NULL, NULL)) {
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"AdjustTokenPrivileges Failed with Error:%d", GetLastError());
return false;
}
LUID luid;
ZeroMemory(&luid, sizeof(luid));
if (!LookupPrivilegeValue(0, SE_TCB_NAME, &luid))
{
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"LookupPrivilegeValue Failed with Error:%d", GetLastError());
return false;
}
TOKEN_PRIVILEGES tp;
ZeroMemory(&tp, sizeof(tp));
tp.PrivilegeCount = 1;
tp.Privileges->Luid.HighPart = luid.HighPart;
tp.Privileges->Luid.LowPart = luid.LowPart;
DWORD dwReturn = 0;
if (!AdjustTokenPrivileges(hTokenDst, SE_PRIVILEGE_ENABLED, &tp, sizeof(tp), 0, &dwReturn))
{
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"AdjustTokenPrivileges for TCB_NAME Failed with Error:%d", GetLastError());
return false;
}
Report(L"Adjust Privileges Succeeded");
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
if (!SetTokenInformation(hTokenDst, TokenSessionId, &dwSessionId, sizeof(dwSessionId)))
{
//_ltow_s(GetLastError(), buffer, len, 10);
Report(L"SetTokenInformation Failed with Error:%d", GetLastError());
return false;;
}
Report(L"SetTokenInformation succeded");
return true;
}
Continue reading...