Friday, 10 December 2021

Detecting Token Stealing using Sysmon v13.30 and EQL


Access token manipulation is a well known technique often used to elevate privileges or to execute in the context of a different identity.  There are different implementations of this technique but the most observed one seen in malwares as well as in common offensive frameworks (i.e. metasploit incognito, cobalt srike steal_token) is often referred to as Token Stealing and aims to elevate privileges from high integrity to System integrity.

If you are interested to know more about the implementation part of this technique I would recommend the following reading :

The classic implementation invole those steps / APIs: 
  1. Enable SeDebugPrivilege (needed for Step 2 and require high integrity)
  2. Obtain a handle to a process running as System via OpenProcess (victim)
  3. Obtain Token handle of the System process via OpenProcessToken 
  4. Duplicate stolen token via ImpersonateLoggedOnUser and DuplicateTokenEx
  5. Create a SYSTEM child process with the token duplicate via CreateProcessWithTokenW

For step 2 (critical step) usually the source process (Malware) will be running as High integrity and won't be able to obtain Full access rights to all System processes (i.e. PPL). 

The minimum needed Access rights are enough to obtain a valid access handle that allow to proceed to step 3:

0x1400 - PROCESS_QUERY_INFORMATION : High to System, fails on PPL protected processes such as the following: 

0x1000 - PROCESS_QUERY_LIMITED_INFORMATION (High to system, works on PPL protected processes)

Also something worth noting is that winlogon.exe is one of the most targeted processes (not PPL and runs as system).


For detection there are some opportunities such as the one described in this blog using custom SACLs to audit a list of selected processes object access via event 4656 (very noisy, often not logged in prod and captures step 2 only) or baselining processes enabling the SeDebugPrivlege using event 4703 (captures step 1 only). 

In this post we will be using Sysmon v.13.30 that added recently some cool enrichment (SourceUser,  TargetUser for process Access events and ParentUser for process creation events) and that we can play with to create a more resilient detection. Before going to the detection logic let's breakdown the key steps/artifacts:

Step 1 - Windows security 4703

Step 2 - Sysmon  Process Access - 10 (Target is a System process and source is not)

Step 3 and 4 - No Events

Step 5 - System Process Creation  

From the above events we can create a correlation (using Elastic EQL) to link artifact from Step2 and Step 5 :

  1. Process Access event from Process A running as normal user to Process B running as SYSTEM (Sysmon 13.30 - Source User and Target User) 
  2. Process A running as normal user (Sysmon 13.30 ParentUser) spawns a child process running as SYSTEM.

sequence with maxspan=1m
  [process where event.code : "10" and
  GrantedAccess values in scope
  winlog.event_data.GrantedAccess :

("0x1000", "0x1400", "0x1F3FFF") and
    winlog.event_data.TargetUser : "NT AUTHORITY\\SYSTEM" and not
    winlog.event_data.SourceUser : "NT AUTHORITY\\*" and
    winlog.event_data.TargetImage : "?:\\Windows\\*.exe"] by process.entity_id
[process where event.code : "1" and
    winlog.event_data.LogonId : "0x3e7" and
    winlog.event_data.TerminalSessionId : "1" and
    not winlog.event_data.ParentUser : "NT AUTHORITY\\*"] by process.parent.entity_id

Testing our detection logic

Same logic triggers on malwares such as Glupteba and Zenpack implementation:

For Sysmon config I would recommend to limit it to commonly targeted System processes like winlogon.exe, lsass.exe and TrustedInstaller.exe if you want to limit sysmon 10 eventing volume. 

Monday, 24 May 2021

Hunting for Suspicious Usage of Background Intelligent Transfer Service (BITS)

BITS Overview

Background Intelligent Transfer Service (BITS) is used by programmers and system administrators to download files from or upload files to HTTP web servers and SMB file shares. 

