Why Query with SM_REMOTESESSION succeeds but WTSIsRemoteSession fails? - winapi

I am using a free application virtualization app - Winflector.
When I use GetSystemMetrics(SM_REMOTESESSION) the function correctly detects that application is running in a remote session, however, WTSQuerySessionInformationA() fails to detect and thus cannot get WTSClientInfo. I want to know, what is difference in the functionalities of these APIs. Also, I am interested in knowing how can I programmatically detect client Side information when running through these kind of applications.
if (GetSystemMetrics(SM_REMOTESESSION)) //passes
printf("\n\n\tSM_REMOTESESSION says this application is running in a remote session \n");
if (WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSIsRemoteSession, &pData, &bytesReturned)){ //fails
}
Also wanted to know if there is a possibility that these kind of applications may employ virtual channels (or dynamic virtual channels) infrastructure of windows?

Related

How to prevent my process from CreateToolhelp32Snapshot?

Is there a way to prevent another process from detecting my process by using CreateToolhelp32Snapshot?
If you are in a environment where you need to protect users from themselves then these users need to be non-admin users and you can simply create a service or task that runs as a different user so it cannot be killed.
If you absolutely need to hide the process and your chosen method is injection & hooking then there are at least 6 things you need to hook in user-mode:
The toolhelp API
The NT4 process API in psapi.dll
The undocumented native NT API
The terminal server API
Performance counters
WMI
A "better" solution is to remove your process from the PsActiveProcessHead list but you need to be in kernel-mode to do that and that means writing a custom driver. If you go down this route your program will be labeled as malware/rootkit by some security tools (and rightly so).

Is a serviced component shared between user sessions on a terminal server, or is one process started for each user session?

I have some .NET code in a COM+/Enterprise Services serviced component. I communicate with this component from a WPF application and also from a legacy VBA application.
This arrangement works well when only one user is logged on to a machine. The component starts in its own process when either the .NET or the legacy application instantiates one of its COM objects.
The system also works for the first user to try to run it on a terminal server installation. However, when another user logs on, he/she is unable to use the application. I had hoped that each session would run in isolation, and that one host process would run per session. Am I wrong in this expectation?
In Component Services on the Activation tab my application is configured to run as a "Server application". On the Identity tab, "Interactive user" is selected. On the Security tab, "Enforce access checks for this application" is unchecked.
There isn't session isolation as you describe, instead process ownership limits what you have access to.
Your conclusion seems correct & you will need to determine a suitable mechanism to exchange data with the service.
I used WCF to create a service with a net named pipe listener https://learn.microsoft.com/en-us/dotnet/framework/wcf/index
The idea of using proxies to make rpc calls is attractive, but I found the proxy definitions and stubs to link it all together quite clumsy to use.
If you have events that may be triggered at either end then keeping client/service in sync becomes problematic.
AIUI you cannot invoke a rpc method that ends up invoking an rpc back at the originating end, although that could be a named pipe limitation.
If I was doing this again I would use a socket server in the service & the websocket protocol for biderectional data transfer, even though you might need to implement some thread handling to avoid the listener thread blocking whilst servicing requests.
Hard to find anything authoritative on this. For standard COM you can set the identity to 'Launching user'. The same is not available for COM+.
According to this archived post,
A COM+ application can be configured to run under the logged in account, or
a specified account. Under the application properties, see the Identity tab.
...
Once set however, it remains under that account until the application shuts
down, so you can't have multiple users using the same COM+ application under
different IDs.
That seems to match what is said in this knowledge base article too.
My conclusion is, I should probably accept that my component must run once per machine rather than once per session. It will need to be modified to accommodate this. Since it needs to start new processes in individual sessions, it will have to run as a Windows service under the Local System account (giving due attention to the security implications).

Sending Password to Remote Computer at Login Screen [Windows 7]

