I feel somewhat sorry for posting such a creepy title in spring. But don't worry, "mutant" is just how a mutex is called in the Windows kernel. A mutex helps to serialize access to a resource. Some applications employ a mutex to ensure that only a single instance is running. And that way, a mutex may lead us directly into the dark realms of some malware. Scary, isn't it?
A mutex is a concept that is widely used in concurrent programming. Assume that that there is a global counter variable that is set to 0 and two threads. The threads will increment the variable by reading its value, incrementing and finally storing the new value. If both threads process the variable in sequence, the we will end with a value of 2. Now assume that thread 1 gets interrupted after it has read the counter (still at 0). While thread 1 is suspended, thread 2 processes the variable and the counter now is 1. Finally the scheduler resumes thread 1. It also increments the previously stored value and writes it back into the global variable. And the counter now reads... 1! Crash!
In order to ensure mutual-exclusive access to the counter both threads should mark their three steps as a "critical section" or acquire a mutex on the global variable, compute and store the new value and then end the critical section or release the mutex. The second thread could then wait for the mutex to be released and then process the counter in a safe way.
There are two kinds of mutexes in the Windows kernel. Fast mutexes, also known as executive mutexes, are frequently used all over the kernel. As their name implies, they provide a mutual exclusion mechanism at a low overhead (guard mutexes of Windows Server 2003 and later are even faster). However, for the rest of this article we will be interested in mutex (or mutant) objects only.
Applications may create a global mutant with their name or some magic string. If a second instance of that application is launched, the creation of the mutant will fail and the program terminates. The mutant provides an easy means to ensure that only a single instance of that application is running. Malicious software uses this technique to avoid multiple infections of the same system.
Other software, both malicious and non-malicious, may create named mutants of other strains of malware in order to "vaccinate" a system. So, the existence of a known-bad mutant is not proof of an infection, but it justifies a closer examination.
The definition of the _KMUTANT structure is available from the kernel's debug symbol file:
kd> dt _KMUTANT nt!_KMUTANT +0x000 Header : _DISPATCHER_HEADER +0x010 MutantListEntry : _LIST_ENTRY +0x018 OwnerThread : Ptr32 _KTHREAD +0x01c Abandoned : UChar +0x01d ApcDisable : UChar
From the proper _OBJECT_TYPE structure we learn about the pool tag ("Muta") and that mutant objects reside in the nonpaged pool. The Microsoft debugger tells us about the typical allocation sizes:
kd> !poolfind Muta Searching NonPaged pool (810c2000 : 812c2000) for Tag: Muta 810dd5e0 size: 40 previous size: 18 (Allocated) Muta (Protected) 810dd650 size: 40 previous size: 30 (Allocated) Muta (Protected) 810e15f0 size: 50 previous size: 30 (Allocated) Muta (Protected) 810e1a48 size: 40 previous size: 30 (Allocated) Muta (Protected) 810e3d50 size: 50 previous size: 30 (Allocated) Muta (Protected) 810e3e20 size: 50 previous size: 30 (Allocated) Muta (Protected) 810e5dd0 size: 40 previous size: 40 (Allocated) Muta (Protected)
A closer examination shows that _KMUTANT always is of the same size. Again it is the _OBJECT_HEADER that varies in size; some headers also contain an object name, which is exactly what we're interested in.
Again, I wrote a plugin for the Volatility memory analysis framework. Please make a backup copy of your installation before you unzip the archive in the Volatility base directory. If you use the version from the current Volatility SVN, then please copy only the plugin file.
>volatility mutantscan -s -f exemplar7.vmem
Phys.Addr. Obj Type #Ptr #Hnd Signal Thread CID Name 0x01825480 0x817c9858 2 1 0 0x813dada8 312:532 9g234sdfdfgjf2304 0x018e2278 0x817c9858 2 1 0 0x8145a020 1092:1440 DLL32M
The above output tells us whether the mutant is in its signaled ("released") state and which thread acquired the mutant. From the associated thread object we then learn about the client ID (CID), which is shown in the format of process:thread. Both identifiers are printed in decimal.
Now we query the list of running processes (truncated) to find the processes by their PID:
Name Pid PPid Thds Hnds Time pp04.exe 312 264 1 33 Thu Jan 08 01:51:57 2009 rundll32.exe 1092 1948 2 46 Thu Jan 08 01:52:03 2009