Adventures in Windows Driver Development: Part 1

tl;dr

This is the first in a series of blog posts relating to driver development on Windows systems. The project started as an attempt to understand drivers and low-level system programming by developing a driver to exercise a wide range of functionality.

The initial stages of the project were difficult and frustrating, as driver deployment and testing for Windows has recently been tied in with Visual Studio and is largely automated. When this automation fails, documentation is sparse. This initial blog post will address some of the issues that may arise, and suggest solutions to these problems.

Drivers in the Security Industry

In addition to providing an interesting area of research, drivers have a number of uses directly relating to security. Areas in which the use of drivers has proven beneficial include:

NCCGroup Windows Activity Logger

NCCGroup Windows Activity Logger [1] is a product developed to allow low-level monitoring of activity taking place across sensitive systems. Information such as process creation, registry key information, and network connections is gathered, to allow monitoring for malware and malicious activity. If monitoring activities take place at a low level, as in this case, then it is harder for malware or an intruder to detect and remove the tool or otherwise interfere with it.

Anti-Corruption and Employee Misuse Detection

Drivers can be used to help mitigate employee misuse and as an anti-corruption mechanism. Companies such as Veriato develop products that use driver technologies in order to counteract the insider threat [2], one of the most problematic security issues in modern organisations. As with the previous example, using low-level drivers makes the product harder to detect and thwart.

Implants and Rootkits

Drivers are often used to maintain access to an infected system and to hide suspicious activity from system administrators. A well-known example of malicious rootkit activity is Stuxnet [3], which used this functionality in order to maintain access and avoid detection.

Rootkits can also be used in non-malicious scenarios, although the ethicality of such activity is widely debated. One such example is the rootkit functionality developed by Sony to enable digital rights management (DRM) [4].

In order to facilitate detection and mitigation, it is vital for security companies to study and understand the techniques used by threat actors in these areas.

Overview and Thought Process

At a high level, the overall aim of the project is to develop similar functionality to that described in The Rootkit Arsenal by Bill Blunden [5], and to apply it to Windows 10. Many mitigations, such as driver signing, are built into modern operating systems to prevent rootkit deployment. This project is currently not an attempt to bypass these; the code will be deployed via legitimate channels using a test signing certificate. Rootkit-like functionality was chosen for the project as it requires a full understanding of low-level processes in order to manipulate them, and it provides an interesting test case with clearly demonstrable results.

Part 1: Deploying Drivers on Windows Systems

Automatic Deployment

Drivers for Windows 8 and above are intended to be written using Visual Studio 2013 (for Windows 8.1) or Visual Studio 2015 (for Windows 10) and then deployed and tested through built-in options [6]. In particular, the connection to the machine to be used for testing can be set up from the  “Configure Devices… “ option under the Driver menu, as can be seen in Figure 1:

Driver Deployment Menu

Unfortunately, there is a known bug in Visual Studio 2015 that has broken this feature. This issue has been reported to Microsoft [7, 8]; however as of April 2016 the issue is still present. The result is that upon attempting to select the “configure devices” option an error message is displayed, as can be seen in Figure 2:

Attempts to use Windows 8.1 and Visual Studio 2013 were also unsuccessful, so it was necessary to find another method to deploy and test the driver.

Manual Deployment

Due to the development of automated deployment methods, documentation around manually deploying drivers is sparse; however a walkthrough for building and deploying the  “Echo “ test driver provided with the Microsoft Sample Drivers (available on Github [9]) was available and demonstrated manual deployment using the Devcon tool [10].

After building the driver as described in the walkthrough, the files echo.inf, echo.sys, and echo.cer were copied to the test virtual machine, which was an up-to-date build with Windows 10 installed, test signing enabled, and debugging turned on to allow kernel debugging via WinDbg at a later stage.

On systems running Windows 7 or later, all drivers need to be signed. For development purposes a test signing certificate can be generated as long as the capability is turned on. Test signing can be enabled by using the following command from an Administrator command prompt:

bcdedit.exe -set TESTSIGNING ON

The certificate must be installed as a trusted root certificate in order to work correctly. This should generate the warning in Figure 3.

Certificate Installation

The specific driver can be installed using the devcon command as follows:

