There has passed already a lot of time since the publication of various detailed researches about Stuxnet and its components. All top AV vendors wrote own comprehensive papers, which reveal major information about destructive Stuxnet features. Some information about Stuxnet rootkits were published by Kaspersky here, Symantec here, ESET here. However, the published information is not complete, because each of these documents covers only a specific sample of the rootkit and describes some of its functions. For example, Kaspersky analysis tries to summarize information about known Stuxnet drivers, but it doesn't contain any technical info about it. Another mentioned report from ESET contains information about two Stuxnet drivers, but this is not sufficient for complete summarizing.
First of all, it is need to be clear that from point of view of undocumented Windows kernel exploration, there are no something really interesting in Stuxnet drivers. I mean nothing interesting comparing with such advanced & sophisticated "civilian" rootkits like ZeroAccess or TDL4. These instances can be deeply embedded into a system, bypassing anti-rootkits and deceive low-level disk access tools. In contrast to them, authors of Stuxnet rootkits do not use such deep persistence into a compromised system. This analysis tries to summarize technical information about Stuxnet drivers.
As a starting point of our research, we can take already published information about Stuxnet drivers by Kaspersky. Their analysis Stuxnet/Duqu: The Evolution of Drivers summarizes some information about drivers that have been used by Stuxnet authors in cyber attacks.
Driver 1
File name: MRxCls.sys
SHA256: 817a7f28a0787509c2973ce9ae85a95beb979e30b7b08e64c66d88372aa3da86
File size: 19840 bytes
Signed: No
Timestamp: 2009-01-01 18:53:25
Device object name: \Device\MRxClsDvX
Main purpose: code injection
AV detection ratio: 53/61
First driver contains sensitive text information such as rootkit device name and path to its service into registry as encrypted data. After starting, the driver performs decryption of this data and we can extract it. Note that name of rootkit service is almost matches its device object name. First dword of decrypted data is also interesting, because it stores some flags, which have an impact on driver behaviour. For example, first bit of this dword restricts the work of rootkit code into Windows safe mode, while second is used as anti-debug trick. If second bit and ntoskrnl!KdDebuggerEnabled are active, the driver will not load.
Decrypted rootkit data also stores name of registry value (Data) that is used by the rootkit to determining what files should be injected into processes. So, these decrypted data are stored in the next sequence.
\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Services\MRxCls
Data
\Device\MRxClsDvX
As driver is registered by Stuxnet with "boot" loading type, it can't perform whole initialization in DriverEntry, because neither NT kernel nor file system is ready to perform requests from clients. So, it calls API IoRegisterDriverReinitialization and delays own initialization. After ReInitialize rootkit function gets control, it checks Windows NT version and fills some dynamic imports. It also doing some preparatory operations and calls PsSetLoadImageNotifyRoutine for registering own handler on load image. This handler will response for code injection into processes. Below you can see scheme of rootkit initialization.
The driver registers following IRP handlers.
First of all, it is need to be clear that from point of view of undocumented Windows kernel exploration, there are no something really interesting in Stuxnet drivers. I mean nothing interesting comparing with such advanced & sophisticated "civilian" rootkits like ZeroAccess or TDL4. These instances can be deeply embedded into a system, bypassing anti-rootkits and deceive low-level disk access tools. In contrast to them, authors of Stuxnet rootkits do not use such deep persistence into a compromised system. This analysis tries to summarize technical information about Stuxnet drivers.
As a starting point of our research, we can take already published information about Stuxnet drivers by Kaspersky. Their analysis Stuxnet/Duqu: The Evolution of Drivers summarizes some information about drivers that have been used by Stuxnet authors in cyber attacks.
Driver 1
File name: MRxCls.sys
SHA256: 817a7f28a0787509c2973ce9ae85a95beb979e30b7b08e64c66d88372aa3da86
File size: 19840 bytes
Signed: No
Timestamp: 2009-01-01 18:53:25
Device object name: \Device\MRxClsDvX
Main purpose: code injection
AV detection ratio: 53/61
First driver contains sensitive text information such as rootkit device name and path to its service into registry as encrypted data. After starting, the driver performs decryption of this data and we can extract it. Note that name of rootkit service is almost matches its device object name. First dword of decrypted data is also interesting, because it stores some flags, which have an impact on driver behaviour. For example, first bit of this dword restricts the work of rootkit code into Windows safe mode, while second is used as anti-debug trick. If second bit and ntoskrnl!KdDebuggerEnabled are active, the driver will not load.
Decrypted rootkit data also stores name of registry value (Data) that is used by the rootkit to determining what files should be injected into processes. So, these decrypted data are stored in the next sequence.
\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Services\MRxCls
Data
\Device\MRxClsDvX
As driver is registered by Stuxnet with "boot" loading type, it can't perform whole initialization in DriverEntry, because neither NT kernel nor file system is ready to perform requests from clients. So, it calls API IoRegisterDriverReinitialization and delays own initialization. After ReInitialize rootkit function gets control, it checks Windows NT version and fills some dynamic imports. It also doing some preparatory operations and calls PsSetLoadImageNotifyRoutine for registering own handler on load image. This handler will response for code injection into processes. Below you can see scheme of rootkit initialization.
The driver registers following IRP handlers.
- IRP_MJ_CREATE
- IRP_MJ_CLOSE
- IRP_MJ_DEVICE_CONTROL (fnDispatchIrpMjDeviceControl)
If you are not familiar with Windows NT drivers development, it is worth to note that any driver that allows to open handles on its device, registers, at least, two IRP handlers: IRP_MJ_CREATE for supporting operations ZwCreateFile and IRP_MJ_CLOSE for ZwClose. Our driver supports ZwDeviceIoControl interface, that's why it registers IRP_MJ_DEVICE_CONTROL handler.
Handler fnDispatchIrpMjDeviceControl serves only for one purpose: to call undocumented Windows NT function ZwProtectVirtualMemory. Client should send to driver special IOCTL code 0x223800 for that (DeviceIoControl) and provide a special prearranged structure with parameters for API call. The driver uses buffered I/O.
As we know, function ZwProtectVirtualMemory is not exported by the Windows kernel and this is another task which authors of MRXCLS.sys have been solved. For example, in case of Windows 2000, they try to find function signature with analysis of executable sections of ntoskrnl image. This signature you can see below.
Authors are trying to enumerate all useful ntoskrnl sections and for each of it call special function that performs searching ZwAllocateVirtualMemory by signatures on Windows 2000 or little harder on Windows XP.
Authors are trying to enumerate all useful ntoskrnl sections and for each of it call special function that performs searching ZwAllocateVirtualMemory by signatures on Windows 2000 or little harder on Windows XP.
Main purpose of this Stuxnet rootkit is code injection. As we can see from its code, the driver tries to read configuration data of injection either from registry parameter Data, either from file, if its name is present into malware sample. In analyzed sample, name of configuration file is absent. Injection configuration data is prepared by user mode part of malware. Injection mechanism was perfectly described by ESET in their paper. The driver performs injection into process in two phases: first phase is preparatory and second is major.
On second phase it tries to read content of file, decrypts it and injects it into process address space. File names for injection are stored into configuration file or registry parameter Data.
As we can see from the code analysis, authors have developed rootkit for injection malicious code into processes. Data for injection is prepared by Stuxnet user mode code. The driver registers handler for image load notify and performs injection into two phases. It also supports one IOCTL command for changing protection for virtual memory pages of process with help of ZwProtectVirtualMemory. For finding this unexported and undocumented function into ntoskrnl, it uses raw bytes search based on special signatures.
Driver 2
File name: Mrxnet.sys
SHA256: 0d8c2bcb575378f6a88d17b5f6ce70e794a264cdc8556c8e812f0b5f9c709198
File size: 17400 bytes
Signed: Yes
Timestamp: 2010-01-25 14:39:24
Device object name: none
Main purpose: malicious files hiding
AV detection ratio: 51/61
Unlike first driver MRXCLS.sys, authors of Mrxnet.sys don't perform anti-analysis checks in the start function of driver. Mrxnet.sys is a FS filter driver that controls some file operations. The rootkit tries to hide some file types by controlling IRP_MJ_DIRECTORY_CONTROL request and removes information about it from buffer.
The rootkit initialization steps.
As we can see from code, the driver plays with two types of devices: firstly its own CDO (Control Device Object) that represents FS filter and secondly devices that were created to filter files related operations on specific volumes. In case of CDO, the rootkit dispatches widely known request IRP_MJ_FILE_SYSTEM_CONTROL and operation IRP_MN_MOUNT_VOLUME. This operation is used by Windows kernel in case of mounting new volume into a system. After got this request, the rootkit creates new device object, registers completion routine and attaches device to newly mounted device. This method allows for driver to monitor appearance in a system new volumes, for example, volume of removable drive.
As you can see from the picture above, the driver also calls IoRegisterFsRegistrationChange I/O manager API for registering its handler that Windows kernel will call each time, when new file system driver CDO is registered into a system. In this handler, the driver creates new device and attaches it to passed CDO or removes device in case of file system driver deletion.
Major purpose of Mrxnet.sys driver is hiding Stuxnet malicious files. Windows kernel provides ZwQueryDirectoryFile API for requesting information about files in directory. This API function calls driver handler of IRP_MJ_DIRECTORY_CONTROL operation. So, the rootkit registers own IRP_MJ_DIRECTORY_CONTROL handler and sets completion routine when such request is passed through handler. In this completion routine it analyzes buffer with data and checks file names in it. It erases from buffer files with extension .LNK and .TMP. It also imposes additional restrictions on hiding. For example, in case of .LNK file, its size should be equal 0x104B.
It should be noted that such technique of files hiding were described in famous book "Rootkits: Subverting the Windows kernel" by Hoglund, Butler.
Driver 3
File name: Jmidebs.sys
SHA256: 63e6b8136058d7a06dfff4034b4ab17a261cdf398e63868a601f77ddd1b32802
File size: 25552 bytes
Signed: Yes
Timestamp: 2010-07-14 09:05:36
Device object name: \Device\{3093983-109232-29291}
Main purpose: code injection
AV detection ratio: 50/61
This driver is pretty similar to MRxCls.sys and serves only for code injection into processes. The following properties distinguish it from original MRxCls.sys.
\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Services\jmidebs
IDE
\Device\{3093983-109232-29291}
The rootkit contains additional IOCTL function, which specializes in caching configuration data. This data are used for injection malicious Stuxnet code.
Driver 4
File name: MRxCls.sys
SHA256: 1635ec04f069ccc8331d01fdf31132a4bc8f6fd3830ac94739df95ee093c555c
File size: 26616 bytes
Signed: Yes
Timestamp: 2009-01-01 18:53:25
Device object name: \Device\MRxClsDvX
Main purpose: code injection
AV detection ratio: 50/61
This sample is identical to driver 1, but signed with digital certificate. Both samples have identical timestamp value in PE header and identical code inside.
Conclusion
As we can see from the analysis, authors of Stuxnet Ring 0 part were interested in code injection and malicious files hiding. Driver MRxCls.sys has two instances, one unsigned and another with digital signature. Both drivers are identical and contain same compilation date. Driver Jmidebs.sys was compiled later than these two and I can call it "MRxCls.sys v2", because it contains some differences inside, but serves for same purpose. Driver Mrxnet.sys is a typical legacy FS filter driver that is used by attackers for hiding files in Windows.
On second phase it tries to read content of file, decrypts it and injects it into process address space. File names for injection are stored into configuration file or registry parameter Data.
As we can see from the code analysis, authors have developed rootkit for injection malicious code into processes. Data for injection is prepared by Stuxnet user mode code. The driver registers handler for image load notify and performs injection into two phases. It also supports one IOCTL command for changing protection for virtual memory pages of process with help of ZwProtectVirtualMemory. For finding this unexported and undocumented function into ntoskrnl, it uses raw bytes search based on special signatures.
Driver 2
File name: Mrxnet.sys
SHA256: 0d8c2bcb575378f6a88d17b5f6ce70e794a264cdc8556c8e812f0b5f9c709198
File size: 17400 bytes
Signed: Yes
Timestamp: 2010-01-25 14:39:24
Device object name: none
Main purpose: malicious files hiding
AV detection ratio: 51/61
Unlike first driver MRXCLS.sys, authors of Mrxnet.sys don't perform anti-analysis checks in the start function of driver. Mrxnet.sys is a FS filter driver that controls some file operations. The rootkit tries to hide some file types by controlling IRP_MJ_DIRECTORY_CONTROL request and removes information about it from buffer.
The rootkit initialization steps.
As we can see from code, the driver plays with two types of devices: firstly its own CDO (Control Device Object) that represents FS filter and secondly devices that were created to filter files related operations on specific volumes. In case of CDO, the rootkit dispatches widely known request IRP_MJ_FILE_SYSTEM_CONTROL and operation IRP_MN_MOUNT_VOLUME. This operation is used by Windows kernel in case of mounting new volume into a system. After got this request, the rootkit creates new device object, registers completion routine and attaches device to newly mounted device. This method allows for driver to monitor appearance in a system new volumes, for example, volume of removable drive.
As you can see from the picture above, the driver also calls IoRegisterFsRegistrationChange I/O manager API for registering its handler that Windows kernel will call each time, when new file system driver CDO is registered into a system. In this handler, the driver creates new device and attaches it to passed CDO or removes device in case of file system driver deletion.
Major purpose of Mrxnet.sys driver is hiding Stuxnet malicious files. Windows kernel provides ZwQueryDirectoryFile API for requesting information about files in directory. This API function calls driver handler of IRP_MJ_DIRECTORY_CONTROL operation. So, the rootkit registers own IRP_MJ_DIRECTORY_CONTROL handler and sets completion routine when such request is passed through handler. In this completion routine it analyzes buffer with data and checks file names in it. It erases from buffer files with extension .LNK and .TMP. It also imposes additional restrictions on hiding. For example, in case of .LNK file, its size should be equal 0x104B.
It should be noted that such technique of files hiding were described in famous book "Rootkits: Subverting the Windows kernel" by Hoglund, Butler.
Driver 3
File name: Jmidebs.sys
SHA256: 63e6b8136058d7a06dfff4034b4ab17a261cdf398e63868a601f77ddd1b32802
File size: 25552 bytes
Signed: Yes
Timestamp: 2010-07-14 09:05:36
Device object name: \Device\{3093983-109232-29291}
Main purpose: code injection
AV detection ratio: 50/61
This driver is pretty similar to MRxCls.sys and serves only for code injection into processes. The following properties distinguish it from original MRxCls.sys.
- New device object name - \Device\{3093983-109232-29291}
- New registry service name - jmidebs
- New registry service parameter name (injection data) - IDE
- New IOCTL code for reading (caching) configuration data
- New constants in decryption routine.
\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Services\jmidebs
IDE
\Device\{3093983-109232-29291}
The rootkit contains additional IOCTL function, which specializes in caching configuration data. This data are used for injection malicious Stuxnet code.
Driver 4
File name: MRxCls.sys
SHA256: 1635ec04f069ccc8331d01fdf31132a4bc8f6fd3830ac94739df95ee093c555c
File size: 26616 bytes
Signed: Yes
Timestamp: 2009-01-01 18:53:25
Device object name: \Device\MRxClsDvX
Main purpose: code injection
AV detection ratio: 50/61
This sample is identical to driver 1, but signed with digital certificate. Both samples have identical timestamp value in PE header and identical code inside.
Conclusion
As we can see from the analysis, authors of Stuxnet Ring 0 part were interested in code injection and malicious files hiding. Driver MRxCls.sys has two instances, one unsigned and another with digital signature. Both drivers are identical and contain same compilation date. Driver Jmidebs.sys was compiled later than these two and I can call it "MRxCls.sys v2", because it contains some differences inside, but serves for same purpose. Driver Mrxnet.sys is a typical legacy FS filter driver that is used by attackers for hiding files in Windows.