When discussing Windows services and how to hunt for their abuse, it is worth mentioning that there are several threat hunting hypotheses that we can leverage. This is very common in threat hunting tradecraft in general and for persistence-related techniques in particular.
When you are dealing with Windows services techniques, all your hypotheses can be split into two big groups: Hunting for service creation (aka “establishment” aka “installation”) and Hunting for service execution (some time after the service was created/established). Each category can further be split into more granular hypotheses. In our case, we have four possible paths:
- Hunting for process command line artifacts of service creation
- Hunting for registry artifacts of service creation
- Hunting for process artifacts of an EXE file executed as a service
- Hunting for process artifacts of a DLL file executed as a service
This post focuses on the first two hypotheses (because they go hand in hand and because we don’t want to overwhelm readers with a large amount of information at once). The latter two hypotheses will be covered in the next part of this blog. The diagram below shows what we will cover in this blog post:
Technique T1543.003 Create or Modify System Process: Windows Service
Windows services are crucial for all types of threat actors. This technique addresses many challenges at the same time (persistent execution + high level of privileges + easy to avoid detection). What is most important for us is that, in order to execute something as a service, threat actors must first create a service, which can be done in many ways — and, more importantly for us, it can be hunted in many ways as well.
Hunting the threat: from hypothesis to event analysis
An initial hypothesis for service creation could be the following:
“Threat actors might use command line utilities to create a service”. Usually we consider utilities such as sc.exe with a specific parameter (namely, create), so our initial query might look like this:event_type: “Process creation” AND Payload.ImageFileName: “*\\sc.exe” AND Payload.Commandline: “* create *”
We can alter the query by adding more specific things (e.g., possible parent processes, path to service executable, other service creation parameters). The results of query execution might look like this:
By exploring a process creation event in detail, we can find more information about the parent process:
In our case, the parent process is cmd.exe, but it is worth bearing in mind that cmd.exe might not be the only parent for sc.exe — which is a good topic for discussion for future blog posts.
Hunting for command line parameters of service creation is simple and what we consider “low-hanging fruit”. The probability of an event being malicious is quite high (which results in much less data to process), but overall it may be rare to see this in action (since threat actors do not often set up persistence like this during an attack). There is also a problem if we consider many other ways in which services can be created using command line utilities (e.g,. PowerShell New-Service, custom service managers such as nssm). Luckily enough, we know that Windows services themselves are just registry entries, which suggests an additional hypothesis:
“Threat actors might create a Windows service using any tool, but we will still be able to see changes in the corresponding registry keys.”
These corresponding registry keys are stored under HKLM\SYSTEM\ControlSet001\services\*service_name*, so we can use this knowledge to create another useful query:event_type: “Registry key value creation or modification” AND Payload.KeyName: “*\\services\\*” AND Payload.Value: [“ImagePath”, “ServiceDll”]
The ImagePath value contains a path to an executable file, and ServiceDll contains a path to a DLL file (if DLL is launched as a service).
Let’s use a version of this query to hunt for possible EXE files installed as services:
This is a detailed view of a noteworthy registry event (which corresponds to a command executed by sc.exe above):
It should be noted that, at this point, we might come across legitimate service installations and modifications, which results in a little more data to analyze, but this is a bulletproof method of hunting for services because regardless of the method used to install the service, service installation is detected. With a few tweaks, such queries can give a high fidelity output.
I would like to specifically mention the case when threat actors use DLL files as a Windows service. The main difference compared with EXE file as a service is that the threat actors must perform an additional action (create a service + assign a DLL file to this service separately). Overall, DLL as a service execution requires execution in a context of specific process which is svchost.exe, so the following is a possible sequence of commands:
First, the threat actors create a service, then they modify the corresponding registry key (in this case using the reg.exe utility, but such modifications can be done manually through the regedit utility or even via a backdoor that uses the Windows API).
In this case, we can still hunt for registry changes using the following query:
And this is an example of the detailed event:
To reduce the amount of registry events, we can make our query more specific by filtering a path to the EXE/DLL file, but this should be done with caution — sometimes threat actors can place their malicious file inside a directory that would be considered non-malicious, such as C:\Windows\system32.
To sum up, this blog post has discussed how to use EDR telemetry to hunt for the creation of suspicious services. We used two separate hypotheses and corresponding queries:
- “Threat actors might use command line utilities to create a service”
event_type: “Process creation” AND Payload.ImageFileName: “*\\sc.exe” AND Payload.Commandline: “* create *”
- “Threat actors might create a Windows service using any tool, but we will still be able to see changes in the corresponding registry keys”
event_type: “Registry key value creation or modification” AND Payload.KeyName: “*\\services\\*” AND Payload.Value: [“ImagePath”, “ServiceDll”]
The first hypothesis is easier to use, but it requires you to know all the possible tools that could be used for service creation. The second hypothesis generates a little more noise but helps to identify service creation events regardless of the tool/method used for service creation (even if the threat actors use the Windows API directly, without leaving any command line traces).
The real challenge starts if you ask yourself a question such as: “But what if we lack telemetry data for the period when the service could have been created?”. To answer this question, we require a completely different approach with completely different hypotheses, so we will address this in the next part of this blog post.
Roman Rezvukhin – Head of Malware Analysis and Threat Hunting Team
https://www.group-ib.com/blog/hunting-rituals-windows-services-part-1/