Investigating a Suspicious Service

The Incident Response team at MDSec regularly gets queries from our customers, as well as our consultants about odd things that they’ve found, either during engagements, or on an ad-hoc basis.

Recently, during one of our Purple Team exercises, one of our consultants drew our attention to a large number of services that had been deployed across the customer network, that were; quite rightly causing a bit of concern.

These services had all the hallmarks of “probably bad, at least very weird”: seemingly randomly named, with some lumps of PowerShell for good measure.

 The customer, and our consultant had a couple of questions about these services:

  1. How do we work out when these were created?
  2. What is it/how much do we need to care?

1: How do we work out when these were created?

There are a couple of simple ways to query information about a service, we prefer using sc qc <service name>. Which displays information about the type of service, the display name, the path name etc.

Unfortunately, this doesn’t display information about when a service was created. There are a number of different ways to obtain this information, some more reliable than others.

Windows Event Logs

System Log, EventID: 7045

You can also query using PowerShell:

Get-EventLog -LogName System | Where-Object {$_.EventID -eq 7045 | Select-Object -Property TimeGenerated, Message | Format-List

Or, if you’re using Log-Extractor:

zgrep '"EventID":{"Qualifiers":"7045"}' *| cut -d ':' -f2- | jq .

*Note that the time shown in the Log-Extractor log is UTC whereas the other two are quoted in local time (because Windows hates analysts).

The trouble with using Windows Event Logs for this sort of thing is that if not centralised (as with this customer) these logs typically have a fairly short lifespan resulting in data being missing or inconclusive.


Services are stored within the Windows Registry, which contains written dates for specific keys. Unfortunately, there’s no super simple way of programatically getting this data, and in the backward way of Windows the simplest way is the following:

  • Open Registry Editor
  • Navigate to appropriate key (HKLM\System\CurrentControlSet\Services\<Service Name>)
  • Right Click, Export as text (not .reg)

2: What is it/how much do we need to care?

Looking at the code, we can see that there are two separate commands being run, the first of which is just command prompt being used to start a process:

cmd.exe /b /c start /b /min <command>

What this is effectively doing is running the command minimised to a user. Largely unnecessary when running as a service but there we are! Interestingly from a detection standpoint this would generate two cmd.exe processes with parent child relationships, and then finally a PowerShell process which would be trivial to signature and unlikely to be associated with legitimate activity.

The much more interesting command being ran is that of the PowerShell script. Immediately we can observe a couple of things:

powershell.exe -nop -w hidden -noni -c

This basically runs the command with no profile (-nop) in a hidden window, in non-interactive (-noni) mode. But we don’t really care about this beyond the fact that it exists.

With a bit of tidying up (and switching to a decent environment), we’re left with some more cohesive PowerShell:

We can see here, quite simply the script is looking to see if we’re running a 32 bit of 64 bit system, then launching a PowerShell process in the background with a number of arguments (in this case the bit we care about). Let’s get rid of all the fluff and focus on the bits we care about:

Effectively what this code is doing is Gzip Decompressing some base64 encoded data. We can work with that! A couple of lines of Python is all that’s needed to convert this into something sensible:

This code should be fairly self explanatory, but in case it’s not. We can use the python base64 library to decode the data, then the gzip library to decompress. You could achieve something very similar using CyberChef:

The result of which gives us something like:

Oh, this looks a bit more complex. This is the point where experience and time optimisation come in. We can see that “$c3F” contains some more base64, we can see that this is effectively being copied into “$gB” which is then invoked in a “CreateThread” function ultimately meaning that the base64 content is executed. Beyond this, we don’t really care at this stage. I’m far more interested in what is under the base64.

With some minor adjustments to our python, we get some gunk out of the Base64, gunk being the technical word for “file doesn’t know what this is”.

Ok, well if only it was easy. Let’s have a look at the hex, and from the age-old cyber security textbook let’s get some Google going:

FC E8 rang a bell for me before we Googled it, but the search results confirm my suspicions.

We always say to analysts, Google everything, sometimes it can save a LOT of time. A long time ago we confirmed that some samples were linked to a known APT group by Googling some strings in a sample we identified. We could have spent significant time and effort reverse engineering the binary, but why bother when someone has already done that work and published it, we save the customer time and money by working efficiently.

Enter SCDBG, this awesome tool emulates shellcode and displays what functions are being called. There’s even a pretty GUI to make it utterly fool proof:

So, what we have here is most likely a Metasploit stager which is attempting to connect to 10.x.x.x address on port 4444. Given its an internal RFC1918 IP address and a default port number, it seems like the most likely explanation is that a security assessment or internal test had occurred and been poorly cleaned up in the past. At this point any further analysis with the data in our possession was unlikely to yield any further results so we reported our findings to the customer who were able to confirm our theory.

This is just one of many possible ways of performing analysis of an unknown, the key takeaways are to focus on the key items rather than getting hung up in the details.

MDSec provides a range of proactive and reactive response services, as well as 24/7/365 retained Emergency Response services. To find out more about how we can help your organisation, please get in touch:

Yara Rule to detect Metasploit and Cobalt Strike Shellcode

        description = "Detects MSF Shellcode"
        author = "MDSec"
        reference = ""
        date = "2021-05-04"
        $initial = {fc e8 ?? 00 00 00 00}

        $initial at 0

This blog post was written by Chris Basnett.

written by

MDSec Research

Ready to engage
with MDSec?

Copyright 2021 MDSec