PART 1: HOW THE TECHNIQUE WORKS
If no “evasion” techniques are used, services are typically created through a standard Windows API call to “CreateServiceA” or “CreateService” – you can read the
full documentation for this API here. This API is also called whenever you use the native Windows executable “sc.exe” to register a service on a machine. A call to this API subsequently generates entries in the event log which corresponds to the service creation event IDs that a responder would be used to seeing.
Threat actors can create services without relying on the typical API call to “CreateServiceA” by directly interacting with the Windows native API calls. For example, the “StartService” API will a make a call to the native API “NdrClientCall2” along with registering the service start events in the event logs. However, by directly calling “NdrClientCall2” to start a service that’s had the registry keys manually created – the service is started and running and no correlating event logs are created – thus evading detection. This will result in a malicious service running and no correlating event log entry. To take this a step further, the threat actors can then remove the evidence in the registry and any correlating evidence loaded in the memory of “services.exe”. This leaves you with little to no registry artefacts and no event log information to analyse.
Stuxnet utilises this technique to register two malicious services to run malicious kernel drivers using a call to the native API “NtLoadDriver”. However, the malware did not remove the artefacts hidden within the registry (because these registry values are required to call NtLoadDriver). This API is documented in the
NTAPI Undocumented Functions website here. To call the API, you just pass one value – the driver name and ensure that the registry has had the path to the malicious driver set.
Normally, when given a memory sample, analysts will run the “svcscan” plugin in Volatility to hunt for services. When confronted with Stuxnet – you will notice this does not return results showing the malicious services. The two malicious services that exist in Stuxnet are called “mrxnet” and “mrxcls”. Running the “svcscan” module you cannot see evidence of these services existing either.
However, referring to the documentation on NtLoadDriver where a registry value needs to be set. Iterating through the registry keys within the memory sample shows that these services indeed exist. So why is this the case? Why didn’t the svcscan plugin pick up on this service?
This is an important place to reflect because it’s important for analysts to understand how the tools they use “work”. Reliance on running plugins without understanding how they work may hamstring an analyst’s ability to figure out alternate methods to hunt.
PART 2: WHY DOESN'T 'SVCSCAN' DETECT THIS?
These two methods do not detect the malicious Stuxnet services because by directly calling native APIs instead of the standard APIs, Service Control Manager (SCM) is bypassed meaning there are no service records created in memory. Let’s go through each of the two methods and why they fail…
Method 1: Traversing the VAD tree looking for memory sections in “services.exe” that might show malicious running services.
The plugin “svcscan” traverses the VAD tree. The VAD is a Virtual Address Descriptor and is used to store the memory ranges used by a process in the structure of a hierarchical tree. As Stuxnet directly interacts with NTLoadDriver, there is no correlating “data” in the process memory of services.exe, thus, traversing the VAD tree will not return any information on the two malicious services.
Method 2: Looking for service records in the memory sample with tags “sErv” and “serH”
This technique iterates through the entire memory sample looking for any service records with those tags that might have been unlinked from Service Control Manager’s (SCM) doubly linked list. This method fails because there is no creation of a correlating service record _SERVICE_RECORD structure when a call to NtLoadDriver is made.
This is why looking for “sErv” and “serH” tags does not detect the services because the record was never created. Service Control Manager (SCM) stores information about services that are installed on a machine in a linked-list or a doubly-linked list. The screenshot below shows the organisation of this structure in a doubly-linked list (older versions of Windows) as “ServiceList” at 0x0.
PART 3: DETECTION METHODOLOGY
When hunting for malicious service creations – this is the logic I would apply from start to finish. Always look for correlating evidence that strengthens a finding versus settling from the results of 1 artefact.
The general IR workflow for most malware / less sophisticated threat actors, the below bullet points cover the course of action. In the instance of Stuxnet, these detection techniques may not have provided any findings nor enough information to determine the malicious drivers and services.
1. Review event logs for 7045, 7035, 7034, 7036, 7040, 4697 service creation
2. Review registry keys for services:
- HKLM\SYSTEM\CurrentControlSet\Services
- HKLM\SYSTEM\ControlSet001\Services
- HKLM\SYSTEM\ControlSet002\Services
3. Review command line logging for signs of services being created using “sc.exe”, “at.exe”
4. Review artefacts for execution i.e. Shimcache, Prefetch, Amcache
5. Review $MFT/$I30 for signs of malicious file creation (i.e. dropped .DLLs, .EXEs etc)
6. Use Volatility “svcscan” to pick up on signs of unlinked services and to find services running
In the instance of Stuxnet… the following actions were also required to form a more complete detection as NTLoadDriver was called by Stuxnet to register malicious driver services.
7. Detect the malicious driver on the disk (can also be done without memory forensics by correlating creation timestamps on disk)
8. Correlate the malicious driver files with the loaded kernel modules to PROVE that the service was running on the system. This means these drivers were running.
9. Detect on native API calls to NTLoadDriver and NdrClientCall2 along with other API calls to functions that allow direct writing of registry keys. Normally EDR tools monitor and alert on the calling of StartService and CreateServiceA – but as demonstrated in this post… this method would bypass that detection.
For detection engineers, I would consider looking for calls to NTLoadDriver and NdrClientCall2 along with other API calls to StartService, RegCreateKey, RegSetValue and correlating evidence being written to the registry keys listed above.
Finally, if you’re interested in reading a full write-up on analysing Stuxnet – I really
recommend this write-up by MNIN here. There are a lot of nuanced techniques baked inside this sample.
REFERENCES
https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-createservicea
https://undocumented.ntinternals.net/
http://mnin.blogspot.com/2011/06/examining-stuxnets-footprint-in-memory.html
Comments
Post a Comment