Let’s suppose we compromise a web application running on a Windows system and we achive RCE, so we send a Reverse Shell to our attacker machine
Enumerating the system DACLs
Once we have access to the system, we transfer to the target a tool that can audit any existing ACE within the DACL of each object’s security descriptor in the system
.\SharpUp.exe audit
Command Output
<SNIP>=== Modifiable Service Binaries === Name : SecurityService DisplayName : PC Security Management Service Description : Responsible for managing PC security State : Stopped StartMode : Auto PathName : "C:\Program Files (x86)\PCProtect\SecurityService.exe" <SNIP>
Verifying permissions over the given resource
We find out that there is a modifiable binary related to a certain service. We can list the DACL of the binary in question as follows
Checking if the given service is running as LOCAL SYSTEM
Once we check that we have FULL CONTROL or other permissions that allow us to replace the given binary with a malicious one, we should check as which user the current service is running as
Get-CIMInstance -ClassName win32_service -Filter 'name="<SERVICE_NAME>"' | Select -ExpandProperty state
Weak Service Permissions
i.e. Service DACL as a Securable Object
Workflow
Continuing with the previous case, after compromising a web application and establish a remote connection to the target through a reverse shell, we start by enumerating the DACL of any securable object looking for any existing weak permissions or misconfiguration
.\SharpUp.exe audit
Command Output
<SNIP>Modifiable Services Name : WindscribeService DisplayName : WindscribeService Description : Manages the firewall and controls the VPN tunnel State : Running StartMode : Auto PathName : "C:\Program Files (x86)\Windscribe\WindscribeService.exe"<SNIP>
This means that we have some kind of privileged right over the service object and we could probably leverage this right to gain code execution as the user account running the given service, which is probably a more privileged principal than the current user
Requirements
The controlled principal must have privileged permissions over the service object
Having verified that the current user has privileged rights over the service in question, such as SERVICE_ALL_ACCESS, as stated, we can gain code execution as the user account running the service
Checking if the given service is running as LOCAL SYSTEM
To do so, first we have to check if the service in question is running as LOCAL SERVICE or another privileged system account. We do this basically to know if once we carry out the remaining steps of the workflow and gain code execution as the user in question, we achieve a more elevated and privileged security context
If the service is running as LOCAL SYSTEM or another privileged user, we can just simply create a malicious payload from our side, transfer it to the target and replace the binary path of the given service with it
Get-CIMInstance -ClassName win32_service -Filter 'name="<SERVICE_NAME>"' | Select -ExpandProperty state
Unquoted Service Path
Workflow
When a service is created on a Windows machine, its registry configuration specifies the absolute path to the binary that will run once the service initialization is triggered
It its path is not encapsulated within quotes, it may be susceptible to some hijack techniques
We must bear in mind that if we have have the folllowing path without being encapsulated within quotes
With this in mind, if there is any misconfigured ACE within the DACL of any of the directories above, we can create a binary file with the same name as one of the ones listed above
So that binary will be executed when we restart the service
The caveat of this approach or technique is that an standard user account rarely has write permissions over one of the mentioned directories or is able to restart a service
Requirements
The Binary Path of the given service must be unquoted
The controlled user account must have write permissions over one of the legitimate binary path directories
The controlled user account must be able to restart the service in question
Abuse
Searching for Unquoted Service Paths
wmic service get name,displayname,pathname,startmode |findstr /i "auto" | findstr /i /v "c:\windows\\" | findstr /i /v """
Checking if the given service is running as LOCAL SYSTEM
Verifying Write Permissions over one of the service’s binary path directories
CMD & PS
icacls '<DIRECTORY>'
PS
Get-ACL '<DIRECTORY>' | Select accessToString
Once we verify that we have WRITE permission over one of the directories, we can just create a malicious binary from our side, upload it to the target and stored it within the directory in question
Then, we simply restart the service if can. If not, all we can do is wait
As we have mentioned several times, once we establish a remote connection to the target through any technique, such as a reverse shell or WinRM, we have to start enumerating the system to look for any security flaw or misconfiguration
After checking most things, we decide to enumerate the DACL of any Windows Registry Hive and its corresponding keys to see if we have write permissions over one of them
Then, we find out that we have WRITE permissions over the registry hive of a certain service, so we can replace the value of its imagePath property with a malicious binary
This way, when the given service is restarted, the malicious binary will be executed and we will achieve code execution as the user running the service
Requirements
The compromised user account must have WRITE permissions over either the entire service’s registry hive or its imagePath
The compromised user account must be able to restart the service in question
Otherwise, we will have to wait for it to restart
Abuse
Checking for Weak Service ACLs in Windows Registry