devcon.exe install %filepath%echo.inf root\ECHO

The format of this command is explained in further detail on the MSDN page [11].  “echo.inf “ is the associated INF file; this is a collection of information used by the system for driver installation [12]. The final entry, root\ECHO, is the hardware ID; this is used as an identification string to match an INF file to a specific driver [13].

However, as can be seen in Figure 4, this approach failed:

Devcon Failure

At this point it is not immediately obvious what has gone wrong. The output does not give any indication as to why installation failed, or indeed any helpful information at all. Initially it was suspected that the certificate had been incorrectly installed. However, viewing the entry in the certmgr tool ruled this out as the cause of the error; as can be seen in Figure 5, the certificate is in place in the correct store:

Certmgr

The next stage was to investigate why the driver was not installing. A review of the walkthrough in use showed all stages had been followed correctly and nothing was missing. The next logical step was to investigate if there where any log files associated with this event or if logging could be enabled.

It was discovered that Windows maintains a log of driver installation events [14,15] in the following location:

C:\Windows\INF\setupapi.dev.log

The full output from the installation attempt is rather verbose however, the following lines provide a clue as to the issue (full details are available on request):

     sig:           {_VERIFY_FILE_SIGNATURE} 17:18:50.279
     sig:                Key      = echo.inf
     sig:                FilePath = c:\users\wdkremoteuser\desktop\driver test\echo.inf
     sig:                Catalog  = c:\users\wdkremoteuser\desktop\driver test\KmdfSamples.cat
!    sig:                Verifying file against specific (valid) catalog failed! (0x00000057)
!    sig:                Error 87: The parameter is incorrect.
     sig:           {_VERIFY_FILE_SIGNATURE exit(0x00000057)} 17:18:50.295
     sig:           {_VERIFY_FILE_SIGNATURE} 17:18:50.295
…
     dvi:                Signer       - Not digitally signed
     dvi:                Signer Score - Not digitally signed
… 
     sig:                     Code Integrity State: Test Signing
     inf:                     Opened INF: 
'C:\Windows\System32\DriverStore\Temp\{93a1754e-210f-ed4e-97b6-1bb3a0529272}\echo.inf' ([strings])
!!!  sig:                     Driver package does not contain a catalog file, 
and Code Integrity is in Test Signing mode.
!!!  sig:                     Driver package failed signature validation. Error = 0xE000022F
     sto:                {DRIVERSTORE IMPORT VALIDATE: exit(0xe000022f)} 17:18:50.405
!!!  sig:                Driver package failed signature verification. Error = 0xE000022F
…
!!!  ndv:      Error 0xe000022f: The third-party INF does not contain digital signature information.
…   
<<<  [Exit status: FAILURE(0xe000022f)]

The log file indicated that there was an error with the driver signing; however, as previously mentioned, the certificate generated by Visual Studio had been installed and verified as residing in the correct location. It was the highlighted line that gave an indication as to why the installation was failing in spite of this.

According to MSDN, catalog files contain cryptographic hashes, and a signed catalog file is used by the Plug and Play Manager as the digital signature for the driver [16]. So while it is not immediately obvious, a signed catalog file is required to deploy drivers [17]. This information can be seen in Figure 6.

MSDN Guidance on Catalog Files

A catalog file is not generated from the Visual Studio in the folder containing the test certificate, and is not mentioned in the walkthrough, indicating there must be a workaround to the issue (the build containing the catalog file was eventually located in another folder, but it did not contain a test signing certificate as was used in the example). Further investigation revealed the solution seen in Figure 7, found in one sentence on a page hidden away on MSDN [18]:

MSDN Guidance on Disabling Signature Verification

In the absence of a valid catalog file, signature enforcement can be disabled by attaching a kernel debugger.

Prior to configuring kernel debugging, a serial port needs to be configured on the target. In the setup used for this example, the test machine is a virtual machine and debugging and development are running from the host. The virtual machine used for driver testing is running on VMware Workstation 11; instructions are provided by VMware for setting up a serial port [19], ensuring that  “output to a named pipe “ is selected in step 5,

