Service Security in Windows Vista
After a long break from blogging due to holidays and a heavy workload, I've finally got round to writing something new. To follow on from my last post on File and Registry Virtualisation, I thought I'd take a look at another Vista security-related topic: Service Security.
Services generally run with elevated privileges and are therefore very attractive targets for hackers looking for ways to elevate their own privilege level. In Windows Vista several key changes help reduce the security risk when using system services. Important changes are:
Session 0 Isolation
Previously Windows services would all run in the same session as the first user who logged on to the console. This session is called Session 0.
Running services and user applications together in Session 0 poses a security risk. Some services have visible and invisible windows and dialogs that the user or other processes can interact with directly using mouse input or programmatically via window messages. This makes them vulnerable to certain attacks such as the so-called Shatter Attack.
Vista mitigates the risk by isolating system services in Session 0 and making Session 0 non-interactive; in Vista, only system processes and services run in Session 0 and the first user logs on to Session 1. Subsequent users log on to sessions 2, 3 ,4 , etc. This means that services never run in the same session as user applications and are therefore protected against attacks from malicious user-mode code.
Figure 1 shows an example service, RegAlert, running on Windows XP. This service monitors a specific registry value and will display a dialogue box to the user when the contents change. In XP, the console user sees the dialogue and can interact with it easily, but as I mentioned this means that malware can also interact with it. Since users and system services no longer "live" in the same session in Vista, this dialogue is not visible to the console user on a Vista system (though there is a workaround, that I'll discuss shortly).
Figure 1: Service dialogue shown on the XP user desktop
Consequences of Session 0 Isolation
Any service (or service-hosted driver) that assumes the user is running in Session 0 won't work correctly in Windows Vista. Some examples of where this is potentially a problem are:
As mentioned above, any service that assumes the user is in the same session is going to have problems interacting with users. Services that show dialogs like this should use alternative methods; for example, use the Terminal Services APIs such as WTSSendMessage to send messages to the appropriate session or use CreateProcessAsUser to create a new process in the user’s session.
If a services and applications use window message functions such as SendMessage and PostMessage to interact they are not going to work as the session isolation means they will have isolated message queues.
Using Named Objects
For services running in Session 0, named objects they create are usually in the \BaseNamedObjects\ namespace. However, user applications that try to open these objects using the default Local\ prefix are going to have problems as the objects are not local to the user session as they were in XP. The proper thing to do here is to create the object with the explicit Global\ prefix.
In actual fact these implications for services are also a problem with Fast User Switching (FUS) in Windows XP because FUS users all run in different sessions. Services that assume that the user is running in Session 0 encounter the same issues as above when subsequent users log on using FUS. Services that work fine with FUS are likely to be ok in Vista, but should be thoroughly tested before migration.
Interactive Service Detection Service
To help work with legacy services that send dialogue boxes to the Session 0 desktop a new system service, the Interactive Service Detection Service (UI0Detect), is available.
The UI0Detect service notifies the user when a dialogue box or window appears in Session 0. Information about each of the last ten dialogue boxes will appear in turn.
Figure 2 shows the RegAlert service running on a Vista system. This time, the dialogue is not displayed to the user; instead the UI0detect shows its own dialogue detailing the service that wants to interact with the user.
Figure 2: UI0detect service alerts the user that a dialogue was shown in Session 0
At this point users can:
• Respond to the dialogue box immediately by clicking the "Show me the message" button to switch to Session 0, interact with the dialogue box, then switch back to their session.
• Be reminded again in 5 minutes. They will continue to be reminded until the dialogue box closes.
Figure 3 shows what the user will see if they select the "Show me the message" option shown in Figure 2. The user can then interact with the dialogue as they would in XP, but the critical difference is that other applications running on the user's desktop are prevented from any interaction.
Figure 3: the Session 0 desktop showing the service dialogue
The UI0detect service can notify users logged on at the physical machine or via Remote Desktop.
Windows Vista now runs many services under accounts that have a lower level of privilege than the LocalSystem account that was typically used in previous Windows versions. In addition, service developers (and administrators) can have their service declare to the Service Control Manager (SCM) which privileges they actually need and the SCM then gives the service a “filtered” token, with just those privileges. This means that even if the service is compromised the rights gained by the hacker are limited to only those the service uses and not the full set granted to LocalSystem, for example.
Administrators can use the built-in SC command to manage the privileges of a given service, so that legacy services (which don’t declare their privilege needs), can also be restricted:
Querying Service Privileges
The privileges allowed to a particular service can be queried using the qprivs option:
SC [server] qprivs [service name]
Figure 4: Showing the privileges allowed for the Windows Installer Service
Setting Service Privileges
The privileges allowed to a particular service can be set using the privs option:
SC [server] privs [service name] [privilege1/privilege2/...]
For example, to allow the Windows Installer service on the local system only the "act as part of the operating system" and "debug programs" rights, use this command:
SC privs msiserver SeTcbPrivilege/SeDebugPrivilege
Or, to clear all privileges set for the Windows Installer, use this command:
SC privs msiserver /
The privileges for a particular service can be set programmatically using the ChangeServiceConfig2 API and are stored in clear text here in the registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<service name>\ RequiredPrivileges
Figure 5: Windows Installer service privileges shown in the registry
The final tool available for securing services is the ability to restrict object access for system services as if the service itself is a user - this is known as Service Isolation. In Vista, the SCM can create a new Security Identifier (SID) for the service itself (hence, it's called a per-service SID). That is, the service will have a new, unique, SID that can be used to grant/deny it permissions to files, etc regardless of the account the service runs under.
The SCM adds the service SID to the security token used when the service is running and it is possible for Administrators to apply a blanket restriction on any “write” operations by the service by setting the SID type.
The SID type can be:
NONE - new SID type is not used
RESTRICTED - SID is restricted from writing to files, registry, etc unless explicitly granted access
UNRESTRICTED - new SID is created and added to the token, but write operations are not automatically restricted
Again this setting can be managed with the SC command:
Viewing the Current SID Type
To query the current type of the service SID, use this command:
SC [server] qsidtype [service name]
Figure 6: Showing the SID type for the RegAlert service
Setting the SID Type
To set the SID type, use this command:
SC [server] sidtype [service name] [none|restricted|unrestricted]
Once the SID is restricted, the service will not be able to write to any resources. Administrator can then use normal file/registry permissions to allow the service access to only the resources they want it to access.
Figure 7: File permissions for the RegAlert service
This is just a brief look at a couple of changes I found interesting. For more detail on these and other improvements, have a look at these documents: