Writing a Function to Query Elasticsearch and return us a dataset to work on¶
In [4]:
def queryes(query) :
print(query)
s = searchContext.query('query_string', query=query).filter('range' , **{'@timestamp': {'gte': 20211220 , 'lt': 20211222, 'format' : 'basic_date'}})
response = s.execute()
if response.success():
df = pd.json_normalize((d.to_dict() for d in s.scan()))
sdf=spark.createDataFrame(df.astype(str))
clean_df = sdf.toDF(*(c.replace('.', '_') for c in sdf.columns))
clean_df = clean_df.toDF(*(c.replace('@', '') for c in clean_df.columns))
return clean_df
else :
print("Es query Failed")
In [5]:
# Gathering File Write Operations
dataset= queryes("event.category:file AND event.action:creation")
dataset.createOrReplaceTempView('dataset')
Unstructured Hunt: Looking for anomalous File Write Operations in Temporary File Directory¶
In [6]:
df1=spark.sql('select count(*) as count,file_name,process_name,process_parent_pid from dataset where (file_name like "%exe%" OR file_name like "%dll%") GROUP BY file_name,process_name,process_parent_pid order by process_name desc;')
df1.show(1000,truncate=False)
Suspicious Observation: MsMpEng.exe Binary in temporary Location is Suspicious at first glance, what is MS-defender Binary doing in a temporary location. Also, Agent.exe doesn't seem to be a LOLBIN and seems to be a 3rd party binary.¶
In [7]:
df1=spark.sql('select Distinct process_name,process_parent_pid from dataset where (file_name like "%exe%" OR file_name like "%dll%");')
df1.show(1000,truncate=False)
Interestingly we have two entries where file write was performed by Agent.exe, Let's Pull Process Data to Correlate!!¶
In [8]:
#pulling Process Dataset
proc_dataset=queryes("event.category:process")
proc_dataset.createOrReplaceTempView('processes')
Process Hashes of Processess Writing in the Directory :¶
In [9]:
spark.sql("select distinct p.process_name,p.process_code_signature_status,p.process_hash_sha256,d.file_name from processes p, dataset d where p.process_pid = d.process_pid AND (d.file_name like '%exe%' OR d.file_name like '%dll%') order by p.process_name").show(1000,truncate=False)
Suspicious Observation: Agent.exe Doesn't seem to have very good Reputation !!!!¶
let's gather Hashes& CommandLines of these Process Executables Create a table of Parent Process, Child Process and Files Written on Disk¶
In [10]:
spark.sql("select distinct d.process_name as writing_process, d.file_name as dropped_file, p.process_parent_name as Parent_process,p.process_command_line as writing_process_cmdLine,\
p.process_code_signature_status,p.process_hash_sha256 \
from processes p, dataset d where p.process_name = d.process_name and d.process_name='Kaseya_agent.exe'").show(200,truncate=False, vertical=True)
Now there are enough pieces of information to Chase this Rabbit Hole for Suspicious Agent.exe:¶
Msmgeng.exe written in temporary Location is Suspicious(Reason: What's a defender binary doing in temporary Location)
A non-Windows Process write Defender binary (Reason: the operation is suspicious cause the process tree is like: Explorer.exe -> Agent.exe -> Drop MsMpEng.exe)
A DLL file is also dropped by the same process (Reason: Could be Masquerade, Could be Tampered DLL, Could be payload embedded in DLL Entry Point, Could be DLL Search order hijacking attacks, DLL Side-loading attacks, lots of possibilities)
A sub-hypothesis could be devised at this point to chase this path: Malware Dropped by non-legitimate process and proceed with Investigation, Sample Acquisition, Reverse Engineering, Malware Sandboxing, Detonation.¶
Structured Hunt: MsMpEng.exe & mpsvc.dll Binary dropped in Temporary Location¶
Note: I won't suggest this structured Hunt, although this could be converted into detection in your EDR, This Hunt falls too low on the Pyramid of Pain and although there is a behavior exhibited but is not really a behavioral search hence an attacker could easily pass this Hunt/Detection Technique
In [11]:
spark.sql("select distinct p.process_parent_name as Parent_process,p.process_command_line as writing_process_cmdLine,d.process_name as writing_process,p.process_code_signature_status,p.process_hash_sha256,d.file_name from processes p, dataset d where p.process_name = d.process_name and (d.file_name='MsMpEng.exe' OR d.file_name='mpsvc.dll')").show(200,truncate=False,vertical=True)
Unstructured Hunt: DLL library Loaded from a temporary Location¶
In [12]:
#Pulling DLL Loading dataset from Elastic
dll_dataset=queryes("event.category :library")
dll_dataset.createOrReplaceTempView('lib_dataset')
In [13]:
spark.sql("select distinct lib_dataset.process_name as Process_name, lib_dataset.process_executable as Process_path, dll_name as DLL_loaded , dll_path from lib_dataset where lib_dataset.dll_path like '%Temp%'").show(truncate=False)
spark.sql("select process_name,process_command_line from processes where process_name in ('netsh.exe','certutil.exe','MsMpEng.exe','setup.exe','MpCmdRun.exe')").show(2000, False)
MpCmdRun.exe -> Interesting event where MpCmdRun.exe is trying to disable the Service.
Netsh.exe -> Interesting attempt of turning on Network Discovery using netsh.exe
Certutil.exe ->These are my executions where I was trying to match the hash of a file with the sample I acquired, THese can be Ignored.
Setup.exe -> This is Microsoft edge Installation. for when my windows OS updated.Can be Ignored.
MsMpEng.exe ->Execution from Temporary location, Execution of v4.18.2111 from ProgramData
Netsh.exe execution clearly shows Modification of system configuration for lateral Movement hence could be converted into a detection/Structred Hunt.¶
In [55]:
spark.sql("select process_name,process_command_line from processes where process_name ='netsh.exe' and process_command_line='netsh advfirewall firewall set rule group=\"Network Discovery\" new enable=Yes'").show(2000, False)
+------------+----------------------------------------------------------------------------+
|process_name|process_command_line |
+------------+----------------------------------------------------------------------------+
|netsh.exe |netsh advfirewall firewall set rule group="Network Discovery" new enable=Yes|
|netsh.exe |netsh advfirewall firewall set rule group="Network Discovery" new enable=Yes|
+------------+----------------------------------------------------------------------------+
DLL Side-loading via MsMpEng.exe - Details¶
We saw that the MsMpEng.exe binary was dropped on the machine along with mpsvc.dll which were actually used for malicious intent. We also do understand that mpsvc.dll was sideloaded into MsMpEng.exe, but there are a few questions that we need to find answers to understand what happened.
Why drop MsMpEng.exe, when it is already present on the Machine a Lolbin ???¶
In [65]:
#grabbing all the processes that correlated to MsMpEng.exe on the Endpoint
spark.sql("select distinct(process_hash_sha256),process_name,process_command_line from processes where process_name like '%MsMpEng.exe%'").show(100,truncate = False, vertical = True)
As you can observe there are two hashes for MsMpEng.exe, One is of the original Binary and another one of the Dropped Binary. Correlating data from VirusTotal :
33bc14d231a4afaa18f06513766d5f69d8b88f1e697cd127d24fb4b72ad44c7a(Dropped Binary) hash is also benign and is a signed legitimate binary
a7c1fe30930d982d69cc263076142edb451ae896b67efbca347b54e064c93bb9(Original Binary) is also a legitimate and signed binary, except for the fact that this binary is newer (V4.18) while the dropped one is older (V4.5)
The older MsMpEng.exe was susceptible to DLL Side loading Technique and hence was perfect for targetting and attacking
The Actual Jupyter Notebook is Located Here, Feel free to Download and use.