Skip to main content

Service Auditing - Advanced


Author(s): Donkey (d0nkeyman), sv_du (sv-du), Anywheres

Last Updated: 08-06-2025

Recommended Prerequisites (click to expand)
  • Service Auditing - Beginner

What To Expect

At this level, service auditing becomes about understanding the Windows service permission system at a low level and exploring the security consequences and nuances of this system.

We recommend having a strong understanding of file permissions and having completed the previous service auditing guides.

Permissions

Just like with files, the permissions of a service can be represented and set through an SDDL string (covered in advanced file permissions). You have probably noticed this when trying to start or stop Windows Defender Firewall (mpssvc) or any other protected service.

So what would happen if mpssvc gave everyone permission to turn it on and off? What if a malicious service made it so only SYSTEM could change its status? We encourage you to experiment with SDDLs and come up with ways they could potentially be used to compromise the security of a system or make certain tasks much harder.

One interesting use case of SDDL strings for services is creating "hidden services" that evade standard tools. You can read about them at https://www.sans.org/blog/red-team-tactics-hiding-windows-services/. In a nutshell, these services do not appear in the services.msc applet nor the Get-Service cmdlet, yet behave like normal. There are limits to this hiding, however, and these are limits that we can exploit!

All services, "hidden" or not, need to be registered in the registry to work properly. Windows has to be able to access this registration to allow the service to run. Registering a service causes an entry to be added in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services, each folder named with the service name, and each folder containing information about the service.

These folders also have SDDLs, which are different from the service SDDL, stored in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<service name>\Security. To do further hiding, an attacker can modify the permissions of these keys to the bare minimum that Windows needs to let the service function. One of the necessary accounts that needs permissions is SYSTEM, which is good because we can log in as SYSTEM.

In essence, to find "hidden" services, one must simply find the keys in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services not outputted in Get-Service

The following Powershell command does just this. To minimize permission errors with registry SDDLs, run this command as SYSTEM

Compare-Object -ReferenceObject (Get-Service | Select-Object -ExpandProperty Name | % { $_ -replace "_[0-9a-f]{2,8}$" } ) -DifferenceObject (Get-ChildItem -path hklm:\system\currentcontrolset\services | % { $_.Name -Replace "HKEY_LOCAL_MACHINE\\","HKLM:\" } | Where-Object { Get-ItemProperty -Path "$_" -name objectname -erroraction 'ignore' } | % { $_.substring(40) }) -PassThru | Where-Object {$_.sideIndicator -eq "=>"}

Protected Process Light (PPL)

Windows has some protections on important services to prevent malicious tampering. The most common one is LSASS, which you should be familiar with at this point. You can read about PPL at https://itm4n.github.io/lsass-runasppl. The only thing I would like to emphasize is that LSASS is not the only service you should pay attention to. Experiment with PPL services in a VM and figure out what they prevent (Can you modify their registry? Can you delete their files?).

LSASS in particular has two registry keys that you can set using the reg utility to ensure it runs as PPL:

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa" /v RunAsPPL /t REG_DWORD /d 1 /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\LSASS.exe" /v AuditLevel /t REG_DWORD /d 8 /f

Unquoted Service Path Injection

When a service is started by the Service Control Manager, the service is run using the ImagePath value of the service's entry in the SCM database (located at HKLM\SYSTEM\CurrentControlSet\Services). This value is just a normal file system path pointing to the executable which should be used to run the service. Due to the way Windows handles paths with the CreateProcess Win32 api call, a service path containing spaces which isn't enclosed in quotes is vulnerable to attack. The reason for this can be seen in the documentation for CreateProcess:

If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the following order:

c:\program.exe

c:\program files\sub.exe

c:\program files\sub dir\program.exe

c:\program files\sub dir\program name.exe

In the event that a service path is unquoted, Windows will search for an executable in each path segment which ends in a space from left to right until it finds a valid executable. If a user happens to have write access to one of these locations, then it is possible that they could take advantage of this search order and place their own malicious executable at one of these locations. For example, if a service executable was placed at C:\Program Files\SecureService\Service Executables\supersecure.exe and had an unquoted path, Windows would first check for C:\Program.exe, then C:\Program Files\SecureService\Service.exe, then finally C:\Program Files\SecureService\Service Executables\supersecure.exe. If an attacker had write access to the SecureService directory, they could create a malicious Service.exe file which would run when the service activates. Since it is common for services to run with high privileges such as those of the LocalSystem account, this could lead to an attacker escalating their privileges on the system. As such, when defending a system you must ensure that any service paths which contain a space are properly enclosed in quotes.

Tooling

As usual, the Sysinternals tools prove to be very useful in higher-level analysis of Windows services. Specifically, Process Explorer can be useful in seeing the current protection level of running processes.

I also recommend Process Hacker, as it makes modifying service permissions, PPL, and much more a lot simpler with a GUI. You should still learn the command line version of the above for your scripts and personal tooling; however, for quick fixes, Process Hacker will prove useful. You can also use it to run with TrustedInstaller-level permissions, which you will need to modify permission/PPL properly.

Practice

Here is a list of practice images that have some more advanced Service Auditing vulnerabilities: https://docs.google.com/spreadsheets/d/1zjvtl_TNkD108jZaluGo-juQI6U89P7tcqWTZELmpH8/edit?usp=sharing

  • King Arthur's Castle
  • Baldi's Basics
  • Sunrise Foundation Training Simulation

References, Further Reading, & Tools Mentioned