BITS will take the cost of the transfer into consideration, as well as the network usage so that the user's foreground work has as little impact as possible. BITS also handles network interruptions, pausing and automatically resuming transfers, even after a reboot, which makes it a very good candidate for implant Command and Control standard tasks (download, upload and ex-filtration). 

BITS includes PowerShell cmdlets for creating and managing transfers as well as the BitsAdmin command-line utility.

BITS is composed of a Client (i.e. bitsadmin, powershell) loading Bitsproxy.dll, qmgrprxy.dll or  Microsoft.BackgroundIntelligentTransfer.Management.Interop.dll and a Server (svchost.exe with the process's command-line value contains the keyword "BITS" and hosting the service DLL qmgr.dll):

Figure 1 - BITS Client

Figure 2 - BITS Server

Communication between the BITS client and server is performed via RPC, and the IBackgroundCopyManager  is the main BITS interface used to enumerate or create new BITS Jobs:

Figure 3 - OleView  of the BITS service exposed interfaces

  Figure 4 - BITS IBackgroundCopyManager Interface exposed Methods

Figure 5 - BITS JOB TYPE

From a behavior perspective all the download and upload activities are performed by the BITS server (svchost.exe) impersonating the BITS client which breaks the link between the client and the server if using standard monitoring telemetry such as Sysmon network and file creation events.

BITS can be also abused for persistence by setting a command to run every time a transfer job enters the BG_JOB_STATE_ERROR or BG_JOB_STATE_TRANSFERRED state using the IBackgroundCopyJob2::SetNotifyCmdLine method (i.e. bitsadmin.exe /SetNotifyCmdLine) which will result in a malicious program or command to be run persistently on a target system.

 Figure 6 - BITS SetNotifyCmdLine Parameters

Detection and Hunting

From a detection and forensics perspective Windows provides good logging events for the BITS client activities via the Microsoft-Windows-Bits-Client provider (enabled by default), key events are:
  • EventID 3 - BITS service created a new Job
  • EventID 59 - BITS started the <jobname> transfer job that is associated with URL.
  • EventID 60 - BITS stopped transferring the <jobname> transfer job that is associated with the URL. The status code is 0xxxx.
  • EventID 4 - The transfer job is complete
  • EventID 5 - Job cancelled.
  • Other events that are related to performance and transfer errors
Events such as 59, 60 and 61 contains the download/upload URL (very useful for forensics and detection) and event 3 contains the details of the BITS client process path and the Job name (very useful for detecting abnormal BITS clients).

Below example of BITS events resulting from this malware sample (Remcos or Netwire RAT loader):

  Figure 7 - BITS Client Event Logs 3 and 60        

A)  Unusual BITS Client:

By default on a Windows machine there are a limited number of BITS clients (native Windows binaries) and the majority are related to third party programs such as browsers. To baseline the clients we can use Bitsproxy.dll or qmgrprxy.dll ImageLoad events (such as Sysmon EventId 7) or BITS Client Event Logs EventId 3.

By default the following are the known normal BITS client with process path residing under c:\windows\ directory.

c:\Windows\System32\MRT.exe (x)
c:\Windows\System32\svchost.exe (BITS service)

Excluding the above we can hunt/detect for unusual client, below an example of a hunting EQL query:

Figure 8 - Unusual Bits Client Hunt

Figure 9 - Notepad.exe Unusual BITS Client

B) Program Execution via BITS SetNotifyCmdline Persistence: 

Programs set to execute via the SetNotifyCmdline method are a child of the BITS service, there are some legit instances especially signed stuff running from program files directories, but its quite rare:

Figure 10 - Hunt Example for Persistence via BITS SetNotifyCmdline Method

Figure 11 - Malware example persisting via BITS SetNotifyCmdline Method

C) Execution of a File Downloaded via BITS Service:

Last example is to hunt for executable content that is downloaded via BITS service and immediately executed, we can do that by correlating File rename event (old file name always follow this pattern BITXXXX.tmp and renamed to the target file name)  by the BITS service followed by process execution by file.path/process.executable:

