随着网络安全问题日益严重网络安全产品也被人们重视起来防火墙作为最早出现的网络安全产品和使用量最大的安全产品也受到用户和研发机构的青睐从防火墙的应用角度来看基本上可以分为两种网络级的防火墙和个人防火墙Windows操作系统作为使用最为广泛的PC操作系统因此在Windows操作系统下开发的个人防火墙产品数不胜数国外比较着名的有AtGuardOutpost FirewallZoneAlarmTiny Personal FirewallNorton Personal Firewall以及Sygate Personal Firewall等国内用的比较多的有天网防火墙等产品
所有基于Windows操作系统的个人防火墙核心技术点在于Windows操作系统下网络数据包拦截技术本文主要讲述的是Windows操作系统下网络数据包拦截的技术首先读者应该对Windows网络体系结构有一定了解并且对开发Windows驱动程序有一定了解
Windows 网络驱动程序结构
图显示了Windows 下的网络驱动程序结构
微软和Com公司在年制定了一套开发Windows下网络驱动程序的标准称为NDIS( Network Driver Interface Specification)NDIS为网络驱动的开发提供了一套标准的接口使得网络驱动程序的跨平台性更好NDIS提供以下几个层次的接口
?NDIS小端口驱动(Miniport driver)这也就是我们常说的网卡驱动
?NDIS 协议驱动(Protocol driver)例如TCPIP协议驱动
?NDIS 中间层驱动(Intermediate driver)这是基于链路层和IP层之间的驱动
从图中我们可以很清楚地看到网络驱动的分层结构这就给我们提供了拦截网络数据包的基本思路
总的来说要拦截Windows下的网络数据包可以在两个层面进行用户态(usermode)和内核态(kernelmode)
用户态下的网络数据包拦截
在用户态下进行网络数据包拦截有以下几种方法
) Winsock Layered Service Provider (LSP)这种方法在MSDN里有很详细的文档并且给出了一个例子(SPICPP)这种方法的好处是可以获得调用Winsock的进程详细信息这就可以用来实现QoS数据流加密等目的但是如果应用程序直接通过TDI(Transport Driver Inface)调用TCPIP来发送数据包这种方法就无能为力了对于一些木马和病毒来说要实现通过TDI直接调用TCPIP是一件很容易的事情因此大多数的个人防火墙都不使用这种方法国内也有使用该方法实现的个人防火墙例如Xfilter()
) Windows 包过滤接口Windows IPHLP API提供了安装包过滤器的功能但是包过滤的规则有很多限制对于个人防火墙来说是远远不够的
) 替换系统自带的WINSOCK动态连接库这种方法可以在很多文章里面找到详细的实现细节
很显然在用户态下进行数据包拦截最致命的缺点就是只能在Winsock层次上进行而对于网络协议栈中底层协议的数据包无法进行处理对于一些木马和病毒来说很容易避开这个层次的防火墙
利用驱动程序拦截网络数据包
大多数的个人防火墙都是利用网络驱动程序来实现的从图中我们马上可以想到可以从以下几个方面来做文章
? TDI过滤驱动程序(TDI Filter Driver)
? NDIS中间层驱动程序(NDIS Intermediate Driver)
? Wink FilterHook Driver
? NDIS Hook Driver
以下我们大体介绍这几种方法具体的实现细节请参见Wink DDK文档
TDI过滤驱动程序当应用程序要发送或接收网络数据包的时候都是通过与协议驱动所提供的接口来进行的协议驱动提供了一套系统预定义的标准接口来和应用程序之间进行交互在Windows /NT下iptcpudp是在一个驱动程序里实现的叫做tcpsys这个驱动程序创建了几个设备DeviceRawIpDeviceUdpDeviceTcpDeviceIp DeviceMULTICAST应用程序所有的网络数据操作都是通过这几个设备进行的因此我们只需要开发一个过滤驱动来截获这些交互的接口就可以实现网络数据包的拦截TDI层的网络数据拦截还可以得到操作网络数据包的进程详细信息这也是个人防火墙的一个重要功能
NDIS中间层驱动中间层驱动介于协议层驱动和小端口驱动之间它能够截获所有的网络数据包(如果是以太网那就是以太帧)NDIS中间层驱动的应用很广泛不仅仅是个人防火墙还可以用来实现VPNNATPPPOverEthernet以及VLan中间层驱动的概念是在Window NT SP之后才有的因此对于Windowsx来说无法直接利用中间层驱动的功能Windows DDK提供了两个着名的中间层驱动例子Passthru以及Mux开发人员可以在Passthru的基础上进行开发Mux则实现了VLan功能目前个人防火墙的产品还很少用到这种技术主要的原因在于中间层驱动的安装过于复杂尤其是在Windows NT下Windows 下可以通过程序实现自动安装但是如果驱动没有经过数字签名的话系统会提示用户是否继续安装中间层驱动功能强大应该是今后个人防火墙技术的趋势所在特别是一些附加功能的实现
Wink FilterHook Driver这是从Windows开始系统所提供的一种驱动程序该驱动程序主要是利用ipfiltdrvsys所提供的功能来拦截网络数据包FilterHook Driver在结构非常简单易于实现但是正因为其结构过于简单并且依赖于ipfiltdrvsysMicrosfot并不推荐使用FilterHook Driver
NDIS Hook Driver这是目前大多数个人防火墙所使用的方法Hook的概念在Windowsx下非常流行而且实现也很容易在Windowsx下驱动程序(VxD)通过使用Hook_Device_Service可以挂接NDIS所提供的所有服务在Windows NT/下面如何实现Hook呢?有两种不同的思路
) 通过修改NDISSYS的Export Table在Windows NT/下可执行文件(包括DLL以及SYS)都是遵从PE(Portable Executable)格式的所有向其他操作系统组件提供接口的驱动程序都有Export Table因此只要修改NDISSYS的Export Table就可以实现对关键NDIS API的挂接由于协议驱动程序在系统启动的时候会调用NdisRegisterProtocol来向系统进行协议注册因此这种方法关键在于修改NDISSYS所提供的NdisRegisterProtocol/NdisDeRegisterProtocol/NdisOpenAdapter/NdisCloseAdapter/NdisSend函数的起始地址我们知道在用户态模式要修改PE文件格式可以用一些API来实现而NDISSYS位于系统的核心内存区因此要修改NDISSYS就不得不通过写驱动程序来实现也就要求我们对PE文件格式有比较深入的了解使用这种方法还要注意驱动程序的加载次序显然Hook Driver必须在NDISSYS被加载之后而在协议驱动程序如tcpipsys被加载之前另外Windows还提供了系统文件保护机制因此在修改ndissys还需要通过修改注册表屏蔽系统文件保护机制
) 向系统注册假协议(fake protocol)在Windows内核中所有已注册的协议是通过一个单向的协议链表来维护的这个单向链表保存了所有已注册协议的NDIS_PROTOCOL_BLOCK结构的地址在这个结构中保存了协议驱动所指定的相应的派发函数的地址如RECEIVE_HANDLER等并且每个协议驱动还对应一个NDIS_OPEN_BLOCK的单向链表来维护其所绑定的网卡信息当协议驱动调用NdisRegisterProtocol之后NDIS总是会把新注册的协议放在协议链表的表头并返回这张表所以只要我们注册一个新的协议通过新协议注册返回的链表头就可以轻而易举的遍历系统中所有协议表但是如果要成功地挂接派发函数还需要对协议所对应的NDIS_OPEN_BLOCK结构里的派发函数进行挂接因为NDIS并不是直接调用协议驱动在NDIS_PROTOCOL_CHARACTERISTICS所注册的派发函数地址而是调用NDIS_OPEN_BLOCK里的派发函数值得注意的是在Windowsx/Me/NT的DDK中NDIS_PROTOCOL_BLOCK的定义是很明确的而在Windows /xp的DDK中并没有该结构的详细定义也就是说该结构在Windows/xp下是非公开的因此开发人员需要利用各种调试工具来发掘该结构的详细定义也正是因为如此这种方法对平台的依赖性比较大需要在程序中判断不同的操作系统版本而使用不同的结构定义
总结
本文重点描述了在WindowsNT//xp下个人防火墙核心技术网络数据包拦截技术分析了各种可能的方法以及各种方法的优缺点实际上许多个人防火墙结合了几种不同的技术来在不同层面上进行网络数据包拦截值得说明的是网络数据包拦截技术不仅仅可以用来开发个人防火墙还可以用来开发其他的产品