Stuxnet

worm that was originally aimed at Iran's nuclear facilities, mutated and spread to other industrial and energy-producing facilities

Memory image

Download the memory image containing Stuxnet malware from here and unzip it.

unzip ~/Downloads/stuxnet.vmem.zip

Identifying the profile

  • First, we will start by identifying the profile of the memory image using imageinfo plugin.

python2 vol.py -f stuxnet.vmem imageinfo
  • It shows various suggested profiles and we shall consider the first one.

Malicious processes

  • Now that we've found the profile of the memory image, we can start looking for suspicious activities in the memory.

Process scan

  • A good place to start is by looking at all the processes. So, we'll start with psscan

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 psscan
  • Looking at the output, there doesn't seem to be any suspicious process.

  • However, I could spot that there are 3 "lsass.exe" processes in the memory. In an ideal scenario, there should be only 1 "lsass.exe" with "winlogon.exe" as the parent on WinXP systems.

  • "lsass.exe" is responsible for security-related functions, including handling user authentication.

Parent-child relationship

  • We can use pstree plugin to view the parent-child relationship between the processes.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 pstree
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 pstree | egrep -i "lsass|winlogon|services" 
  • I've grepped the output for better visibility. As we can see, 2 "lsass.exe" processes with PID 1928 and 868 have the parent of "services.exe" which is not normal. On WinXP systems, the parent process should be “winlogon.exe”.

  • It is also worth looking at "svchost.exe". In an ideal system, it should have a parent of "services.exe". Here it seems legit.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 pstree | egrep -i "svchost|services" 

Process path

  • Now that we have 2 suspicious processes (1928, 868) to look out for, we'll check their path.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 cmdline | egrep -i lsass 
  • We can see from the output that these processes are running from a legit path.

Injected code

  • Next, we'll use the malfind plugin to identify hidden and injected code in those processes.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 malfind -p 1928 
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 malfind -p 868 
  • As we see, these 2 processes have memory regions with the protection of PAGE_EXECUTE_READWRITE. Typically, memory sections shouldn't be executable and writable simultaneously.

  • The process name and path of those 2 suspicious processes are legit but we have multiple instances of those running with their memory regions with wrong protection.

  • This might be because the process is hollowed out, meaning the process would have been duplicated in a suspended state and the executable portion of the processes is replaced with malicious code. Now when that process resumes, the name and the path are maintained. This is called Hollow Process Injection.

  • We can use a plugin called hollowfind for those 2 PIDs to identify this.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 hollowfind -p 868 
  • From the output, along with other details, we can also see that the path of the process is empty in VAD but is present in PEB. This discrepancy is caused because of Hollow Process Injection.

  • The output also shows us similar processes and suspicious memory regions to look out for.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 hollowfind -p 1928 
  • We can also verify the other "lsass.exe" (PID of 680 - which had the valid parent process) if it has injected code or not.

  • From the output, we can see that it is clean.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 malfind -p 680 
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 hollowfind -p 680
  • Now we can confirm from our analysis that the processes 1928 and 868 are hollowed out and in fact malicious.

Dump malicious processes

  • Finally, we can now proceed to dump those processes using procdump and verify our conclusions that those processes are malicious.

  • Create a folder to dump those processes.

mkdir procdump/
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 procdump -p 1928,868 -D procdump/

Investigate process hash

  • Let's find the hashes of those dumped files and investigate in VirusTotal.

