Based on my earlier posts, I've recently written a whitepaper for Microsoft France on how to build a machine that is capable of dual booting either Linux or Windows Vista when the latter is protected by BitLocker leveraging a TPM chip.
If you understand French, you' ll find the whitepaper, a webcast where I describe the steps and a video showing all the process and test of the final result on Microsoft's France interoperability website (http://www.microsoft.com/france/interop). To directly access the file please go to http://www.microsoft.com/france/interop/themes/infrastructure/20080430-dualboot-linux-bitlocker/default.mspx.
The video ("Partie2") is annotated with French callouts but it should be easy to understand even to non French speaking people. Here are the different sequences you can watch (the file embeds markers to jump directly to the different sections) :
0’00”: Linux OpenSuse install

4’28”: GRUB install out of MBR, on the Linux partition; get a copy of Linux boot sector


6’22”: Windows Vista install



10’54”: add an entry for Linux/GRUB in Windows Vista Boot Manager, using bcdedit tool

13’11”: boot test with Linux BEFORE enabling BitLocker; NTFS partitions mount

15’09”: enable TPM in BIOS

15’32”: BitLocker enablement with TPM from Windows Vista





22’38”: boot test with Linux AFTER Bitlocker was enabled using a TPM; NTFS partitions mount fails

24’18”: boot test with Windows VistaAFTER BitLocker was enabled using a TPM; visualize partition with DiskScape tool


25’23”: add entry for Boot Manager in GRUB
26’32”: secure startup test launching machine through Boot Manager then GRUB then Boot Manager



27’20”: secure startup test using a bootable DVD in startup chain
(This is part 5 of our series of posts on service hardening.)
Last but not least a service can be (and should be) configured to have network restrictions with what is called the "Windows Service Hardening" rules in the Windows SDK (we'll call those WSH rules for short). As a service developer, it is your responsibility to setup those rules during the installation and configuration of your service. Why? Because you know what network access (if any) your service needs, and by setting up WSH rules you can make sure your service will only get access to network ports and protocols it needs, thus contributing to the overall defense of the system and the environment.
What is different with those WSH network rules and, let's say, the Windows Firewall with Advanced Firewall Security rules? Well, technically, it is reasonable to think that the WSH are evaluated and enforced by Windows Vista integrated firewall. However, from a functional standpoint, they are totally independent and separate:
· Once defined, WSH rules for your service are en forced no matter what the firewall configuration may be. The administrator may have turned off all firewalls, yet this won’t affect the WSH rules that you have setup.
· WSH network restrictions rules can only be used to restrict access, they cannot in any way grant access to a network resource that would not already be allowed by the firewall. WSH rules are evaluated first, before those of the firewall.
· WSH rules cannot be configured with the Windows Firewall with Advanced Security administration tools such as the WF.msc MMC snap-in or netsh. They can only be defined with the API. So once your service has been installed and the WSH rules put in place, there is no way (short of programming or scripting) an administrator may change them while administering the firewall.
As a service developer for Windows Vista and Longhorn server, it is a best practice to take advantage of the service network restriction mechanism and setup the WSH rules for your service. In addition, the network resources that your service needs should be documented so that the IT folks in charge of a deployment can configure the firewall accordingly.
To define WSH rules, one uses the INetFwServiceRestriction interface which can be used from C++ code or VB scripts. Calling the RestrictService method with the restrictService parameter set to TRUE creates two rules that will block all inbound and outbound network communication for your service. This is what the following script would do:
' Create the FwPolicy2 object.
Dim fwPolicy2
Set fwPolicy2 = CreateObject("HNetCfg.FwPolicy2")
' Get the Service Restriction object for the local firewall policy.
Dim ServiceRestriction
Set ServiceRestriction = fwPolicy2.ServiceRestriction
' Restrict a service
ServiceRestriction.RestrictService ServiceName, ProgramName, TRUE, FALSE
Those two rules can be seen in the WSH rules section of the registry (HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Configurable\System):
v2.0|Action=Block|Active=TRUE|Dir=Out|App=c:\mysvc\mysvc.exe|Svc=mysvc|Name=Outbound service restriction rule for mysvc|Desc=Block all outbound traffic from service mysvc|Edge=FALSE|
v2.0|Action=Block|Active=TRUE|Dir=In|App=c:\mysvc\mysvc.exe|Svc=mysvc|Name=Inbound service restriction rule for mysvc|Desc=Block all inbound traffic to service mysvc|Edge=FALSE|
Notice that those rules refer to the service specifically (by its short name) and affect only the service (and not other software components). Per-service SID (see our previous posts on service hardening) and WSH network restriction rules go hand in hand. If your service does not already have a per-service SID, the RestrictService API will configure it to have one. In addition, if your service is to be run write-restricted, you can set the serviceSidRestricted parameter to TRUE. This is convenient as it saves you from having to call ChangeServiceConfig2.
Imagine now that your service needs outbound network access on TCP port 8080, you can define the appropriate rules with the INetFwRule interface. The following script (in addition to the previous one would) would restrict the service for outbound communication on that port and protocol only:
Dim CurrentRule
set CurrentRule = CreateObject("HNetCfg.FwRule")
CurrentRule.Name = "MySvc network restriction"
CurrentRule.ApplicationName = ProgramName
CurrentRule.ServiceName = ServiceName
CurrentRule.Protocol = 6
CurrentRule.RemotePorts = 8080
CurrentRule.Direction = NET_FW_RULE_DIR_OUT
CurrentRule.Enabled = TRUE
ServiceRestriction.Rules.Add CurrentRule
The corresponding WSH service network restriction rules in the registry would be:
v2.0|Action=Allow|Active=TRUE|Dir=Out|Protocol=6|RPort=8080|App=c:\mysvc\mysvc.exe|Svc=mysvc|Name=Allow mysvc (c:\mysvc\mysvc.exe) outbound on port 8080|Edge=FALSE|
v2.0|Action=Block|Active=TRUE|Dir=Out|App=c:\mysvc\mysvc.exe|Svc=mysvc|Name=Outbound service restriction rule for mysvc|Desc=Block all outbound traffic from service mysvc|Edge=FALSE|
v2.0|Action=Block|Active=TRUE|Dir=In|App=c:\mysvc\mysvc.exe|Svc=mysvc|Name=Inbound service restriction rule for mysvc|Desc=Block all inbound traffic to service mysvc|Edge=FALSE|
What about Windows Vista native services? Well most of them have their own network restriction rules. Actually, the INetFwServiceRestriction and INetFwRule APIs cannot be used to configure restrictions for the OS native services. So network restrictions for native services are something fully static. It is configured once for all at the OS install (development?) time and cannot be changed. You may notice that while WSH rules are stored in the RestrictedServices\Configurable subkey, Windows Vista native services network restriction rules are stored separately in RestrictedServices\Static subkey.
(This is part 4 of our series of posts on service hardening.)
A service can be configured to be write-restricted, in addition to having a per-service SID. To do so, you specify a SID type of "Restricted" when configuring your service (see our previous post “Per-service SID”). In that case the process hosting your service will run with a (new to Windows Vista) "write-restricted" token.
Hmmm, what is this animal, and what does it mean?
You may have heard of (or maybe be familiar with) restricted tokens. There are several definitions for those, one of which is a token issued from the CreateRestrictedToken API. We like to think of restricted tokens as tokens that have Restricting SIDs. When the system evaluates access to a resource, if there are restricting SIDs, the evaluation is made with two independent passes. The first pass uses the User SID and the Group SIDs, and the second pass uses the Restricting SIDs. For access to be granted, both passes must succeed. What that means is that Restricting SIDs can only be used to restrain access that a user account would have to start with but not broaden it in any event. Another case of the recurring "always restrain, never broaden" scheme.
We see restricted tokens along with the S-1-5-12 Restricted Code SID as early attempts to run applications with lower privilege and were used by "Run As…" with the "Protect my computer and data from unauthorized program activity” checkbox (no longer in Vista). In addition to Windows SDK documentation, you may want to check out blogs from Aaron Margosis and Larry Osterman for comments on these topics as well as Keith Brown's Programming Windows Security.
A write-restricted token (new to Windows Vista) is one that is flagged as WRITE_RESTRICTED (have a look at winnt.h). With a write-restricted token, the evaluation of the Restricting SIDs is only effective for write access checks. So a write-restricted token can be seen as less restrictive than a restricted token which is restricted for all types of accesses, and not only writes.
The write-restricted token for a "Restricted" service will have the following restricting SIDs: the per-service SID, the logon SID, the Everyone SID, and the (new to Vista) write-restricted SID (S-1-5-33 or NT AUTHORITY\WRITE RESTRICTED). The per-service SID and the write-restricted SID are also added to the Group SIDs. What does that mean?
Let's try:
· Writes are only possible by virtue of the service SID, the logon SID, Everyone SID, or write-restricted SID, and not the service account nor its groups. Reads are unaffected.
· The write-restricted SID allows for granting access to write-restricted services as a class, without forehand knowledge of which services will be write-restricted.
· By default, the write-restricted service looses write access to a lot of resources it would normally have access to by virtue of its account and groups. Write access must be explicitly granted to the service SID, the logon SID, the write-restricted class, or Everyone to be possible.
While running your service as "Unrestricted" (see our previous post “Per-service SID”) allows you to protect your resources using the per-service SID, running your service as "Restricted" protects the system in the event your code would get compromised (how can that be? J). It is a measure of good citizenship: your code runs write-restricted and its impact on the system in case of an exploit is mitigated. Is it expensive? You bet it is. You have to determine all write accesses your code will need and make sure you explicitly grant that access to your service. Are there tools to do so? We don't know, please comment…
A built-in example
In Windows Vista, only a few services are natively provided as “write-restricted”. The
sc qsidtype MpsSvc
command will show you that the Windows Firewall service (MpsSvc, short for Microsoft Protection Service) is configured to be a “Restricted” service:
[SC] QueryServiceConfig2 SUCCESS
SERVICE_NAME: MpsSvc
SERVICE_SID_TYPE: RESTRICTED
A quick inspection with a tool showing security tokens, like Process Explorer, will confirm that this service is indeed using a write-restricted token. The Windows Firewall service is hosted in a svchost.exe process running with the Local Service account and which also contains other services: Base Filtering Engine, Diagnostic Policy Service, Windows Media Center Service Launcher, Performance Logs & Alerts.
The
icacls C:\Windows\System32\LogFiles\Firewall
command will return
NT SERVICE\MpsSvc:(OI)(F)
NT AUTHORITY\SYSTEM:(OI)(F)
BUILTIN\Administrators:(OI)(F)
NT SERVICE\TrustedInstaller:(I)(F)
NT SERVICE\TrustedInstaller:(I)(CI)(IO)(F)
NT AUTHORITY\SYSTEM:(I)(F)
NT AUTHORITY\SYSTEM:(I)(OI)(CI)(IO)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
BUILTIN\Users:(I)(RX)
BUILTIN\Users:(I)(OI)(CI)(IO)(GR,GE)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)
showing an explicit ACE granting full control to the MpsSvc service SID. This is used to protect this folder and its content, namely firewall logs. As the Windows Firewall service is a write-restricted service, the net result will be that except for this folder and its content, the service won’t be able to write anywhere else on the file system except places where Everyone can write (or that have an explicit write permission for NT AUTHORITY\WRITE RESTRICTED which we did not find. If you do, please share by posting a comment. Thank you).
The same reasoning was applied to the registry: the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy
key. Looking at its ACL shows inherited permissions granting full control to Administrators and System and read permission for Users on the key and its subkeys, full control for the owner of any subkey and explicitly grant full control for MpsSvc service on the key and its subkeys. As we’ll see in our next post, some subkeys here are used to apply network restrictions on services. Therefore, it is particularly interesting to protect those rules so that only the Windows Firewall service NT AUTHORITY\WRITE RESTRICTED, an Administrator or the System can modify or create them. Moreover, due to the use of a write-restricted token, the Windows Firewall service can only write in this part of the registry and nowhere else except on keys Everyone can write to (or that show an explicit write permission to NT AUTHORITY\WRITE RESTRICTED; so far, we don’t know any shipping with Windows Vista. If you find one please share with all of us by posting a comment. Thank you).
(This is part 3 of our series of posts on service hardening.)
Under Windows Vista/Longhorn Server, your service can now have its own SID (Security Identifier), which you can then use in ACLs to protect your service resources. You configure your service to be assigned a per-service SID during its installation with the ChangeServiceConfig2 API (dwInfoLevel= SERVICE_CONFIG_SERVICE_SID_INFO) or the sc.exe command with the sidtype verb. In either case, three values are possible:
None – 0x0
Unrestricted – 0x1
Restricted – 0x3
If you want your service to have a per-service SID (as covered in this blog post), you should use "Unrestricted" for the type of SID. This means setting the SERVICE_SID_INFO.dwServiceSidType to SERVICE_SID_TYPE_UNRESTRICTED (0x1) if you are using the API, or using the following syntax with sc.exe:
sc sidtype [service name] unrestricted
You can also query the current configuration of your service with:
sc qsidtype [service name]
We find the semantics "type of SID" is a little funny, but once you get used to it, it's okay. A type of SID "None" means your service will not have a per-service SID nor a write-restricted token. Currently this is the default configuration for a service: no per-service SID. A type of SID "Unrestricted" means your service will have a per-service SID. A type of SID "Restricted" means your service will have a per-service SID and also a "write-restricted" token (this is our next post).
When configured to have a per-service SID (i.e. type of SID either "Unrestricted" or "Restricted"), the service SID is computed as S-1-5-80-{SHA-1(service name in uppercase)} and added to the host process token. If you need to know what the SID is or would be for a given service name, you can use the
sc showsid [service name]
command. This can be done through the use of APIs as well.
Once you have configured your service to have a per-service SID, you can grant access to resources your service needs. Prior to Windows Vista, when running your service with a built-in account (Local Service or Network Service), granting access to a resource for your service meant granting access to the other services running with that account as well. To avoid that side effect, you had to run your service with a dedicated account. Now with the per-service SID mechanism of Windows Vista, you can use the built-in service accounts while benefiting from the higher granularity of the per-service SID and thus ACL resources for your service only. When using the ACL editor (either on the file system, or registry) or icacls command line tool, you can use the "NT SERVICE\<service_name>" syntax to add your service SID to a resource.
In a recent Security Briefs article, Keith Brown shows how to factor out the higher privileged protocol transition operation in a COM+ component so a network facing gateway can be ran with lower privileges. In one of our projects, the gateway is a service configured with a service SID. We tried to add the service SID in COM+ roles with the "Component Services" mmc , to allow only our service to access the protocol transition component. But we found we couldn’t. However using a local group as an indirection, and adding the service SID to the local group worked just fine.
Configuring your service for a type of SID "Unrestricted" and thus having a service SID is a great way to either protect the resources your service needs, or in an environment that has been hardened, make sure that you only open access to your service. It is cheap to implement with a good return in terms of security gain.
This is part 2 of our series of posts on service hardening.
"Need to have" and least privilege principle
Executing with least privilege is a good practice of computer security. As with the "need to know" principle for information access, there should be a "need to have" principle for privileges. If your code does not need a specific privilege why should it run with it?
With Windows Vista, User Account Control ensures that user applications execute with less (and lower) privileges by default. User Account Control does not, however, apply to nor affect Win32 services which have their own mechanism (new to Windows Vista) for execution with least privileges. In Windows Vista and Longhorn Server, the RequiredPrivileges registry key allows to specify the privileges that the service should execute with. The process hosting the service will only have the privileges specified in RequiredPrivileges , and other privileges will be removed from the process token.
Although this may seem obvious, it is still worth stating that the RequiredPrivilege mechanism cannot in any case be used to augment the privileges of services but only to reduce them. If RequiredPrivileges refers to privileges that the service account does not already have, those privileges will be ignored. This is a recurring scheme in security by which a given mechanism can be used to restrain, but not to widen access.
Configure your service for least privilege
As a developer you should determine what minimum privileges your service needs and configure your service during its installation to run with those privileges only. This is an initiative of "good citizenship" on your part to lower the potential damage to the system in the event your code gets compromised. You can configure your service for least privilege with the ChangeServiceConfig2 API. If you don't, the administrator can still do it using the sc.exe command:
sc privs [service name] [Privileges]
And the current configuration for a service can be queried with the qprivs verb:
sc qprivs [service name]
Whether you use the ChangeServiceConfig2 API or the sc.exe command, you specify a privilege by its string. For instance, for the impersonate privilege, you would use "SeImpersonatePrivilege". The Windows SDK and winnt.h has the list of those and corresponding constants for each privilege strings (look for "Privilege Constants").
How do you determine which privileges your service needs? To our knowledge, this has to be done manually (please correct us if profiling tools similar to the ones for UAC analysis are available). Fortunately, the Windows SDK documentation often mentions the privileges needed when working with a given API and also whether those privileges should be enabled before calling the API versus whether the API is taking care of that. You may need to read the Remarks section carefully though. For instance, the SDK documentation for ImpersonateLoggedOnUser states that "The calling thread does not need to have any particular privilege." Sure, the API can be called without any particular privilege for some scenarios such as "identification level" impersonation, but if you want to do real impersonation, you do need the impersonate privilege.
In practice we've found that eliminating the unneeded privileges using knowledge of what the service does, code reviews, SDK documentation, and testing all execution paths was not too expensive and well worth the effort.
If you are hosting several services in the same process, the set of privileges the process gets is the union of those of its services. You should pay attention to this and regroup services according to their privilege requirements.
Built-in service accounts
Local Service and Network Service built-in service accounts were designed to be able to run services with lower privileges (than those of the all powerful Local System) without having to use dedicated user accounts. Creating and using dedicated user accounts for running services can be less than ideal as those user accounts have to be created and managed, including their (hopefully long and strong) passwords.
Local Service has about eleven privileges and no network identity. A service running under Local Service may listen for client requests from the network but if it attempts to reach a remote service, it will be seen as anonymous and most likely will fail (unless of course the remote service accepts anonymous requests). Network Service has one less privilege (i.e. it does not have the SeSystemTimePrivilege) and its network identity is the machine account on the domain.
Before Windows Vista, using Local or Network Service built-in accounts lacked granularity as all services running under a built-in account had the same privileges. Thanks to the RequiredPrivileges mechanism you can now have a fine granularity control over the privileges of your service without having recourse to dedicated user accounts. As a matter of fact, the other service hardening mechanisms in Windows Vista, which we will cover in our next posts, all tend to facilitate the use of built-in service accounts by providing more granular control. Several scenarii that previously reckoned for a dedicated user account are now possible with built-in accounts.
That said, there are plenty situations where a dedicated domain wide user account is necessary and fully appropriate for running a service. One such example is when you need to trust your service (such as trust for delegation) or grant access to your service on a remote resource or service, and you've determined that you’d rather trust your service specifically than trust the machine account.
Windows Vista native services
Microsoft has gone at length in its effort to reduce privileges of native Win32 service in Windows Vista. You can use Process Explorer to see the processes hosting Windows Vista services. A lot of native services are hosted using instances of svchost.exe (more on how native Vista services are grouped in svchost instances in our next posts). Notice that the DHCP Client service is hosted in a svchost instance that runs under Local Service with only four privileges (compare this with Local System and its twenty or so privileges under Windows XP). Actually, the DHCP Client service only requires two privileges as shown by the sc command:
C:\Windows\System32>sc qprivs dhcp
[SC] QueryServiceConfig2 réussite(s)
SERVICE_NAME: dhcp
PRIVILEGES : SeChangeNotifyPrivilege
: SeCreateGlobalPrivilege
The total of four privileges is due to the sharing of that svchost instance with other services such as the Eventlog or lmhosts services.
By the way, if you wonder whether you could use svchost to host your service, the answer is you are not supposed to. Svchost is for operating system native services.
Voili voilou! That’s all folks. Our next posts will go over the other service hardening mechanisms of Vista which are the per-service SID, write-restricted services, and network restrictions.
You may have heard that built-in services in Windows Vista were specifically hardened by Microsoft engineers during its development process. You might be wondering what that really means, how it works and, if you are a developer, how to harden your own services the Vista way. Jean-Yves Poublan, a Principal Security Consultant at Microsoft, and I are publishing a series of posts on how to leverage Windows Vista new architecture to make your services more secure.
Today, we start with a significant change with Windows Vista and Longhorn Server: Win32 services are now isolated in Session 0. So, what does this mean for developers?
‘windows’ on ‘desktops’ in ‘window stations’ in ‘Terminal Services sessions’
Windows NT was designed to be a multi-user system through the use of sessions. The SDK refers to these as Terminal Services sessions which are not to be confused with logon sessions, as they are not the same thing. Terminal Services sessions are created and managed by the session manager (smss.exe) which is one of the first processes created when the system starts. Logon sessions and processes somehow live within a Terminal Services session.
Note : The Terminal Services session ID for a given logon session may be obtained by calling the LsaGetLogonSessionData API after having enumerated the logon sessions (LsaEnumerateLogonSessions). One may also get the Terminal Services session ID for a process with the GetTokenInformation(TokenSessionId) API after having obtained the primary token for the process (OpenProcessToken).
Previous to Windows Vista and Longhorn Server, Win32 services and user applications for the console user (as well as winlogon.exe and the Win32 subsystem – csrss.exe) were all started within Terminal Services Session 0. A second Terminal Services session (Session 1) was created when a second user logged on (such as a user connecting through Terminal Services on Windows Server 2003, or a second user logging on Windows XP through Fast User Switching), and so on.
So user applications for the console user always shared Session 0 with system services. This is no longer the case with Windows Vista and Longhorn server.
What is wrong with having system services and user applications live in the same session? Well, it mostly has to do with interactive services.
First let’s recall what desktops and window stations are. Both are securable kernel objects in the sense that they are protected by ACLs. You can think of Terminal Services sessions having window stations that in turn contain desktops. There is a special window station called Winsta0 which is the windows station that is connected to the display and input devices. Processes are attached to a window station which they are going to use (supposedly) to interact with the user. Threads within a process are themselves attached to a desktop (within the window station) on which they display windows and they get input from the user. Windows messages are confined within a desktop, and Winsta0 will typically have three desktops: the winlogon desktop, the interactive desktop, and the screen saver desktop. Winsta0 grants rights to SYSTEM and the logon SID, so only the system and the currently logged on user can access the console. When a user logs off, the logon SID is removed from Winsta0, and when a new user logs on, the new logon SID is added to Winsta0’s ACL.
Windows, on the other hand, are user objects that are not securable by ACLs. So threads that have gained access to a desktop can send messages to any window on that desktop. In the past, applications that ran with higher privileges on the desktop have been vulnerable to the infamous shatter attacks from other malicious applications.
Normally, Win32 services are not attached to Winsta0 (they don’t have the rights on Winsta0), but instead they get their own window stations. Those window stations are not connected to any hardware so if a service displays a window and waits for user input, it may well wait forever…
Interactive services – to be avoided if at all possible
Interactive services are services that are configured as such (flag SERVICE_INTERACTIVE_PROCESS for CreateService or ChangeServiceConfig APIs). When the SCM starts a process for an interactive service, it attaches the service to Winsta0 instead of the service window station. In order to do so, the service process must run as SYSTEM (since only SYSTEM - and currently logged on user - have rights on Winsta0). Service threads can then attach to the interactive desktop and interact with the user.
One can see two compounded problems here: interactive services are vulnerable to Windows messages attacks from malicious user applications, and those attacks can result in privilege elevation since interactive services run as SYSTEM with TCB privilege. So deploying an interactive service that is vulnerable could compromise the whole system.
There are other things wrong with interactive services. On Windows Server 2003 with Terminal Services, the user that is currently logged on at the console in Session 0 may not be the user that the service should interact with. On Windows XP with Fast User Switching, it is even worse. The currently active console user may not be Session 0, but Session 1 (or Session n). In that case, if the interactive service waits for user input, it may wait forever from Session 0 which is not active. It is said that interactive services with Fast User Switching just don’t work. Because of that, developing and deploying interactive services has been strongly discouraged. As a matter of fact, interactive services can be banned from the system by setting the NoInteractiveServices registry value to 1 in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows. In that case, interactive services will still be started by the SCM (Services Control Manager), but they won’t be attached to Winsta0 (the SCM does log a warning in the event log). This is valid for Windows Vista and Longhorn as well.
Isolation of services in Session 0 with Windows Vista and Longhorn Server
With Windows Vista and Longhorn Server, user applications for the first logged on console user are now started in Terminal Services Session 1, and services in Session 0 are isolated from user applications. The second logged on user gets Session 2 and so on. Services isolation in Session 0 helps protecting the system from malicious user applications. Imagine one has installed an interactive service that is vulnerable, that interactive service will not share the desktop with (potentially) malicious user applications anymore and as such will be less likely to be compromised and used as a vehicle to attack the system.
Services isolation in Session 0 affects all services that assume they are running in the same session as user applications, and not only services that configured as interactive services. For instance, a service that communicates with user applications by way of Windows messages will no longer work. Also, a service that synchronizes with user applications through synchronization objects (semaphores, mutexes, etc…) created in the session private name space will no longer work as well. The global name space should be used instead (object names prefixed with Global\).
Under Windows Vista and Longhorn, a service can still be configured to be an interactive service, but such configuration does not make a whole lot of sense, since the interactive service will be attached to the Winsta0 in Session 0, which does not have a physical console and user to interact with.
If you have a service that is designed to be an interactive service and as such interacts with the desktop, or a service that assumes it is running in the same session as user applications, it is time to change it. Windows SDK does give some ideas of how a service could interact with users, without having to be an interactive service. This includes communicating with a user process through some form of IPC (preferably secure) channel, or using Terminal Services APIs such WTSSendMessage. Determining which user (in which target session) your service should interact with is up to you but should not be overlooked.
For legacy interactive services that cannot be changed in the short term, Windows Vista provides a compatibility mechanism called Interactive Service Detection service (ui0detect.exe). UI0Detect monitors interactive services in Wintsta0 of Session 0 and when such service displays a modal dialog it notifies the user in the currently active console session. The user can choose to switch to Winsta0/interactive desktop of Session 0 to respond to the dialog, and then switch back to the user session. UI0Detect is a temporary measure designed to limit the effect of Session 0 service isolation for existing interactive services that cannot be changed. As a service developer you should not count on that mechanism.
What about MessageBox() and MessageBox(MB_SERVICE_NOTIFICATION)?
When calling the MessageBox() API - *without* the MS_SERVICE_NOTIFICATION flag - from a service that is not an interactive service, the thread waits forever. It is worth noting that if a non interactive service is programmed in managed code on the .Net Runtime, calling the System.Windows.Forms.MessageBox.Show() method will raise an exception (“System.InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application”) instead of hanging there waiting for user input. Also if the service is an interactive service, under Windows Vista, UI0Detect will handle the interaction for MessageBox() – without MB_SERVICE_NOTIFICATION.
The MB_SERVICE_NOTIFICATION flag causes the system to redirect the message box to the interactive desktop (or winlogon desktop if there is no user logged on) on WinSta0 where it is handled by csrss.exe (the Win32 subsystem).It was designed to allow services that technically are not interactive services (i.e. they are not configured as interactive services and thus are not attached to Winsta0) to display a modal dialog message box on the interactive desktop and get user input.
Under Windows Vista RTM, this does not work however, in the sense that instead of the message box being redirected to the interactive desktop of a session with a user on it, or taken care of by UI0Detect as one could hope, the functions returns IDOK immediately with no user interaction whatsoever. It behaves that way even for services that are configured as interactive services and whose interactions are normally handled by UI0Detect. If your service uses MessageBox(MB_SERVICE_NOTIFICATION) to ask for user approval for some operation, it may need to be modified.
The following two tables summarize MessageBox behaviors under Windows XP SP2 and Windows Vista RTM.
|
NoInteractiveServices = 0 |
NoInteractiveServices = 1 |
|
SERVICE_INTERACTIVE_PROCESS (CreateService, ChangeServiceConfig)
Window station (service is running as SYSTEM) |
0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ |
0x00000100
"Allow service to interact with desktop"= checked
WinSta0 |
0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ |
0x00000100
"Allow service to interact with desktop"= checked
Service-0x0-3e7$ |
|
MessageBox() |
No display – waiting forever (1) |
Display OK (directly by service process)
|
No display – waiting forever (1) |
SCM warning in event log when starting the service
No display – waiting forever (1) |
|
MessageBox(MB_SERVICE_NOTIFICATION) |
Display OK (through csrss.exe) |
Display OK (through csrss.exe) |
Display OK (through csrss.exe) |
SCM warning in event log when starting the service
Display OK (through csrss.exe) |
MessageBox behavior on Windows XP SP2
(1) Managed code: runtime will raise an exception
|
NoInteractiveServices = 0 |
NoInteractiveServices = 1 |
|
SERVICE_INTERACTIVE_PROCESS (CreateService, ChangeServiceConfig)
Window station (service is running as SYSTEM) |
0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ |
0x00000100
"Allow service to interact with desktop"= checked
WinSta0 |
0x00000000
"Allow service to interact with desktop"= unchecked
Service-0x0-3e7$ |
0x00000100
"Allow service to interact with desktop"= checked
Service-0x0-3e7$ |
|
MessageBox() |
No display – waiting forever (1) |
Interactive Service Detection – user can switch to Session 0 to respond service |
No display – waiting forever (1) |
SCM warning in event log when starting the service
No display – waiting forever (1) |
|
MessageBox(MB_SERVICE_NOTIFICATION) |
No display – returns 1 (IDOK)(2) immediately |
No display – returns 1 (IDOK)(2) immediately |
No display – returns 1 (IDOK)(2) immediately |
SCM warning in event log when starting the service
No display – returns 1 (IDOK)(2) immediately |
MessageBox behavior on Windows Vista RTM
(1) Managed code: runtime will raise an exception
(2) Even if message box has no such button
Yesterday, the first Microsoft Techdays ended in Paris after three days and more than 200 presentations. Thank you to all of you who honored us by their attendance! (I don’t have the final figures yet but you were about 9,000 people on the two first days alone.) If you didn't have a chance to attend, you will be able to watch the presentations once they are published at the beginning of March (an understanding of French will be necessary). My personal involvement was to help define the security track content, present 5 sessions and lead two workshops on Windows Vista security with my colleague Pascal Sauliere.
My sessions included:
- Getting ready for NAP (original title: 'Se préparer à NAP') where I did demonstrate 802.1X enforcement on a Cisco 3750 switch. I did test the 802.1X enforcement on Enterasys gear too. I plan to publish a video of what it looks like on this blog. I will also provide some documentation on what I did to configure this demo. Stay tuned.
- The human factor: the weakest link or the last resort (original title: 'Le facteur humain maillon faible ou dernière chance '). Stanislas Quastana and I have had a lot of fun doing this one. I hope it will help support the fact that The human factor is a chance for Information Systems Security. You'll find all the references for the books we talked about on Stan's blog.
- What's new in security with Windows Vista (original title: Nouveautés de sécurité de Windows Vista). A short overview of Windows Vista security, co-animated with Pascal Sauliere.
- UAC: User Account Control (original title : Contrôle de compte utilisateur UAC) co-animated with Pascal Sauliere.
- An introduction to Forefront Client Security (original title: Découvrir Forefront Client Security) the enterprise antimalware solution by Microsoft.
I’ve heard that there were some great presentations (by both Microsoft and non Microsoft speakers). So, if you do speak French, I’m sure you will enjoy the content once it is published and more particularly, to only name a few: a tutorial on virology, Office documents fuzzing, quantum cryptography, integrating Linux into Active Directory…
People: the weakest link or a chance for security?
Have you ever heard security experts? They all point out that the human factor is the weakest link in the security chain. They often make fun of people being victims of social engineering for instance. They try to prove their assumption by showing how phishing attacks have been successful so far. Sometimes, the human factor seems to be an easy explanation or even an excuse for security failure... However, no one can pretend to do security if they only work on improving technologies or processes while stigmatizing people rather than taking them really into account. Moreover, it‘s time to stop deploring the weakness of the human factor. Fortunately, there’s another theory around the human factor by Robert Longeon, an IS security engineer at CNRS (http://www.cnrs.fr/index.html). Robert and I teamed together to introduce his theory more broadly and to try to make you realize that while the human factor might be a weak link, people are indeed a chance for information system security (IS security).
First of all, both of us do acknowledge it is true that bad behaviors of information systems actors can be a source of security incidents. Actually, at the source of any security incident, there’s almost always a person or a process deficiency. The gap between the level of security that one would like to have and what they have is usually due to either a transgression of security rules, whether maliciously or by negligence, or by a violation of security policies. Obviously, incidents’ outcome might be severely worsened by inadequate behaviors, insufficient vigilance or, at the opposite, excess of confidence of people at key roles.
Let’s talk about transgressions. Many authors [1] have worked on the human factor, some more particularly on information system security. Their work lead to theories used as reference in this domain (behavior theories, psychology or criminology inspired theories) or to explanatory models (behavior deviating with morals, technology acceptance model…). All these theories have in common to explain behaviors and related situations, to allow avoiding some mistakes, but do not give any practical method! Some more fecund works were done in safety, reliability or ergonomics researchs [2]: “The way by which the operators manage their working conditions has a great variability: the conduits observed show various logics of hierarchisation of the priorities in the event of constraints. They can cover the appearance of a search for compromise between the realization and the cost of a will to achieve an operational goal with the detriment of safety.” [3] So here is an interesting first point: an inappropriate behavior does not necessarily result from a malicious intent. Better, a transgression is not arbitrary and usually is the result of targeting a specific goal by adapting rules in response to a constraint. Therefore, there are solutions where some issues would be reduced by improving systems ergonomics to no force people to make a bad tradeoff between their goal and the company’s rules. That means there’s no fate and we don’t have to stay here watching issues arise while some specialists try to comment in erudite language!
If we try to improve ergonomics, we still need to avoid a common pitfall which is to believe that we can find a technical solution to this issue. Let’s face it, when people stigmatize the human factor, they usually think that securing information systems would be much easier if there was no human being involved at all. Thinking that machines could do the job better is over simplistic and loses sight of the fact that the root cause of the most frequent and most serious security incidents usually lies in management errors like ignoring to take security into account in the strategic goals of the company, not including security at the beginning of a project, over confidence in security devices by techno-friendly people, lack or insufficient training and education for security, loss of motivation by staff due to weak values in corporate culture, mistakes in defining security goals, deficient structures, lack of rules and procedures, diluted responsibility …
Moreover, information systems are called system for a reason. It’s because information in a company, while it may appear like chaos at first, is in fact a complex system. And complexity can’t be dealt by a finite-state automaton because a finite-state machine can only do what it was designed for. Only the human mind is able to grasp complex issues. On one hand in a normal situation, the surprisingly unpredictable and fundamentally irrational nature of human beings can waste the Information Security Officer’s day. On the other hand, in an unknown, therefore not programmed before, situation, it is a major asset. In such a situation of turbulences, the human factor is irreplaceable and highly valuable.
IS security is about information risk management and, as everyone knows, this risk can’t be annihilated. Therefore, one has to make choices. “To decide or to make strategic choices is an activity by itself that can’t be reduced to a sum of technical decisions.” [4] IS security is the realm of non deterministic choices based on a variety of notions that we can’t model for a finite-state automaton. These notions include our perception of reality, our vision of security and our understanding of our best interests at a given time… The human factor allows us to deal with the non deterministic nature of information systems. Any project management model relying on a deterministic logic of systematically and progressively reducing risk does not work. A technical system cannot pilot IS security while people can. Without the human factor, there’s simply no IS security. Piloting IS security is often more a matter of deciding in uncertainty rather than risk management. Indeed situations faced are new and cannot be deduced from past events (this impedes our ability to prevent or predict based on statistics). Worse, we don’t know everything about occurring events. What’s more, decisions taken modify the environment and the parameters assessed to take the decisions and usually understanding an issue requires a systemic approach based on knowledge in other areas. Zero day attacks based on an unlikely chaining of events are unpredictable. All these issues make objective probabilities difficult to compute. Using subjective probabilities has the drawback of relying on the limited rationality of decision makers and allows their beliefs to be manipulated. Works from other disciplines, in particular Knight [5] and Keynes [6] in economics, teach us how to distinguish risk (or situations where probabilities can be computed) from uncertainty (situations where probabilities can’t be computed) and give us clues on how to deal with the human factor. Therefore, the human factor is an uncertainty, not a risk! And one can try to reduce it by management efforts.
Conclusion and proposals for reducing uncertainty of the human factor by management
We agree that inadequate behaviors of IS actors can lead to security incidents. However, complexity of information systems makes inappropriate any deterministic solution like a technical solution. The only way we know to deal with a non deterministic system is to put in place a human organization. That’s why the human factor is a chance for information systems security, not a risk. To put it another way, a popular Russian proverb says “some eagles may fly lower than some hens, but a hen will never fly higher than an eagle”.
To achieve the goal of reducing uncertainty related to inappropriate behaviors, it takes a combination of the three following ingredients that Human Resources division cultivates:
- Knowledge: people need to have been trained to react correctly. This means an appropriate, targeted, not condescending training.
- Empowerment: people need to have the means and necessary authority to react. Some people need to be identified and selected to be individually accountable. The corporate culture should reward personal initiatives. For instance, if someone decides to innovate in dealing with a never seen before situation rather than stupidly following the procedures that are leading the company to failure, they should be confident that they will be recognized and not penalized for not sticking to the usual, inappropriate, procedures.
- Will: people need to be willing to react for the organization’s best interest, namely be responsible actors: “if anyone of us is aware of their roles, they discover themselves to be more than servants, they are sentinels and each and every sentinel is responsible of the empire.”[7]
In order to improve your security, you need to rely on people to complement technologies to, more or less intuitively, detect abnormal events when they occur. The required qualities are not learned in training centers. That’s why a selection is necessary. However the values in a company’s culture and the management style can help in maintaining and developing those qualities rather than annihilating them. Reducing uncertainty of the human factor is therefore about management!
Adding more technology is not a solution to organizational issues where decision processes need to be redesigned. Worse, a purely technological view of IS security can make you more vulnerable. And to emphasize the importance of employee involvement compared to the technological arsenal, let’s quote Thucydide, a Greek historian from the 5th century before Christ: “The thickness of a wall is less important than the will to defend it”. Indeed, the involvement of employees in IS security in a company is an excellent indication of its dynamism and social state. This can become a useful indicator for investors to assess the risk… of their investment.
References:
Updated 2008-05-12 : added a step to turn the TPM on before enabling BitLocker. By the way, someone made me notice this post is now referenced by the official BitLocker FAQ on Microsoft's website.
Many people have wondered if it would be possible to dual boot a TPM-bitlockered instance of Windows Vista with Linux, or another OS. The answer is yes and the following procedure will hopefully help you setup your machine correctly.
Some (simplified) background on Bitlocker:
Bitlocker Drive Encryption allows encryption of Windows Vista’s partition and provides a secure startup process when in use with a TPM (a crypto chip on the motherboard). Basically the BIOS, the TPM, the MBR and the boot sector will collaborate to help verify that there was no modification to the boot sequence since Bitlocker was activated. This is done by using a function of the TPM to compute and store a hash of the code before executing it, at each of the initial steps of the boot sequence. Different hashes will be computed and stored in specific registers of the TPM. Then Windows Vista will ask the TPM to unseal its volume encryption key and the TPM will only provide this key if its registers are correctly set. Therefore if you replace Windows Vista’s MBR by a MBR that is not TPM aware, it won’t hash the boot sector before executing it and a register in the TPM won’t be populated. Same with the boot sector. Therefore Bitlocker will simply refuse to be enabled.
The underlying idea here is to have Bitlocker enabled with the original Windows Vista boot files. Another possibility would be to use a TPM-aware version of GRUB. However this would imply using files in the boot sequence that were not tested by Microsoft, which I would not recommend. Moreover, using original Windows Vista files offers you the benefits of code that went through the Security Development Lifecycle, which I personally find very valuable.
Note: I assume that you have a Bitlocker compatible machine (including TPM 1.2, TCG BIOS). See http://www.microsoft.com/technet/windowsvista/library/c61f2a12-8ae6-4957-b031-97b4d762cf31.mspx#BKMK_require
Step 1 – Install Linux
Note: be sure to leave enough unpartitioned space for Windows Vista: about 11 GB of free unpartitioned space and slots for 2 partitions are needed
Step 2 – Install GRUB on the Linux partition (outside of MBR)
See other post “How to use Windows Vista’s Boot Manager to boot Linux”
Step 3 – Get a copy of Linux boot sector
See other post “How to use Windows Vista’s Boot Manager to boot Linux”
Step 4 – Create partitions for Windows Vista
We need to create 2 primary NTFS formatted partitions on the disk: one active, 1.5GB size minimum and another larger (all the rest for instance with a minimum of 8.5GB). The former will be used to boot the machine (active partition) and will remain unencrypted while the latter will host Windows Vista and will be encrypted when we activate Bitlocker.
You can use diskpart tool to do this (available from Repair options on the Windows Vista DVD). Here is what the instructions may look like :
· select disk 1
· create partition primary size=2048
· active
· create partition primary
Step 5 - Install Windows Vista
Install Windows Vista on the largest NTFS partition.
Step 6 - Set up Windows Vista Boot Manager to boot Linux
See other post “How to use Windows Vista’s Boot Manager to boot Linux”.
Step 7 - Enable TPM in BIOS
See instructions in your computer's manual.
Step 8 - Enable BitLocker on Windows Vista
See BitLocker documentation, like http://www.microsoft.com/technet/windowsvista/library/c61f2a12-8ae6-4957-b031-97b4d762cf31.mspx#BKMK_S3
The Web is full of explanations on how to dual boot Windows and Linux using a Linux boot manager like GRUB or LILO. If you want to dual boot Windows Vista and Linux using Windows Vista’s Boot Manager, please read on. I will assume that you already have installed Linux on your machine using GRUB as your boot loader.
Step 1 – Install GRUB on the Linux partition (outside of MBR)
As Windows Vista will replace the Master Boot Record (MBR) with its own, we need to relocate GRUB elsewhere by running grub-install with the Linux partition as a parameter.
• On Linux, launch a Terminal with root privileges
• Find the name of the partition Linux is installed on by running fdisk –l (the partition you’re looking for is the one whose system is Linux, can be something like /dev/sda1 or /dev/hda1. For the rest of this post, I’ll use /dev/sda1)
• Install GRUB on the Linux partition by running : grub-install /dev/sda1
Step 2 – Get a copy of Linux boot sector
We will need to instruct Windows Boot Manager how to boot correctly Linux using Linux boot sector, which we will extract using dd.
• On Linux, launch a Terminal with root privileges
• Take a copy of Linux boot sector : dd if=/dev/sda1 of=/tmp/linux.bin bs=512 count=1
• Copy linux.bin on a FAT formatted USB key or any storage accessible from Windows Vista
Step 3 – Install Windows Vista
Step 4 – Configure dual booting in Windows Vista
We will create an entry for GRUB in Windows Vista boot configuration data store using bcdedit.
• On Windows Vista, launch a command prompt with administrative privileges (by right clicking on cmd and choosing Run as Administrator)
• Copy Linux boot sector on the root of the Windows boot (active) partition, namely the one containing bootmgr. If you don’t know for sure you can use diskpart or diskmgmt.msc to find out which one it is.
• Create an entry for GRUB :
o bcdedit /create /d “GRUB” /application BOOTSECTOR
o Note: bcdedit will return an ID for this entry that we will call {LinuxID} below. You will need to replace {LinuxID} by the returned identifier in this step. An example of {LinuxID} is {81ed7925-47ee-11db-bd26-cbb4e160eb27}
• Specify which device hosts a copy of the Linux boot sector
o bcdedit /set {LinuxID} device boot
• Specify the path to a copy of the Linux boot sector
o bcdedit /set {LinuxID} PATH \linux.bin
• Add Linux entry to the displayed menu at boot time
o bcdedit /displayorder {LinuxID} /addlast
• Let the menu be displayed 10 seconds to allow for OS selection
o bcdedit /timeout 10
I want to thank Pascal Sauliere (http://blogs.technet.com/pascals) and Mathieu Malaise (http://www.microsoft.com/france/securite) for help on Linux/GRUB and for helping research bcdedit options.
Hello everyone! As you can see, I decided to start blogging on security, maybe sometimes on interoperability. To be honest, if the blogosphere was the solar system, I could be found closer to Neptune than Mercury. However, I’ve been spending more than the last five years meeting with people on security and every time I have had a discussion with a customer, a partner, a home user, a security expert or a crisis management specialist the exchange was very valuable. In fact, security is such a wide topic that one can learn something every day. What’s more there are many sources of inspiration in other industries. I hope that this blog will be a way for me to share with you some thoughts and for you to provide feedback, to both me and the readers (if there are some:-)). I’ll try to cover a wide range of topics. I plan to share pointers to content from people at the border or even outside of this industry whose work or ideas can provide food for thought. And I’ll also post on technical subjects. After all, this blog is hosted on TechNet!
(*) Well, you might be wondering what I really mean there. I was inspired in the choice of this ironical sentence by a colleague saying “for a computer science engineer, technical skills are not important; as long as he has them”. I like transactional jokes and decided to paraphrase it. I think it actually emphasizes pretty well that security is paramount (in fact maybe my colleague was himself paraphrasing someone else but after some quick research I did not find the original, so if you know, let us all know).
Some people seem to still consider security as a impeding and boring thing that is at best a necessary evil. Having tried to convince some of them that security can be fun, I must admit that I wish they were totally right in not being interested in security, and maybe thinking security is not important. That would mean they would have mastered security enough to not worry about it anymore, because they would have managed to achieve and maintain the right level of security. The first part of this tag line also emphasizes that a company is usually not about security, it’s about its core business. Therefore for any regular business, security should not be the most important thing as it should be granted that any of its competitor would achieve a comparable and reasonable level of security. Well let’s face it, the day any company can say that security is not important may never happen. And if it is ever close to arriving, which I don’t really believe, that will take a lot of efforts. After all, it’s maybe why you decided to be a security professional: to have a lifetime insurance against unemployment, isn’t it ? ;-)