F
FLASHCODER
Guest
I have a service application and want from this service (that is executed under NT AUTHORITY\SYSTEM account after your installation and computer reboot) execute a application.exe also in NT AUTHORITY\SYSTEM account.
Already tried several codes including a routine (LaunchAppIntoDifferentSession();) found in this article that take (or at least try obtain) the token of winlogon.exe, but notthing worked, the "application.exe" not appear in any place.
Some idea of solution to this my case?
Here was the last attempt:
#include "stdafx.h"
#include <Windows.h>
#include <WtsApi32.h>
#include <UserEnv.h>
#include <tlhelp32.h>
#include <winternl.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib,"WtsApi32.lib")
#pragma comment(lib,"UserEnv.lib")
#define MY_SERVICE_NAME "MyService"
#define MY_SERVICE_DESCRIPTOR "MyService description"
#define MY_SERVICE_BIN_NAME "MyService.exe"
#define MY_APPLICATION_BIN_NAME "application.exe"
BOOL InstallMyService()
{
char strDir[MAX_PATH + 1];
SC_HANDLE schSCManager;
SC_HANDLE schService;
LPCTSTR lpszBinaryPathName;
GetCurrentDirectory(MAX_PATH, strDir);
strcat(strDir, "\\"MY_SERVICE_BIN_NAME);
if ((schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL)
return (TRUE);
lpszBinaryPathName = strDir;
schService = CreateService(schSCManager, MY_SERVICE_NAME, MY_SERVICE_DESCRIPTOR,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
lpszBinaryPathName, NULL, NULL, NULL, NULL, NULL);
if (schService == NULL)
return (FALSE);
if (schService)
{
StartService(schService, 0, NULL);
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return (TRUE);
}
BOOL DeleteMyService()
{
SC_HANDLE schSCManager;
SC_HANDLE hService;
if ((schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL)
return (FALSE);
if ((hService = OpenService(schSCManager, MY_SERVICE_NAME, SERVICE_ALL_ACCESS)) == NULL)
return (FALSE);
if (!DeleteService(hService))
return (FALSE);
if (!CloseServiceHandle(hService))
return (FALSE);
if (!CloseServiceHandle(schSCManager))
return (FALSE);
return (TRUE);
}
SERVICE_STATUS g_ServiceStatus;
SERVICE_STATUS_HANDLE g_ServiceStatusHandle;
BOOL bRunning = true;
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
switch (Opcode)
{
case SERVICE_CONTROL_PAUSE:
g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
bRunning = false;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
}
ULONG cup();
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
g_ServiceStatus.dwServiceType = SERVICE_WIN32;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
g_ServiceStatusHandle = RegisterServiceCtrlHandler(MY_SERVICE_NAME, ServiceCtrlHandler);
if (g_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
return;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
cup();
bRunning = true;
while (bRunning)
{
Sleep(3000);
}
}
#define LAA(se) {{se},SE_PRIVILEGE_ENABLED|SE_PRIVILEGE_ENABLED_BY_DEFAULT}
#define BEGIN_PRIVILEGES(tp, n) static const struct {ULONG PrivilegeCount;LUID_AND_ATTRIBUTES Privileges[n];} tp = {n,{
#define END_PRIVILEGES }};
#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L)
#define SE_INCREASE_QUOTA_PRIVILEGE (5L)
ULONG adjustPrivileges()
{
HANDLE hToken;
ULONG err;
if (OpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
BEGIN_PRIVILEGES(tp, 2)
LAA(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE),
LAA(SE_INCREASE_QUOTA_PRIVILEGE),
END_PRIVILEGES
AdjustTokenPrivileges(hToken, FALSE, (PTOKEN_PRIVILEGES)&tp, 0, 0, 0);
err = GetLastError();
CloseHandle(hToken);
}
else
{
err = GetLastError();
}
return err;
}
ULONG cup()
{
HANDLE hUserToken;
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
if (dwSessionId == MAXDWORD)
{
return ERROR_GEN_FAILURE;
}
ULONG err = adjustPrivileges();
if (err)
{
return err;
}
if (WTSQueryUserToken(dwSessionId, &hUserToken))
{
PVOID pEnv;
if (CreateEnvironmentBlock(&pEnv, hUserToken, TRUE))
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(STARTUPINFO) };
si.lpDesktop = "winsta0\\default";
char strDir[MAX_PATH + 1];
GetCurrentDirectory(MAX_PATH, strDir);
strcat(strDir, "\\"MY_APPLICATION_BIN_NAME);
if (CreateProcessAsUser(
hUserToken,
strDir,
NULL,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT | HIGH_PRIORITY_CLASS,
pEnv,
NULL,
&si,
&pi
))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
{
err = GetLastError();
}
DestroyEnvironmentBlock(pEnv);
}
else
{
err = GetLastError();
}
CloseHandle(hUserToken);
}
else
{
err = GetLastError();
}
return err;
}
int main(int argc, char* argv[])
{
if (argc > 1)
{
if (!strcmp(argv[1], "-i"))
if (InstallMyService())
printf("\nService correctly installed\n");
else
printf("\nService uncorrectly installed\n");
else if (!strcmp(argv[1], "-d"))
if (DeleteMyService())
printf("\nService correctly deleted\n");
else
printf("\nService uncorrectly deleted\n");
}
else
{
SERVICE_TABLE_ENTRY DispatchTable[] = { { MY_SERVICE_NAME, ServiceMain }, { NULL, NULL } };
StartServiceCtrlDispatcher(DispatchTable);
}
//getchar();
return (EXIT_SUCCESS);
}
The final goal is be able (like Team View software) to seen any active desktop (including UAC and WinLogon) making screenshots from of "application.exe".
Continue reading...
Already tried several codes including a routine (LaunchAppIntoDifferentSession();) found in this article that take (or at least try obtain) the token of winlogon.exe, but notthing worked, the "application.exe" not appear in any place.
Some idea of solution to this my case?
Here was the last attempt:
#include "stdafx.h"
#include <Windows.h>
#include <WtsApi32.h>
#include <UserEnv.h>
#include <tlhelp32.h>
#include <winternl.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib,"WtsApi32.lib")
#pragma comment(lib,"UserEnv.lib")
#define MY_SERVICE_NAME "MyService"
#define MY_SERVICE_DESCRIPTOR "MyService description"
#define MY_SERVICE_BIN_NAME "MyService.exe"
#define MY_APPLICATION_BIN_NAME "application.exe"
BOOL InstallMyService()
{
char strDir[MAX_PATH + 1];
SC_HANDLE schSCManager;
SC_HANDLE schService;
LPCTSTR lpszBinaryPathName;
GetCurrentDirectory(MAX_PATH, strDir);
strcat(strDir, "\\"MY_SERVICE_BIN_NAME);
if ((schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL)
return (TRUE);
lpszBinaryPathName = strDir;
schService = CreateService(schSCManager, MY_SERVICE_NAME, MY_SERVICE_DESCRIPTOR,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
lpszBinaryPathName, NULL, NULL, NULL, NULL, NULL);
if (schService == NULL)
return (FALSE);
if (schService)
{
StartService(schService, 0, NULL);
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return (TRUE);
}
BOOL DeleteMyService()
{
SC_HANDLE schSCManager;
SC_HANDLE hService;
if ((schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL)
return (FALSE);
if ((hService = OpenService(schSCManager, MY_SERVICE_NAME, SERVICE_ALL_ACCESS)) == NULL)
return (FALSE);
if (!DeleteService(hService))
return (FALSE);
if (!CloseServiceHandle(hService))
return (FALSE);
if (!CloseServiceHandle(schSCManager))
return (FALSE);
return (TRUE);
}
SERVICE_STATUS g_ServiceStatus;
SERVICE_STATUS_HANDLE g_ServiceStatusHandle;
BOOL bRunning = true;
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
switch (Opcode)
{
case SERVICE_CONTROL_PAUSE:
g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
bRunning = false;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
}
ULONG cup();
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
g_ServiceStatus.dwServiceType = SERVICE_WIN32;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
g_ServiceStatusHandle = RegisterServiceCtrlHandler(MY_SERVICE_NAME, ServiceCtrlHandler);
if (g_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
return;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatus.dwCheckPoint = 0;
g_ServiceStatus.dwWaitHint = 0;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
cup();
bRunning = true;
while (bRunning)
{
Sleep(3000);
}
}
#define LAA(se) {{se},SE_PRIVILEGE_ENABLED|SE_PRIVILEGE_ENABLED_BY_DEFAULT}
#define BEGIN_PRIVILEGES(tp, n) static const struct {ULONG PrivilegeCount;LUID_AND_ATTRIBUTES Privileges[n];} tp = {n,{
#define END_PRIVILEGES }};
#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L)
#define SE_INCREASE_QUOTA_PRIVILEGE (5L)
ULONG adjustPrivileges()
{
HANDLE hToken;
ULONG err;
if (OpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
BEGIN_PRIVILEGES(tp, 2)
LAA(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE),
LAA(SE_INCREASE_QUOTA_PRIVILEGE),
END_PRIVILEGES
AdjustTokenPrivileges(hToken, FALSE, (PTOKEN_PRIVILEGES)&tp, 0, 0, 0);
err = GetLastError();
CloseHandle(hToken);
}
else
{
err = GetLastError();
}
return err;
}
ULONG cup()
{
HANDLE hUserToken;
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
if (dwSessionId == MAXDWORD)
{
return ERROR_GEN_FAILURE;
}
ULONG err = adjustPrivileges();
if (err)
{
return err;
}
if (WTSQueryUserToken(dwSessionId, &hUserToken))
{
PVOID pEnv;
if (CreateEnvironmentBlock(&pEnv, hUserToken, TRUE))
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(STARTUPINFO) };
si.lpDesktop = "winsta0\\default";
char strDir[MAX_PATH + 1];
GetCurrentDirectory(MAX_PATH, strDir);
strcat(strDir, "\\"MY_APPLICATION_BIN_NAME);
if (CreateProcessAsUser(
hUserToken,
strDir,
NULL,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT | HIGH_PRIORITY_CLASS,
pEnv,
NULL,
&si,
&pi
))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
{
err = GetLastError();
}
DestroyEnvironmentBlock(pEnv);
}
else
{
err = GetLastError();
}
CloseHandle(hUserToken);
}
else
{
err = GetLastError();
}
return err;
}
int main(int argc, char* argv[])
{
if (argc > 1)
{
if (!strcmp(argv[1], "-i"))
if (InstallMyService())
printf("\nService correctly installed\n");
else
printf("\nService uncorrectly installed\n");
else if (!strcmp(argv[1], "-d"))
if (DeleteMyService())
printf("\nService correctly deleted\n");
else
printf("\nService uncorrectly deleted\n");
}
else
{
SERVICE_TABLE_ENTRY DispatchTable[] = { { MY_SERVICE_NAME, ServiceMain }, { NULL, NULL } };
StartServiceCtrlDispatcher(DispatchTable);
}
//getchar();
return (EXIT_SUCCESS);
}
The final goal is be able (like Team View software) to seen any active desktop (including UAC and WinLogon) making screenshots from of "application.exe".
Continue reading...