Accessing the setup page by right-clicking the required VM, choosing  “settings “, and then selecting the serial port should give a similar output to Figure 8. Ensure that the pipe name matches the one entered during the serial port setup.

VMWare Named Pipe Setup

Kernel debugging can be enabled on Windows using the following commands from an elevated command prompt:

bcdedit /debug ON
bcdedit /dbgsettings serial debugport:n baudrate:115200

Where the highlighted n is the number of the COM port on the virtual machine. In the case of VMware this can be determined by examining the number given to the serial port under the device column (for example, in this setup the name is  “serial port 2”, therefore  “debugport:2” is used)

At this point, WinDbg was started on the host machine, with the settings shown in Figure 9 entered under the “File→Kernel Debug…” menu.

WinDbg Kernel Debugging Setup

Restarting the virtual machine should attach the kernel debugger, as can be seen in Figure 10, and allow deployment of the test driver.

Running the devcon command yields the result in Figure 11. The security popup indicates that the attempted installation has succeeded, but Windows is warning against the installation of a driver signed with a self-signed certificate.

Driver Installation Successful

The device manager tool shows that the driver has installed correctly, as can be seen in Figure 12:

Viewing Driver in Device Manager

At this stage the sample driver is deployed and ready to be tested. As this was the sample driver provided by the Driver Development Kit, there is not much more to do, other than review the rest of the stages in the walkthrough. However, these stages describe how to set up a virtual machine for testing and deploy drivers successfully, allowing development on the driver project to commence.

Conclusions

Modern driver development on Windows systems is intended to be done via automated tools provided with Visual Studio. However, if these tools do not work documentation is sparse and not necessarily coherent. Manual deployment through the devcon tool allows drivers to be installed as long as the necessary conditions are met.

Setting up an environment and deploying drivers is not a straightforward process as it first appears, but can be achieved by following the steps detailed here.

References and Further Reading

  1. https://labs.nccgroup.trust/windowsactivitylogger/
  2. http://www.veriato.com/solutions/detect-insider-threats
  3. http://www.symantec.com/connect/blogs/stuxnet-introduces-first-known-rootkit-scada-devices
  4. https://blogs.technet.microsoft.com/markrussinovich/2005/10/31/sony-rootkits-and-digital-rights-management-gone-too-far/
  5. http://www.amazon.co.uk/The-Rootkit-Arsenal-Evasion-Corners/dp/144962636X
  6. https://msdn.microsoft.com/en-us/library/windows/hardware/dn745909
  7. https://social.msdn.microsoft.com/Forums/vstudio/en-US/6cbc1b0b-e89c-4b6c-921f-4dba6b89c35b/inappropriate-request-for-export-from-part-that-belongs-to-another-sharing-boundary?forum=visualstudiogeneral
  8. https://connect.microsoft.com/VisualStudio/feedback/details/2080376/fails-to-load-configure-devices
  9. https://github.com/Microsoft/Windows-driver-samples
  10. https://msdn.microsoft.com/en-us/library/windows/hardware/mt269367
  11. https://msdn.microsoft.com/en-gb/library/windows/hardware/ff544780%28v=vs.85%29.aspx
  12. https://msdn.microsoft.com/en-us/library/windows/hardware/ff549520%28v=vs.85%29.aspx
  13. https://msdn.microsoft.com/en-gb/library/windows/hardware/ff546152%28v=vs.85%29.aspx
  14. https://msdn.microsoft.com/en-us/library/windows/hardware/ff550887%28v=vs.85%29.aspx
  15. https://msdn.microsoft.com/en-us/library/windows/hardware/ff550900%28v=vs.85%29.aspx
  16. https://msdn.microsoft.com/en-gb/library/windows/hardware/ff537872%28v=vs.85%29.aspx
  17. https://msdn.microsoft.com/en-gb/library/windows/hardware/ff553480%28v=vs.85%29.aspx
  18. https://msdn.microsoft.com/en-us/library/windows/hardware/ff547565%28v=vs.85%29.aspx
  19. https://pubs.vmware.com/workstation-9/index.jsp?topic=%2Fcom.vmware.ws.using.doc%2FGUID-70C25BED-6791-4AF2-B530-8030E39ED749.html

Published date:  27 April 2016

Written by:  Katy Winterborn