Figure 12 - Download & Execution of a file via BITS using PowerShell

As you can see below we can link the file download activity to the process execution event:

Figure 13 - Hunt for Process Execution of a File Downloaded via BITS service

Figure 14 - Hunt Results for Process Execution of a File Downloaded via BITS service

There other scenarios but that should give you an idea of the building blocks and how to play with them to spot unusual combinations.

Monday, 4 January 2021

How to Design Abnormal Child Processes Rules without Telemetry

    In detection engineering we often encounter attack techniques that result into a system process spawning an unusual child process, which can be used as a good detection or hunting logic. The only problem that remains is to exclude legitimate/expected benign child processes,  and for this often we need some endpoint production telemetry (the more the better), unfortunately not everyone has this privilege. In this post we will share with you some quick steps you can follow to tune your rule with no telemetry access.

For this let's take the example of a malware masquerading as WerFault.exe via hollowing or any equivalent form of injection, and our goal is to detect suspicious instances via looking at any abnormal child process (e.g. cmd.exe):

1) Imported Modules: Step 1 consist of identifying all imported DLL that are specific to the functioning of the subject process (not generic ones such as kernel32.dll, ntdll.dll etc.), in our example we can see 2 modules wer.dll and faultrep.dll:


2) Strings: Step 2 consist of identifying all executables in the process (werfault.exe) strings and also the previously identified function specific DLLs (wer.dll, faultrep.dll):

Of course not all programs names are valid child processes of WerFault.exe, to confirm which one are potential benign/expected child processes we need to move to the next step. 

3) Process Creation APIs: goal here is to identify all references to process creation related APIs (CreateProcessA/W, CreateProcessAsUserA/W, CreateProcessInternal, WinExec,  ShellExecute , ShellExecuteEx, NtCreateProcess, ZwCreateProcess  etc.). we will need to start first with those extracted directly from WerFault.exe, and then repeat same steps for the function specific DLLs.

For brevity we will show the steps for WerFault.exe example only, open your subject process in your favorite disassembler (you don't need to be a reverser!) and go to the the imports view, then search for the process creation related APIs:

Next double-click on the matched API name, then right-click or X to display the functions that use this API:

 As you can see below, we have only 6 functions to check, you can also start from the process names identified in Step 2 (Strings View), but for better flow and understanding start first with the APIs XREFs:

The CreateProcess API arguments that we care about (point the potential benign child process we are looking for) are lpCommandLine or lpApplicationName:

In the example of the CInpagePlugIn::StartCoFireProcess function we can see that the cofire.exe t is a potential child process.

In this case it was easy (adjacent to the API call), in other cases you will need to drill-down a couple of functions to find the ApplicationName or CommandLine being populated, you can always go back to the Program names extracted at phase 2 and cross reference the function that uses them for correlation. 

Psr.exe is another potential child process referenced in CAppRecorderPlugin::StopRecordingSession 

4) Going back to Step 1 if needed:  before repeating the same steps 1, 2 and 3 on wer.dll and faultrep.dll, first check via strings or checking the Import Table the presence of any process creation related APIs:

In case of no references to process names or process creation APIs, it's safe to move directly to step 5.

5) Detection Logic: Last step is straightforward, look for process with parent process name equal to WerFault.exe and process name is different than the identified potential benign child processes:

process where == "werfault.exe" and not in ("cofire.exe", "psr.exe, ", "VsJITDebugger.exe", "TTTracer.exe", "rundll32.exe")

  Of course this approach will miss in some instances potential false positives such as processes created with arguments passed via standard input, config files, registry values, COM, RPC and equivalent :

above you can see an example where a potential child process name is extracted from the registry values ReflectDebugger. or Debugger:

This method is time consuming but still if applied to a limited number of target processes it can provide you with an initial working detection rule with minimum noise and with no access to production endpoint process execution telemetry.