Mark Russinovich’s technical blog covering topics such as Windows troubleshooting, technologies and security.
In the first post of this series, I used Autoruns, Process Explorer and VMMap to statically analyze a Stuxnet infection on Windows XP. That phase of the investigation revealed that Stuxnet infected multiple processes, launched infected processes that appeared to be running system executables, and installed and loaded two device drivers. In the second phase, I turned to the Process Monitor trace I had captured during the infection and learned that Stuxnet had launched several additional processes during the infection. The trace also uncovered the fact that Stuxnet had dropped four files with the .PNF extension into the C:\Windows\Inf directory. In this concluding post, I use the Sysinternals tools to try to determine the purpose of the PNF files and to look at how Stuxnet used a zero-day vulnerability on Windows 7 (since fixed) to elevate itself to run with administrator rights.
My first step in gathering clues about the .PNF files was to just see how large they were. Tiny files would probably be data and larger ones code. The four .PNF files in question are the following, listed with the sizes in bytes I observed in Explorer:
I also dumped the printable characters contained within the files using the Sysinternals Strings utility, but saw no legible words. That wasn’t surprising, however, because I expected the files to be compressed or encrypted.
I thought that by looking at the way Stuxnet references the .PNF files, I might find additional clues regarding their purpose. To get a more complete view of their usage, I captured a Process Monitor boot log of the system rebooting after the infection. Boot logging, which you configure by selecting Enable Boot Logging in the Options menu, has Process Monitor capture activity from very early in the next boot and stop capturing either when you run Process Monitor again, or when the system shuts down:
After capturing a boot log that included me logging back into the system, I loaded the boot log into one Process Monitor window and the initial infection trace into a second Process Monitor window. Then I reset the filters in both traces, removed the advanced filter that excludes System process activity, and added an inclusion filter for Mdmeric3.pnf to see all activity directed at the first file. The infection trace had the events related to the initial creation of the file and nothing more, and the file wasn’t referenced at all in the boot log. It appeared that Stuxnet didn’t leverage the file during the initial infection or in its subsequent activation. The file’s small size, 90 bytes, implies that it is data, but I couldn’t determine its purpose based on the little evidence I saw in the logs. In fact, the file may serve no useful purpose since none of the published Stuxnet reports have anything further to say about the file other than that it’s a data file.
Next, I repeated the same filtering exercise for Mdmcpq3.pnf. In the infection log, I had seen the Services.exe process write the file’s contents three times during the initial infection, but there were no accesses afterward. In the boot trace, I could see Services.exe read the file immediately after starting:
The fact that Stuxnet writes the file during the infection and reads it once when it activates during a system boot, coupled with the file’s relatively small size, hints that it might be Stuxnet configuration data, and that’s what formal analysis by antivirus researchers has concluded.
The third file, Oem7a.pnf, is the largest of the files. I saw during my analysis of the infection log in the last post that after the rogue Lsass.exe writes the file during the infection, one of the other rogue Lsass.exe instances reads it in its entirety, as does the infected Services.exe process. An examination of the boot log showed that Services.exe reads the entire file when it starts:
What’s unusual is that the read operations are the very first performed by Services.exe, even before the Ntdll.dll system DLL loads. Ntdll.dll loads before any user-mode code executes, so seeing activity before then can only mean that kernel-mode code is responsible. The stack shows that they are actually initiated by Mrxcls.sys, one of the Stuxnet drivers, from kernel mode:
The stack shows that Mrxcls.sys is invoked by the PsCallImageNotifyRoutines kernel function. That means Mrxcls.sys called PsSetLoadImageNotifyRoutine so that Windows would call it whenever an executable image, such as a DLL or device driver, is mapped into memory. Here, Windows was notifying the driver that the Services.exe image file was loading into memory to start the Services.exe process. Stuxnet clearly registers with the callback so that it can watch for the launch of Services.exe. Ironically, Process Monitor also uses this callback functionality to monitor image loads.
These observations point at Mrxcls.sys as the driver that triggers the infection of user-mode processes when the system boots after the infection. Further, the size of the file, 498,176 bytes (487 KB), almost exactly matches the size of the virtual memory region, 488 KB, from where we saw Stuxnet operations initiate in Part 1 of the investigation. That region held an actual DLL, so it appears that Oem7a.pnf is the encrypted on-disk form of the main Stuxnet DLL, a hypothesis that’s confirmed by antimalware researchers.
The final file, Oem6c.pnf, is not referenced at all in the boot trace. The only accesses in the infection trace are writes from the initial Lsass.exe process that also writes the other files. Thus, this file is written during the initial infection, but apparently never read. There are several potential explanations for this behavior. One is that the file might be read under specific circumstances that I haven’t reproduced in my test environment. Another is that it is a log file that records information about the infection for collection and review by Stuxnet developers at a later point. It’s not possible to tell from the traces, but antimalware researchers believe that it is a log file.
Many of the operations performed by Stuxnet, including the infection of system processes like Services.exe and the installation of device drivers, require administrative rights. If Stuxnet failed to infect systems with users lacking those rights, its ability to spread would have been severely hampered, especially into the sensitive networks it seems to have been targeting where most users likely run with standard user rights. To gain administrative rights from standard-user accounts, Stuxnet took advantage of two zero-day vulnerabilities.
On Windows XP and Windows 2000, Stuxnet used an index checking bug in Win32k.sys that could be triggered by loading specially-crafted keyboard layout files(fixed in MS10-073). The bug allowed Stuxnet to inject code into kernel-mode and run with kernel privileges. On Windows Vista and newer, Stuxnet used a flaw in the access protection of scheduled task files that enabled it to give itself administrative rights (fixed in MS10-92). Standard users can create scheduled tasks, but those tasks should only be able to run with the same privileges as the user that created them. Before the bug was fixed, Windows would create the file storing a task with permissions that allowed standard users to modify the file. Stuxnet took advantage of the hole by creating a new task, setting the flag in the resulting task file that specifies that the task should run in the System account, which has full administrative rights, and then launching the task.
To watch Stuxnet exploiting the Windows 7 bug, I started by uninstalling the related patch on a test system and monitored a Stuxnet infection with Process Monitor. After capturing the trace, I followed the same steps I described in the last post of setting a filter that discarded all operations except those that modify files and registry keys (“Category Is Write”), and then methodically excluding unrelated events. When I was finished the Process Monitor window looked like this:
The first events are Stuxnet dropping the temporary files that it later copies to PNF files in the C:\Windows\Inf directory. Those are followed by Svchost.exe events that are clearly related to the Task Scheduler service. The Scvhost.exe process creates a new scheduled task file in C:\Windows\System32\Tasks and then sets some related registry values. Stack traces of the events show that Schedsvc.dll, the DLL that implements the Task Scheduler service, is responsible:
A few operations later, Explorer writes some data to the new task file:
This is the operation that shouldn’t be possible, since a standard user account should not be able to manipulate a system file. We saw in the last post that the <unknown> frames in the stack of the operation show that Stuxnet is at work:
The final operations in the trace associated with the task file are those of the Task Scheduler deleting the file, so Stuxnet apparently modifies the task, launches it, and then deletes it:
To verify that the Task Scheduler in fact launches the task, I removed the write filter and applied another filter that included only references to the task file. That made an event appear in the display that shows Svchost.exe read the file after Stuxnet wrote to the file:
As a final confirmation, I looked at the operation’s stack and saw the Task Scheduler service’s SchRpcEnableTask function, whose name implies that it’s related to task activation:
In this concluding segment of my Stuxnet investigation, I was able to use Process Monitor’s boot logging feature to gather clues pointing to the purpose of the various files Stuxnet drops on a system at the time of infection. Process Monitor also revealed the method by which Stuxnet used a flaw in the Task Scheduler service on Windows 7 to give itself administrative rights.
This blog post series shows how the Sysinternals tools can provide an overview of malware infection and subsequent operation, as well as present a guide for cleaning an infection. They showed many of the key aspects of Stuxnet’s behavior with relative ease, including the launching of processes, dropping of files, installation of device drivers and elevation of privilege via the task scheduler. As I pointed out at the beginning of Part 1, a professional security researcher’s job would be far from done at this point, but the view given by the tools provides an accurate sketch of Stuxnet’s operation and a framework for further analysis. Static analysis alone would make gaining this level of comprehension virtually impossible, certainly within the half hour or so it took me using the Sysinternals tools.
Mark Russinovich is a Technical Fellow on the Windows Azure team at Microsoft and is author of Windows Internals, The Windows Sysinternals Administrator’s Reference, and the cyberthriller Zero Day: A Novel. You can contact him at firstname.lastname@example.org.
Mark, thank you SO much for sharing, as usual. This series on Stuxnet, in particular, was a most interesting read, and, as per your usual style, easy to assimilate and follow.
Again, we very much appreciate the Sysinternals tools and your personal interactivity with the tech community.
Good work Dr Mark :)
Mark Please host a online session for the planned seminar, We are all interested in your Zero Day Malware Cleaning with the Sysinternals Tools seminar but really difficult to travel from EU to US for it.
Indeed, I agree, Mark. I understand that it should have been difficult preparing this blog post, in fact more difficult than just learning it for yourself. Thank you.
By the way, Mark, did you use an actual computer or a virtual one?
@RichardVJ the seminar is being simulcast for web viewing.
@Feet Command: virtual
So the ability to modify the task sechduling file. Do you think that that's something someone at Microsoft intentionally enabled for some backwards compatability purposes? I can invision a bug where something with Task Scheulding was broken (or undesirably difficult) because of new admin security models, so someone intentionally shimmed the scenario, by passing the credentials.