I have written a piece of software that allows you to control computers remotely and one of its functions is to turn on all the computers that it controls via Magic Packets.
Due to the restrictions of Network Drives and the need for passwords on accounts, I have run into an issue.
When the computers boot, I am stuck at the login screen on each computer and must walk around manually and type in the passwords.
Is there anyway that I can send the passwords to the individual computers or have the computers log themselves in?
You probably want to install your program as a Service. You'll set its startup to automatic, which means it'll start up and run automatically when the computer is started up, even without a user being logged in.
Note that it's also possible to set a Service's startup to Boot. You probably want to avoid this though. Boot startup is primarily for device drivers, not normal services. It runs much earlier in the boot process. You don't need (or probably want) that -- you just want it to run roughly when the system would be ready for somebody to log in if they chose.
I'd also note that a service is (normally) written slightly differently from a normal program. It has a Windows-style event loop, but responds to a different set of "messages" that start the service, stop the service, pause the service, and so on. Most of it isn't terribly difficult but it is somewhat different from a normal program.

Starting an Application from Windows Service

I am building a Windows service that will watch for specific occurrences of events and disk activity. When such an event occurs my plan is to alert the user to the event via a client app, and provide remediation if necessary. I have (mostly) completed both the client and service components, which work great... unless the client app isn't running.
In short, I am looking for a way to start up the client app from the Windows service via CreateProcess to provide information to the user. However, it appears the service can't even see the file/folder of the client app to execute it. I suspect this is due to the credentials under which the service is running, or maybe due to service level restrictions, but wanted to reach out for some advise before I get into this any deeper.
So, the obvious question first... am I thinking about this clearly? Is the architecture plan sound, or should I look at another method? I would prefer not to re-do any of the work I have already completed, but obviously want to make sure the plan and process is solid.
Question #2, what are the limitations I face with this model? Is there a service account that will allow this level of access?
I am obviously struggling with this right now, so any thoughts or assistance will be greatly appreciated!
Thanks,
Kris
As others have mentioned already, you can't (easily) launch an application directly from the service, so I think the easiest way around the problem is to create a process that starts on login and runs with the credentials of the logged in user, eg an app that sits in the system tray, and it opens up a named pipe or a network port to the service. If the service needs to alert the user, it sends a message down that channel and then the client process can either show its own UI or launch an application. Interprocess communication using pipes or ports are the simplest way to deal with the restrictions on session 0 processes.
A Windows service does not have access to the user session in Vista and above, so it is blocked from starting an executable on that session. You can download a white paper from Microsoft that goes into detail: Impact of Session 0 Isolation on Services and Drivers in Windows.
Since Vista, services run in session 0 and the user's desktop is always in a different session. Thus you need to work hard to start a service on the user's desktop.
It can be done but it is pretty tricky. Details can be found here: http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx?wa=wsignin1.0

session0 isolation in Windows 2008/windows7

I have a C++ application which used Mutex, Events,Semaphores for synchronization. While hosted in windows 2008 server/Windows 7, this application is not starting from a remote client.
I used telnet client to connect remotely to this application and saw that telnet server is running under session 0 and therefore it is trying to start my application under session 0. My application is trying call OpenMutex to open a mutex which was created by another application running locally (in session 1).
I can make my application work by perpending "Global\" to mutex name. What I am looking for is a way run application without making this code change. Is it even possible? Is it possible to launch telnet service under session 1.
CreateMutex(&sa,FALSE,Buffer, "MyMutexName"));
I can modify this to CreateMutex(&sa,FALSE,SYS_ID2(szSysIdBuffer, "Global\MyMutexName")); but is there any other way other that making this change.
Thanks
You probably know the document http://www.microsoft.com/whdc/system/sysinternals/session0changes.mspx which describes problems with the Session 0 isolation. The old way to make a service interactive which are described in http://msdn.microsoft.com/en-us/library/ms683502.aspx not works on Widows 7 because Terminal Services are active per default.
So it seems to me that in your case the way with the "Global\" prefix, which you currently use, is really the best one. To understand the complexity of an other possible way you can read following Process with administrative privileges run on user logon.

Resources