Remote Create Instance - dcerpc - wmi

Creating SQL view from Mordor Process Injection dataset

Create Spark session

from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .appName("Spark_Data_Analysis") \
    .config("spark.sql.caseSensitive","True") \
    .getOrCreate()

Unzip Mordor Dataset

! unzip -o ../datasets/covenant_sharpwmi_dcerpc_wmi_remotecreateinstance.zip -d ../datasets/
Archive:  ../datasets/covenant_sharpwmi_dcerpc_wmi_remotecreateinstance.zip
  inflating: ../datasets/covenant_sharpwmi_dcerpc_wmi_remotecreateinstance_2020-08-06035621.json  

Expose the dataframe as a SQL view

wmiJson = '../datasets/covenant_sharpwmi_dcerpc_wmi_remotecreateinstance_2020-08-06035621.json'

wmiDf = spark.read.json(wmiJson)

wmiDf.createOrReplaceTempView('wmi')

Technical Description

WMI is the Microsoft implementation of the Web-Based Enterprise Management (WBEM) and Common Information Model (CIM). Both standards aim to provide an industry-agnostic means of collecting and transmitting information related to any managed component in an enterprise. An example of a managed component in WMI would be a running process, registry key, installed service, file information, etc. At a high level, Microsoft’s implementation of these standards can be summarized as follows > Managed Components Managed components are represented as WMI objects — class instances representing highly structured operating system data. Microsoft provides a wealth of WMI objects that communicate information related to the operating system. E.g. Win32_Process, Win32_Service, AntiVirusProduct, Win32_StartupCommand, etc.

One well known lateral movement technique is performed via the WMI object — class Win32_Process and its method Create. This is because the Create method allows a user to create a process either locally or remotely. One thing to notice is that when the Create method is used on a remote system, the method is run under a host process named “Wmiprvse.exe”.

The process WmiprvSE.exe is what spawns the process defined in the CommandLine parameter of the Create method. Therefore, the new process created remotely will have Wmiprvse.exe as a parent. WmiprvSE.exe is a DCOM server and it is spawned underneath the DCOM service host svchost.exe with the following parameters C:\WINDOWS\system32\svchost.exe -k DcomLaunch -p. From a logon session perspective, on the target, WmiprvSE.exe is spawned in a different logon session by the DCOM service host. However, whatever is executed by WmiprvSE.exe occurs on the new network type (3) logon session created by the user that authenticated from the network.

Additional Reading

  • https://github.com/hunters-forge/ThreatHunter-Playbook/tree/master/docs/library/logon_session.md

Filtering data

Look for wmiprvse.exe spawning processes that are part of non-system account sessions.

processCreation = spark.sql(
'''
SELECT `@timestamp`, Hostname, SubjectUserName, TargetUserName, NewProcessName, CommandLine
FROM wmi
WHERE lower(Channel) = "security"
    AND EventID = 4688
    AND lower(ParentProcessName) LIKE "%wmiprvse.exe"
    AND NOT TargetLogonId = "0x3e7"
''')

print('This dataframe has {} records!!'.format(processCreation.count()))
processCreation.show(vertical = True, truncate = False)
This dataframe has 1 records!!
-RECORD 0--------------------------------------------------
 @timestamp      | 2020-08-06 03:56:43.178                 
 Hostname        | WORKSTATION6.theshire.local             
 SubjectUserName | WORKSTATION6$                           
 TargetUserName  | pgustavo                                
 NewProcessName  | C:\Windows\System32\GruntHTTP2.exe      
 CommandLine     | "C:\\Windows\\System32\\GruntHTTP2.exe" 

Correlating data

Look for non-system accounts leveraging WMI over the netwotk to execute code

authenticationNetwork = spark.sql(
'''
SELECT o.`@timestamp`, o.Hostname, o.SubjectUserName, o.TargetUserName, o.NewProcessName, o.CommandLine, a.IpAddress
FROM wmi o
INNER JOIN (
    SELECT Hostname,TargetUserName,TargetLogonId,IpAddress
    FROM wmi
    WHERE lower(Channel) = "security"
        AND LogonType = 3
        AND IpAddress IS NOT NULL
        AND NOT TargetUserName LIKE "%$"
    ) a
ON o.TargetLogonId = a.TargetLogonId
WHERE lower(o.Channel) = "security"
    AND o.EventID = 4688
    AND lower(o.ParentProcessName) LIKE "%wmiprvse.exe"
    AND NOT o.TargetLogonId = "0x3e7"
'''
)

print('This dataframe has {} records!!'.format(authenticationNetwork.count()))
authenticationNetwork.show(vertical = True, truncate = False)
This dataframe has 1 records!!
-RECORD 0--------------------------------------------------
 @timestamp      | 2020-08-06 03:56:43.178                 
 Hostname        | WORKSTATION6.theshire.local             
 SubjectUserName | WORKSTATION6$                           
 TargetUserName  | pgustavo                                
 NewProcessName  | C:\Windows\System32\GruntHTTP2.exe      
 CommandLine     | "C:\\Windows\\System32\\GruntHTTP2.exe" 
 IpAddress       | 172.18.39.5                             

Thank you! I hope you enjoyed it!