A lil’ bit about NDIS, Windows Firewall and the undocumented Firewall-Hook Drivers Interface
haxorcize on Oct 11th 2008
Up until a recent time, I wasn’t thoroughly familiar with the way Windows-based Firewalls are implemented. Due to my endless endeavours in the mazy subject called Device Driver Development (The evil triple D’s) I came accross the interesting subject of Network device drivers, during of which I’ve learned some interesting “internal” facts I’d like to share with you, in relation to Windows Firewall.
Not being too impetuous by the choice of words in this article’s title, I didn’t plan on being well versed in WF’s internal features as I’ll mainly focus on the implementation detail that interested me: The way WF filters network packets. One more thing to note is that this article concerns the WXP Firewall. In vista things have changed with the arrival of NDIS 6.X and the creation of the Windows Filtering Platform (WFP).
I am going to begin by describing merely a few kernel NDIS-related particles of the humongous Windows Networking Architecture in a somewhat superficial but understable way:
- If you are familiar with NDIS you may skip to the following phrase. For those of you who aren’t, try understanding the definitions but dont feel bad if you don’t, it takes some time to get acquainted with those terms.
- NDIS, aka the “Network Driver Interface Specification”, is meant to provide a common framework for network interfaces development, and originated back in 1989. It allows network adapater vendors to easily develop NDIS drivers for the NIC devices, in a rather portable manner. It does so by a layered design - very much like the OSI refernece model.
- NDIS Library Driver - %SYSTEMROOT%\System32\Drivers\Ndis.sys implements the NDIS library functionality that allows the decoupling between the layers, and makes everything tick from top to bottom and back to the top.
- NDIS Miniport Drivers - The ones that actually talk to the hardware itself (the NIC), with the assitance of the HAL of course.
- NDIS Protocol Drivers - Drivers that implement a specific protocol, and are logically seperated from the Miniport-Drivers with the aid of the NDIS library. An example for such a driver is the TCP/IP protocol driver is implemented in %SYSTEMROOT%\System32\Drivers\tcpip.sys.
- NDIS Intermediate Drivers - Windows NT 4.0 SP3 introduced a new type of drivers called NDIS Intermediate (IM) drivers. NDIS IM drivers layer themself (with the aid of the NDIS Library) between the miniport drivers and the protocol drivers, thus allowing themself to notice all the traffic a host generates and receives.
I even created (as in “not copied” :)) a figure to illustrate the relations between the various NDIS components and their layers:

As been told above, the TCP/IP implementation in Windows is actually an NDIS Protocol driver. As such, it communicates with the different layers inside NDIS with the help of the NDIS library. The great Windows Internals book, along with the (lousy :)) WDK documentation describes that the TCP/IP Protocol Driver has a few private interfaces that allows other drivers to extend the functionality of the TCP/IP driver by implementing all sort of Hooks on packets going in and out. Some of them are known as “Filter-Hook Drivers” and “Firewall-Hook drivers”.
An interesting fact about the Firewall-Hook Drivers Interface is that its completely undocumented in the WDK, while the Filter-Hook Drivers Interface is completely documented (that is, in a WDK lacking fashion). Sufficiently to say that Filter-Hook Drivers Interface isn’t as powerful as Firewall-Hook Drivers Interface, since it doesn’t allow you to touch the data of outgoing packets, nor can you alter the contents. On top of that, there’s a limitation of the FIlter-Hook Drivers Interface that allows only a single Filter-Hook Driver to exist in the system.
The only reference I could find in the WDK on Firewall-Hook drivers is half a page that barely begins to describe anything, and contains, mostly, the following recommendations:
It is not recommended to implement a firewall-hook driver (or firewall driver) for Microsoft Windows XP and later versions of the operating system.
…
To provide firewall functionality on Windows XP and later, you should create an NDIS intermediate miniport driver to manage packets sent and received across a firewall. For information about creating an NDIS intermediate miniport driver, see NDIS Intermediate Drivers.
As it seems from above’s comments, its highly unrecommended to use the Firewall-Hook interface, and Microsoft strongly advises to develop firewall-like products as IM drivers (which indeed makes a lot of sense due to their comfortable position in the network-stack). But for some weird-enough reason, they didn’t follow their own recommendations and developed WF as a Firewall-Hook driver! WF is an integrated part of the IpNat.sys driver, that among other things offers NAT and Firewall services.
Here’s a revised figure that illustrates the TCP/IP Protocol Driver extensions (there are more than the two I’m showing):

The WDK Reference section for Firewall-Hook Drivers contains documentation on a few weird methods, that their usage was (and probably is still) unclear at that stage. The WDK was kind enough though to lead me in the right direction, directly to the Ipfirewall.h header file! Looking at the ipfirewall.h header file, we can find the some interesting artifacts that only begin to describe the intricacies of this private interface. Among those artifacts you could find non-common data structures used to transfer and receive data in that private interface. Other artifacts include function definition, some constants, and a very interesting IOCTL named IOCTL_IP_SET_FIREWALL_HOOK. This IOCTL name hints that its probably important.
Trying to find definitive answers, I’ve decided to look into IpNat.sys’s assembly. I immediately launched IDA and dropped the file into it. IpNat’s DriverEntry routine, like in most drivers, performs a lot of driver-related initialization work. (For example: it creates device object named: “\\Device\\IPNAT”). Among other things, it calls an interesting function called NatInitializeDriver.
Seeing as there’s a lot of initialization, I took a different approach and searched for a place where this IOCTL could possibly be constructed as an IRP. A quick xref search on the IoBuildDeviceIoControlRequest lead me to the following interesting results:
The first entry immediately points at an interesting function, NatSetFirewallHook. And immediately at the begining we witness the creation of a IOCTL IRP:
And later on we see that this IRP is sent with IofCallDriver to the device object represented by \Device\IP.
Interesting!
So what is this IOCTL precisely?

Device Type Access IOCTL Code Transfer Type 00...010010 10 000000001100 00
#define FSCTL_IP_BASE FILE_DEVICE_NETWORK
#define _IP_CTL_CODE(function, method, access) \
CTL_CODE(FSCTL_IP_BASE, function, method, access)
#define IOCTL_IP_SET_FIREWALL_HOOK \
_IP_CTL_CODE(12, METHOD_BUFFERED, FILE_WRITE_ACCESS)
As suspected, WF uses the exact same IOCTL we found in ipfirewall.h! to register itself as a Firewall-Hook Driver. (Searching this IOCTL in google brings up some very interesting hits. Especially this article that actually describes the whole Firewall-Hook charade from a programmatic point of view).
I guess most of you evil-minded fellas have already had the following thought coming across their mind in some point of the article (if not before): “Gee… Not only does the Windows Firewall completely ignores outgoing packets, it also binds itself directly to the TCP/IP Protocol Driver leaving the rest of the NDIS network stack completely vulnerable for kernel-malware??”. Yes, it seems that way. I guess this is why most people use commercial firewalls, and Microsoft advises against their own particular firewall implementation.
I’ll add and say that good firewalls will usually take a bit more of an aggressive approach and hook the entire networking subsystem to ensure that not even the slighest bit of information is slipping out or coming into the host computer. The not-so-good among them usally perform a poor-man’s hook into some higher-level layer(s) inside NDIS. The worst kinds stay away and find some comfortable “Firewal-Hook” trick to enfore their policies. Then again, even the best commerical product has the somewhat-better rootkit that bypasses it completely.
Anyway, this has been fun and I hope you guys have learnt a lil’ bit about NDIS, Windows Firewall and the undocumented Firewall-Hook Drivers Interface.
Filed in Dissected Programs, Misc. | 2 responses so far














