Attaching to Windows Kernel with KDNET — a Short Guide

Recently, I’ve been working on a task at work which required debugging a malicious Windows driver. To be able to do so, I had to set up a kernel-debugging environment — attach a debugger on my host to a target machine’s kernel. This took a lot of time, many Google searches and probably some headache for my team leader, but I finally made this beautiful screen appear:

kd.exe attached to the target machine’s kernel

I am not writing this blog post to provide readers with an answer to how to setup KDNET. This has already been (very well) done by Microsoft. I wish to clarify why every step is taken and what it means. These are things I learned along the way and wish to share in a “one stop shop”-kind-of post.

This is what I had when I started:

  • a Windows 10 host with Debugging Tools for Windows installed;
  • a virtual machine running Windows 10;
  • ping working from host to guest and vice versa (see some troubleshooting tips in the last section).

Now let’s attach to a kernel 🤘

On The Target (Debuggee)

What we’re about to do on the target machine is the following:

  1. Create a new boot entry designated for kernel debugging;
  2. Edit this entry to have proper settings for our needs;
  3. Configure network settings to allow host-guest communication.

To do all these, we will use the bcdedit(Boot Configuration Data Edit) utility.

Note: Make sure you execute all of the following commands as Administrator.

To create a new boot entry, we will simply /copy the entry we’re currently running, which is referred to by the {current} identifier. To keep things neat, we add a description for this entry using the /d option.

> bcdedit /copy {current} /d "KDNet port 50035"
The entry was successfully copied to {dd896c2e-fccb-11e8-9cb7-d481d7c30c24}

Now let’s make this entry our /default using the GUID we just received:

> bcdedit /default {dd896c2e-fccb-11e8-9cb7-d481d7c30c24}
The operation completed successfully.

From now on, we can refer to our newly-created entry as {default}.

It’s time to make this operating system’s boot “debuggable”:

> bcdedit /set {default} debug yes
The operation completed successfully.

Important: Windows 10’s Secure Boot does not allow modifying this setting through bcdedit and must therefore be disabled. On a Hyper-V virtual machine, this is configured in the Security tab of the machine’s settings.

Finally, we need to configure the network /dbgsettings. We set the debug transport (the means via which we connect the host and the target) to net (for network); we decide upon a port number and tell the target what the host-IP address is. We ask for a newkey to be generated, which will be used later on the host.

Note: Choose a port number according to Microsoft’s recommendation.

> bcdedit /dbgsettings net hostip:192.168.1.120 port:50035 newkey
Key=g3mx1h96o5j9.tbdbyy05hfu7.10tkqaj5agj7e.xttvshlq4zsr

To verify these settings, we can type /dbgsettings with no arguments:

> bcdedit /dbgsettings
key g3mx1h96o5j9.tbdbyy05hfu7.10tkqaj5agj7e.xttvshlq4zsr
debugtype NET
hostip 192.168.1.120
port 50035

If you reboot your operating system at this point, you should see this screen:

Our new boot entry is highlighted.

Well, to be honest, you will see this screen only if you run:

> bcdedit /set {default} bootmenupolicy legacy

Otherwise, you will see a beautiful, Windows blueish screen with the same boot entries for options.

We’re done with the target — on to the host!

On the Host (Debugger)

Setting up the host is simpler; you just run the kernel debugging engine in one of its forms —kd for command-line based debugging, WinDbg for GUI, whatever you like.

> kd.exe -k net:port=50035,key=g3mx1h96o5j9.tbdbyy05hfu7.10tkqaj5agj7e.xttvshlq4zsr

Once you run this command or try to attach to a kernel from WinDbg (through File-Kernel Debug) restart the target machine and make sure the chosen boot entry is the one you created earlier.

It should take a couple of seconds until a connection to the debuggee is made. WinDbg will break automatically and will look something like this:

windbg.exe attached to the target machine’s kernel. Looks similar.

Hooray!

What, that didn’t work? Move on to the next section.

Tips and Tricks

IP addresses and Networking

  • You need to make sure the host and guest are able to communicate over the network. In my case, pinging from host to target did not work because the network discovery option on the target was turned off.
Network discovery settings in Windows’ Control Panel
  • IP addresses sometimes change after reboots. Make sure that the host IP provided when executing/dbgsettings is valid and reachable by the guest.

Windows Firewall

Windows Firewall can block network traffic between applications. I noticed that every time I tried a new application in order to attach to a kernel (be it WinDbg, WinDbg Preview or kd) a message immediately popped up alerting on this.

Windows Firewall blocking WinDbg from doing things

Be sure to allow the relevant applications through the firewall, and if this popup does not appear for some reason — verify or add manually.

Don’t Give Up

Making this work felt like forever and was exhausting. Here, see for yourselves:

Fight until it works. Double check keys and IP addresses as many times as needed, use tools such as Wireshark or tcpview to monitor network traffic, reboot again and again. I promise, this debugger will eventually attach to that kernel.

@ophirharpaz on Twitter. Security researcher at Guardicore. Reverse engineering enthusiast. Author of https://begin.re.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store