file procdump/*
sha256sum procdump/*
  • By investigating those hashes with VirusTotal, we can confirm that those processes are indeed malicious.

Now that we have found the malicious processes, it is important to extract as many Indicators of Compromise (IOCs) as possible, so that it is easier to detect on other systems in the network.

C2 connections

  • Another common way to investigate is to look for suspicious network connections that the malicious processes might establish to their Command & Control servers.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 connections
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 connscan
  • We can see that there are no open connections from this memory. Let's move on.

Suspicious Registry entries

  • One important thing that malware does is persist system reboots. So let's check in the registry if there are any persistence mechanisms added by the malware.

List of hives

  • We can start by listing out the registry hives loaded in the memory using hivelist plugin.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 hivelist

Dump registries

  • Now let us dump all these registries using dumpregistry plugin for further analysis.

  • Make sure to create an output directory for that.

mkdir regdump/
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 dumpregistry -D regdump/

Investigate registries

  • To find the entry of the malicious "lsass.exe" processes in the registry, we'll run strings against all those registry dumps.

  • We'll use "strings" along with the following flags:

    • -f : to print the name of the file before each identified string

    • -a : to scan the entire file and not just the data section

    • -el : to specify the encoding to be 16-bit little-endian (encoding of Windows registries)

strings -fa -el regdump/* | egrep -i "lsass.exe"
  • So the "lsass.exe" is mentioned in the "system" hive.

  • This hive can be used by malware to achieve system-level persistence, like adding drivers.

Unknown Drivers

  • Now that we know that the malicious process might have added drivers to achieve persistence, let's look at the drivers.

Malicious drivers

  • Since we don't know the driver names, we can look for callbacks that are used by processes in user space to communicate with kernel space. There is a plugin called callbacks to identify them.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 callbacks
  • After manually reading about each module, we can zero down on "mrxcls.sys" and "mrxnet.sys" as being undesirable.

  • To investigate further, we need to dump the modules. To dump the modules, we need the base address of those modules. For this, we can use modules plugin and grep for those modules.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 modules | egrep -i "mrxnet|mrxcls" 

Dump drivers

  • Now that we know the base address of those drivers, we can proceed to dump them using moddump plugin and specify the base address.

  • As always, create a dump directory.

mkdir moddump/
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 moddump -b 0xf895a000 -D moddump/
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 moddump -b 0xb21d8000 -D moddump/

Investigate driver hash

  • Also running file against those dumped modules shows us they are PE32 executable (native) which confirms they are driver files.

file moddump/*
  • Now, let's find out the hashes of these possibly malicious drivers and investigate in VirusTotal.

sha256sum moddump/*
  • This confirms that these drivers are malicious. Let's not stop here.

Search for driver entries

  • Now that we have the malicious driver names, we can also look if they have entries in the registries by running strings on the registry dump as before and grep for those driver names.

strings -fa -el regdump/* | egrep -i "mrxnet|mrxcls"
  • We again see there are entries in the "system" hive which show the location of the drivers.

  • Now we will usereglookup on the "system" hive and grep for those malicious drivers to find out where the location of the drivers is mentioned.

reglookup regdump/registry.0xe1035b60.system.reg | egrep -i "mrxnet.sys|mrxcls.sys" 
  • From the output, we can see various things:

    • The presence of the MRxCls and MRxNet subkey under Services indicates that the malware is trying to register services with those names.

    • ImagePath value name is set to the path of the drivers, linking the services "MRxCls" and "MRxNet" with the drivers "mrxcls.sys" and "mrxnet.sys" respectively.

  • Now, we would also like to see what other values are there within the malicious service names. We can see this by using the printkey plugin and giving the keys we found in the reglookup output.

python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 printkey -K "ControlSet001\Services\MRxCls" 
python2 vol.py -f stuxnet.vmem --profile WinXPSP2x86 printkey -K "ControlSet001\Services\MRxNet" 
  • While I missed adding the output of the printkey command, it shows that the Start value of both services is set to 1.

  • Upon research, we can see that the Start value of 1 corresponds SERVICE_SYSTEM_START which means the service is started automatically during system boot. This is the persistence mechanism the malicious drivers are using.

  • Also, don't forget to learn about the other details from the output, like Group, Type etc.

Now that we extracted most of the information from the memory (to the best of our knowledge), let's list them down!

Indicators Of Compromise

The presence of Stuxnet can be identified with the help of the below IOCs.

Processes

  • Process name: lsass.exe (multiple running instances in memory)

Drivers/Files

  • Driver name: mrxnet.sys

  • Driver path: C:\WINDOWS\system32\Drivers\mrxnet.sys

  • Driver name: mrxcls.sys

  • Driver path: C:\WINDOWS\system32\Drivers\mrxcls.sys

Registry entries

  • Registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\MRxNet

    • Value: ImagePath Data: C:\WINDOWS\system32\Drivers\mrxnet.sys

    • Value: Start Data: 1

  • Registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\MRxCls

    • Value: ImagePath Data: ??\C:\WINDOWS\system32\Drivers\mrxcls.sys

    • Value: Start Data: 1

Last updated