(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.
Set fwPolicy2 = CreateObject("HNetCfg.FwPolicy2")
' Get the Service Restriction object for the local firewall policy.
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:
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
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|
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.