Interacting with Services

In the comments for my first services post, someone asked about the SERVICE_INTERACTIVE_PROCESS flag that can be specified for the CreateService API.

This flag allows the user to specify that the service should be allowed to interact with the logged on user.  The idea of an interactive service was added back in NT 3.1 for components like printer drivers that want to pop up UI.

IMHO this was a spectacularly bad idea that should never have been added to the system.

MSDN has an entire page on interactive services, unfortunately IMHO, it doesn't go into enough detail as to why it's a bad idea to ever specify the SERVICE_INTERACTIVE_PROCESS flag on a service.

The primary reason for this being a bad idea is that interactive services enable a class of threats known as "Shatter" attacks (because they "shatter windows", I believe). 

If you do a search for "shatter attack", you can see some details of how these security threats work.  Microsoft also published KB article 327618 which extends the documentation about interactive services, and Michael Howard wrote an article about interactive services for the MSDN Library.  Initially the shatter attacks went after windows components that had background window message pumps (which have long been fixed), but they've also been used to attack 3rd party services that pop up UI.

The second reason it's a bad idea is that the SERVICE_INTERACTIVE_PROCESS flag simply doesn't work correctly.  The service UI pops up in the system session (normally session 0).  If, on the other hand, the user is running in another session, the user never sees the UI.  There are two main scenarios that have a user connecting in another session - Terminal Services, and Fast User Switching.  TS isn't that common, but in home scenarios where there are multiple people using a single computer, FUS is often enabled (we have 4 people logged in pretty much all the time on the computer in our kitchen, for example).

The third reason that interactive services is a bad idea is that interactive services aren't guaranteed to work with Windows Vista :)  As a part of the security hardening process that went into Windows Vista, interactive users log onto sessions other than the system session - the first interactive user runs in session 1, not session 0.  This has the effect of totally cutting shatter attacks off at the knees - user apps can't interact with high privilege windows running in services. 


On the other hand, sometimes it's important to interact with the logged on user.  How do you deal with this problem?  There are a couple of suggestions as to how to resolve the issue.  The first is to use the CreateProcessAsUser API to create a process on the users desktop.  Since the new process is running in the context of the user, privilege elevation attacks don't apply.  Another variant of this solution is to use an existing systray process to communicate with the service.

In addition, if a COM object is marked as running in the security context of the interactive user, it will be activated in the interactive user's session.  You can use a session moniker to start a COM object in a particular session.  There's an example of how to do this here.