Threat hunting for abuse of Windows Services – part:2

When discussing Windows services and how to hunt for their abuse, it is worth mentioning that several threat hunting hypotheses can be leveraged. This is common in threat hunting in general and for persistence-related techniques in particular.

As a reminder, all our service-related hypotheses can be split into two main groups: Hunting for service creation (aka “establishment” or “installation”) and Hunting for service execution (sometimes after the service is created/established). Each category can also be split into more granular hypotheses for specific threat hunting needs. Our four possible hypotheses, which we established earlier, are:

  1. Hunting for process command line artifacts of service creation
  2. Hunting for registry artifacts of service creation
  3. Hunting for process artifacts of an EXE file executed as a service
  4. Hunting for process artifacts of a DLL file executed as a service

This post covers hypotheses 3 and 4. They are very similar in nature but require entirely different threat hunting approaches (hypotheses 1 and 2 were covered in the previous Hunting Rituals blog post). The diagram below shows what we’ve already covered and what can be expected from this blog post:

windows services related threat hunting hypotheses

Technique T1569.002 System Services: Service Execution

As stated in the previous post, Windows services are important to both high- and low-profile threat actors. They allow for persistent execution of their backdoors along with high privileges and relative disguise. We have already discussed how we can hunt for events relating to service installation, but sometimes it is not enough to pursue a lurking attacker in your network. What if events related to service installation are outside of EDR telemetry retention period? What if we’ve just installed EDR and physically cannot have any data from the past?

Well, we still have some useful hypotheses in our arsenal. Of course, service setup is a key part, but one more thing must be considered: services (especially malicious ones) MUST be executed, and they are usually executed repeatedly — unlike service setup, which usually occurs only once. It is harder to hunt for such execution behavior since services are widely used by legitimate software, but it is a more ultimate way of dissecting a concealed activity, especially if you have made correct assumptions about the attacker’s capabilities.

Feeling confident in your ability to hunt down cyber threats?

Be a part of the “Hunting season: Group-IB 20th anniversary CTF” and put your crime-nabbing skills to the ultimate test. Solve 16 expert-crafted cyber challenges and unlock a special reward.

Register now

Hunting the threat: from hypothesis to event analysis

First of all, it is important to understand the main idea behind service threat hunting, namely that services are executable files (for the most part) that are triggered under specific conditions. We will focus on .exe files being executed as services and on .dll files being loaded in the context of a service process. What this means for us is that, in both cases, we will not use any special EDR events. Instead, we will rely on the good old “Process creation” and “Loading executable code in the process” event types.

Disclaimer: We will not cover cases when .sys files are executed as services because the related hunting procedure is similar to .dll service hunting. On top of that, it is relatively rare for attackers to use .sys files because .exe- and .dll files are sufficient for their needs. Most of the time, threat actors are not as sophisticated as we think they are, and there is no need to make things complicated for yourself  — just accept it 

An initial hypothesis for an .exe file executed as a service could be the following:

“There will be a suspicious process executed as a service”. Simply put, we expect to observe a process being spawned by a services.exe process, the well-known “father of all services” in Windows OS. In such cases, the initial EDR query might look like this:event_type: “Process creation” AND Payload.ParentImageFileName: “*\\services.exe”

We can alter the query by adding more specific things (e.g., specific command line arguments, path to service executable file, signature status). The results of query execution might look like this:

results of query execution

There are too many events matching this query — and almost all the events are legitimate. We need additional baselining to obtain the list of suspicious events. Unfortunately, a universal list of exclusions does not exist in this case because they all depend on the infrastructure (which is different for every network). We could process them one by one, but this would be time-consuming. In this case, we therefore have an additional analysis method at our disposal, namely to build statistics for matching events and perform quick baselining:

statistics for matching events

In this case, we simply count the number of occurrences of unique service executable files. The most interesting and most suspicious things are usually at the bottom of such a table, so let’s take a look

suspicious-looking executable

Bingo! There is at least one suspicious-looking executable. So we can build a simple query to look for a process creation event related to this executable:

a process creation event related to suspicious-looking executable

And this may be the event we were looking for:

event related to suspicious-looking executable

We can now pivot from this event to obtain information regarding related network connections/file modifications performed by this process or even look for process children to determine whether there are any commands executed by potential attackers. It is worth noting that the signature status is valid (unlike the file path), which means that if it is actually a malicious service process, potential threat actors could also rely on the DLL side loading technique (in which case you can refer to the hypothesis shown in our first blog post in the Hunting Rituals series).

Next, let’s focus on a case when a malicious service is executed as a .dll file. In such cases, the .dll file in question is loaded to the memory by the svchost.exe process. Bear in mind that there may be many svchost.exe processes running at the same time and there may be many .dll files loaded by each one, so it is a bit difficult to rely on process creation events. Luckily, we have a special event type for this case: Loading executable code in the process (or “DLL loading” for simplicity).

The hypothesis for the .dll file loaded as a service could be phrased as follows:

“There will be a suspicious .dll file loaded by svchost.exe”. It can easily be transformed into a EDR query:event_type: “Loading executable code in the process” AND Payload.ImageFileName: “*.dll” AND Header.ImageFileName: “*\\svchost.exe”

The results for a single host over a short period of time may look like this:

results for a single host over a short period of time

We can explore them one by one to see if there are any outliers (and to determine whether we can add some specific details or exclusions to our query):

executable code in managed xdr platform

It seems that additional filtering based on a signature status could be a good idea. If there is a service .dll file which is not signed, then it is most likely suspicious or malicious. It is true until you decide to execute a corresponding query not against a single host, but against all the hosts in your infrastructure. The possible numbers for a filtered query are:

possible numbers for a filtered query in managed xdr interface by group-ib

The numbers for the same infrastructure (consisting of approximately 1,000 hosts, i.e., not too big) are:

possible numbers for a filtered query in managed xdr interface by group-ib

It may be a serious threat hunting challenge to weed out the legitimate events in this case, but there are still some methods we can use. They are not that simple and require an in-depth understanding of how malware works internally and how to handle a large amount of data, however, which makes it beyond the scope of this blog post (at least for now).

Roman Rezvukhin

Roman Rezvukhin – Head of Malware Analysis and Threat Hunting Team

https://www.group-ib.com/blog/hunting-rituals-windows-services-part-2/