Service permissions are often an overlooked, yet easily exploitable if incorrectly configured, area of the Windows operating system. In this brief tutorial we take you through a simple scenario in which we identify a vulnerable service (purposely configured in an insecure manner) before explaining how we may use this to our advantage. It should be mentioned that here we are dealing with service permissions rather than the more commonly known service binary permissions, i.e. those assigned to the actual executable.
Firstly, there is nothing new here. However we hope this will shine some light to an otherwise uninteresting, just revealing topic.
Configuring Service Permissions:
An easy way to gain an overview of effective service permissions is to use the SysInternals utility AccessChk.
The following command will display a high level overview of the existing permissions of a service. Usage of this tool is as follows (example service used throughout this post is ‘MozillaMaintenance’):
AccessChk.exe –c MozillaMaintenance
Output from this command follows (please note that the service is deliberately configured insecurely and the verbose output option from AccessChk has not been used purposefully for ease of reference in this example):
RW BUILTINAdministrators RW NT AUTHORITYAuthenticated Users RW PWNMEGuest R BUILTINPower Users RW NT AUTHORITYSYSTEM RW BUILTINUsers
From the above output it is obvious to see that a number of untrusted groups have privileged access to this service. By using the built-in tool sc we can extract more granular detail, as well as the data required in order to modify this service:
sc sdshow MozillaMaintenance
Output from this command is as follows:
The output from this command can be somewhat confusing. By consulting the this reference it is easier to understand the construction of the data descriptor.
For example the first extract D:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA can be broken down as follows:
The prefix ‘D’ states that were are dealing with a Discretionary Access Control List (DCAL) – these control permissions. The second variety ‘S’ tells us that we would be dealing with a System Access Control List (SACL) – these control auditing (of which we are not concerned with in this post). The remaining are detailed below:
(A) Allow (CC) SERVICE_QUERY_CONFIG (DC) Delete All Child Objects (LC) SERVICE_QUERY_STATUS (SW) SERVICE_ENUMERATE_DEPENDENTS (RP) SERVICE_START (WP) SERVICE_STOP (DT) SERVICE_PAUSE_CONTINUE (LO) SERVICE_INTERROGATE (CR) SERVICE_USER_DEFINED_CONTROL (SD) Delete (RC) READ_CONTROL (WD) Modify Permissions (WO) Modify Owner
Finally (after the three semi-colons) we’re told which account these permissions affect:
(BA) Built-in administrators
As is evident from the first extract, this particular service allows a number of groups privileged access. In this following example we will remove the ‘Authenticated Users’ group entirely from the service permissions:
sc sdset “MozillaMaintenance” D:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;LG)(A;;CCLCSWRPWPDTLOCRRC;;;PU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BU)
Again, using the AccessChk tool, it is obvious to see that the ‘Authenticated Users’ group has been successfully removed.
RW BUILTINAdministrators RW PWNMEGuest R BUILTINPower Users RW NT AUTHORITYSYSTEM RW BUILTINUsers
It is also possible have finer control/permission assignment over the service permissions. In the following example we will use the same service and reassign the guest account (reference LG within the access descriptor) just the ‘SERVICE_QUERY_CONFIG’ permission.
Firstly, we require the SID (or the descriptor, i.e. LG for Local Guest) of the user. Tools can be found online to gain access to this; including using PowerShell. In this example the SID of the guest user is S-1-5-21-XXXXXXXXX-XXXXXXXXX-XXXXXXXXX-501 (note the local guest will always have the RID of 501). To modify the access descriptor the SID can be supplied along with the relevant permissions:
To verify the changes have been successful you can again use the sc sdshow command or, easier still, use AccessChk with greater verbosity.
What’s the issue?
Consider this. As it stands, prior to any modification of service permissions, the ‘Authenticated Users’ group has quite a number of permissions. What happens if an authenticated, yet unprivileged user has a malicious payload located at C:tempmalicious.exe.
Perhaps this may enlighten:
sc config MozillaMaintenance binPath= "C:tempmalicious.exe"
We have now modified the legitimate MozillaMaintenance service to call our payload when executed. You may be thinking great, but what use is this? I can call the malicious payload myself! You can but you will be limited by the permissions of your account. Here we’re looking for privilege escalation vulnerabilities. Let’s query the MozillaMaintenance service to see which account this runs as.
sc qc MozillaMaintenance ***output redacted for ease of reference*** SERVICE_START_NAME : LocalSystem
In summary any malicious payload that we have managed to ‘inject’ will run under the context of the LocalSystem account. Game over.