Windows下网络数据报的监听和拦截技术

Windows下网络数据报的监听和拦截技术1

        Windows下网络数据报的监听和拦截技术是一个比较古老的话题,应用也很广泛,例如

防火墙等等。这篇小文只是对该技术的一个总结,没有新技术,高手免看:)

        要监听和拦截Windows下的数据报,基本可以在两个层次进行,一个是用户态(user-mo

de),一个是核心态(kernel-mode)

        在用户态下,从高到低大概有四种方法。

        1、原是套结字(Raw Socket)Winsock2以后提供了原始套结字功能,可以在用户态用

Winsock函数接收所有流经WinsockIP包。这种方法在MSDN里面有叙述,是MS官方支持

的方法,在网上也有很多资料。但是这种方法只能监听但是不能拦截数据报,所以可以

作为网络监视器的选择技术,但是不能实现防火墙等更高要求的功能。另外最致命的缺

点就是只能在Winsock层次上进行,而对于网络协议栈中底层协议的数据包例如TDI无法

进行处理。对于一些木马和病毒来说很容易避开这个层次的监听。

        2、替换系统自带的WINSOCK动态连接库。这种方法可以在很多文章里面找到详细的实现

细节。 通过替换系统Winsock库的部分导出函数,实现数据报的监听和拦截。缺点同1

 

        3Winsock服务提供者(SPI)SPIWinsock的另一面,是Winsock2的一个新特性。

起初的Winsock是围绕着TCP/IP协议运行的,但是在Winsock 2中却增加了对更多传输协

议的支持。Winsock2不仅提供了一个供应用程序访问网络服务的Windows socket应用程

编程接口(API),还包含了由传输服务提供者和名字解析服务提供者实现的Winsock

服务提供者接口(SPI)和ws2_32.dll Winsock 2的传输服务提供者是以动态链接库的

形式(DLL)存在的。以下是winsock 2在传输服务提供者上的WOSAWindows开放服务结

构):

----------------------------

|Windows socket 2 应用程序|

----------------------------Windows socket 2 API

|       WS2_32.DLL        |

----------------------------Windows socket 2 传输SPI

|   传输服务提供者(DLL  |

----------------------------

Windows socket SPI提供三种协议:分层协议,基础协议和协议链。分层协议是在基础

协议的上层,依靠底层基础协议实现更高级的通信服务。基础协议是能够独立,安全地

和远程端点实现数据通信的协议,它是相对与分层协议而言的。协议链是将一系列的基

础协议和分层协议按特点的顺序连接在一起的链状结构,可以通过Platform SDK附带的

工具Sporder.exe察看系统已经安装的SPI,请参见下图:

API------------------------

   |      WS2_32.DLL     |

SPI------------------------

   | 分层协议 |

SPI-------------

   | 分层协议 |

SPI------------------------

   |       基础协议       |

   ------------------------

        每个应用程序通过Ws2_32.dll和相应的服务提供者进行严格的数据交换。Ws2_32.dl

l

据应用程序在创建套接字时所提供的参数来选择特定的服务提供者,然后把应用程序

实现过程转发由所选创建套接字的服务提供者来管理。也就是说,Ws2_32.dll只是一个

中间过程,而应用程序只是一个接口,数据通信的实现却是由服务提供者来完成的。所

以我们通过适当的增加自己的分层协议服务提供者,使其位于SPI的顶端,那么就能将W

s2_32.dll传给服务提供者的数据报拦截下来。由于是MS的官方方法,具体的使用方法在

Platform SDK里面有详细的例子(LSP),在MSDN里面也有详细的解释。这种方法的优点

是能够获得调用Winsock的进程的详细信息,并能实现Qos和数据加密。所以SPI是用户态

数据拦截的较好地点。缺点同1

        4Windows2000包过滤接口。由于过滤规则限制太多不灵活而应用不多。

        5、网络监视器SDKMS官方的实时监视分析网络数据的方法。但是由于封装的太复?

?

使用起来不灵活。

 

        在核心态下,数据报的监视和拦截方法比较复杂,由于大多个人防火墙都是在核心?

?

实现的,所以在这里比较详细的叙述一下。具体的请参见nt/2kDDK文档。大概有下面几

个方法。

1     TDI过滤驱动程序TDI Filter Driver)。

2     NDIS中间层驱动程序NDIS Intermediate Driver)。编写IM DRIVERNDIS中间层

 

 

MINIPORT(网卡驱动程序)和协议驱动程序之间的数据包进行拦截。这是微软提供的

一种技术。在DDKMS提供了Passthru例子,很多中间层过滤驱动都可以由之改编。但编

写该过滤程序拦截程序非常的复杂,安装也很麻烦。

3     Win2k Filter-Hook Driver

4     NDIS Hook Driver。这种方法又有两种实现方式。

1)向NDIS注册假协议(fake protocol)。这是在协议层上的处理。在Windows内核中

,所有已注册的协议是通过一个单向的协议链表来维护的。这个单向链表保存了所有已

注册协议的NDIS_PROTOCOL_BLOCK结构的地址,在这个结构中保存了协议驱动所指定的相

应的派发函数的地址如RECEIVE_HANDLER等。

struct _NDIS_PROTOCOL_BLOCK

{

PNDIS_OPEN_BLOCK OpenQueue; // queue of opens for this protocol

REFERENCE Ref; // contains spinlock for OpenQueue

UINT Length; // of this NDIS_PROTOCOL_BLOCK struct

NDIS50_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics;// handler addresses

 

struct _NDIS_PROTOCOL_BLOCK * NextProtocol; // Link to next

ULONG MaxPatternSize;

#if defined(NDIS_WRAPPER)

//

// Protocol filters

//

struct _NDIS_PROTOCOL_FILTER * ProtocolFilter[NdisMediumMax+1];

WORK_QUEUE_ITEM WorkItem; // Used during NdisRegisterProtocol to

// notify protocols of existing drivers.

KMUTEX Mutex; // For serialization of Bind/Unbind requests

PKEVENT DeregEvent; // Used by NdisDeregisterProtocol

#endif

};

typedef struct _NDIS_PROTOCOL_BLOCK NDIS_PROTOCOL_BLOCK, *PNDIS_PROTOCOL_BLO

CK;并且,每个协议驱动还对应一个NDIS_OPEN_BLOCK的单向链表来维护其所绑定的网卡

信息。当协议驱动调用NdisRegisterProtocol之后,

EXPORT

VOID

NdisRegisterProtocol(

OUT PNDIS_STATUS Status,

OUT PNDIS_PROTOCOL_BLOCK NdisProtocolHandle, /*注意NDIS_HANDLE所指向的就是PN

DIS_PROTOCOL_BLOCK的结构,不要有什么怀疑。*/

IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics,

IN UINT CharacteristicsLength

);

NDIS总是会把新注册的协议放在协议链表的表头并返回这张表,所以只要我们注册一个

新的协议通过新协议注册返回的链表头就可以轻而易举的遍历系统中所有协议表。但是

,如果要成功地挂接派发函数,还需要对协议所对应的NDIS_OPEN_BLOCK结构里的派发函

数进行挂接,因为NDIS并不是直接调用协议驱动在NDIS_PROTOCOL_CHARACTERISTICS所注

册的派发函数地址,而是调用NDIS_OPEN_BLOCK里的派发函数。

struct _NDIS_OPEN_BLOCK

{

PNDIS_MAC_BLOCK MacHandle; // pointer to our MAC

NDIS_HANDLE MacBindingHandle; // context when calling MacXX funcs

PNDIS_ADAPTER_BLOCK AdapterHandle; // pointer to our adapter

PNDIS_PROTOCOL_BLOCK ProtocolHandle; // pointer to our protocol

NDIS_HANDLE ProtocolBindingContext;// context when calling ProtXX funcs

PNDIS_OPEN_BLOCK AdapterNextOpen; // used by adapter's OpenQueue

PNDIS_OPEN_BLOCK ProtocolNextOpen; // used by protocol's OpenQueue

PFILE_OBJECT FileObject; // created by operating system

BOOLEAN Closing; // TRUE when removing this struct

BOOLEAN Unloading; // TRUE when processing unload

BOOLEAN NoProtRsvdOnRcvPkt; // Reflect the protocol_options

NDIS_HANDLE CloseRequestHandle; // 0 indicates an internal close

KSPIN_LOCK SpinLock; // guards Closing

PNDIS_OPEN_BLOCK NextGlobalOpen;

//

// These are optimizations for getting to MAC routines. They are not

// necessary, but are here to save a dereference through the MAC block.

//

SEND_HANDLER SendHandler;

TRANSFER_DATA_HANDLER TransferDataHandler;

//

// These are optimizations for getting to PROTOCOL routines. They are not

// necessary, but are here to save a dereference through the PROTOCOL block.

 

//

SEND_COMPLETE_HANDLER SendCompleteHandler;

TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;

RECEIVE_HANDLER ReceiveHandler;

RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler;

//

// Extentions to the OPEN_BLOCK since Product 1.

//

RECEIVE_HANDLER PostNt31ReceiveHandler;

RECEIVE_COMPLETE_HANDLER PostNt31ReceiveCompleteHandler;

//

// NDIS 4.0 extensions

//

RECEIVE_PACKET_HANDLER ReceivePacketHandler;

SEND_PACKETS_HANDLER SendPacketsHandler;

//

// More NDIS 3.0 Cached Handlers

//

RESET_HANDLER ResetHandler;

REQUEST_HANDLER RequestHandler;

//

// Needed for PnP

//

UNICODE_STRING AdapterName; // Upcased name of the adapter we are bound to

};

这张表是一个单向链接表,并且存放了和PNDIS_OPEN_BLOCK->ProtocolCharacteristic

s

一样的数据收发派发函数,当第N块网卡发送数据包到第N个协议时,就会调用第N个协议

与第N个网卡之间建立的

NDIS_OPEN_BLOCK表里的SendHandlerSendPacketHandler。所以我们还需要对这张表里

的派发函数进行处理(勾挂)。

值得注意的是,在Windows9x/Me/NTDDK中,NDIS_PROTOCOL_BLOCK的定义是很明确的,

而在Windows 2000/xpDDK中,并没有该结构的详细定义,也就是说该结构在Windows2

000/xp下是非公开的,因此开发人员需要利用各种调试工具来发掘该结构的详细定义。

也正是因为如此,这种方法对平台的依赖性比较大,需要在程序中判断不同的操作系统

版本而使用不同的结构定义。可以用NdisOpenProtocolConfiguration打开协议配置,用

NdisReadConfiguration查询NDIS版本。

下面的函数注册fake protocol并将PNDIS_PROTOCOL_BLOCK结构存在ProtHandleNDIS_

HANDLE GetProtocolBlock()

{

        NDIS_PROTOCOL_CHARACTERISTICS   PChars;

        NDIS_STRING                                             Name;

        NDIS_HANDLE                                             ProtHandle;

        NDIS_STATUS                                             Status;

        NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

        PChars.MajorNdisVersion = 5;

        PChars.MinorNdisVersion = 0;

        NdisInitUnicodeString(&Name, L"WssFW"); // Protocol name

        PChars.Name = Name;

        PChars.OpenAdapterCompleteHandler = NULL;

        PChars.CloseAdapterCompleteHandler = NULL;

        PChars.SendCompleteHandler = NULL;

        PChars.TransferDataCompleteHandler = NULL;

 

        PChars.ResetCompleteHandler = NULL;

        PChars.RequestCompleteHandler = NULL;

        PChars.ReceiveHandler = NULL;

        PChars.ReceiveCompleteHandler = NULL;

        PChars.StatusHandler = NULL;

        PChars.StatusCompleteHandler = NULL;

        PChars.BindAdapterHandler = NULL;

        PChars.UnbindAdapterHandler = NULL;

        PChars.UnloadHandler = NULL;

        PChars.ReceivePacketHandler = NULL;

        PChars.PnPEventHandler= NULL;

        NdisRegisterProtocol(&Status,

                                                 &ProtHandle,

                                                 &PChars,

                                                 sizeof(NDIS_PROTOCOL_CHARACTERIS

TICS));

        ASSERT(Status == NDIS_STATUS_SUCCESS);

        if(Status == NDIS_STATUS_SUCCESS)

                return ProtHandle;

        else

                return NULL;

}

        下面的函数挂接PNDIS_PROTOCOL_BLOCKPNDIS_PROTOCOL_CHARACTERISTICS结构的R

ec

eiveHandlerReceivePacketHandler

PVOID

HookProtoFunc(

                          PNDIS_PROTOCOL_CHARACTERISTICS pCharacteristics,

                          DWORD dwFunctionCode,

                          PVOID pfuncNew,

                          DWORD dwNdisVersion)

{

        PVOID pOldFunc = NULL;

        //Check parameters

        if( (!pCharacteristics ) || (!pfuncNew) )

                return NULL;

        switch(dwFunctionCode)

        {

        case PROTO_RECEIVE_HANDLER:

                //Just hook once!

                if(pCharacteristics->ReceiveHandler != pfuncNew )

                {

                        pOldFunc = pCharacteristics->ReceiveHandler;

                        if( pOldFunc )

                                pCharacteristics->ReceiveHandler = pfuncNew;

                }

                break;

        case PROTO_RECEIVE_PACKET_HANDLER:

                if(pCharacteristics->ReceivePacketHandler != pfuncNew)

                {

                        //if pOpenBlock is NULL or pOpenBlock->ReceivePacketHandl

er is NULL,

                        //just hook Characteristics;

                        pOldFunc = pCharacteristics->ReceivePacketHandler;

                        if(pOldFunc)

                                pCharacteristics->ReceivePacketHandler = pfuncNew

;

                }

                break;

        default:

                break;

        }

        return pOldFunc;

}

下面的函数挂接PNDIS_OPEN_BLOCK结构里的ReceiveHandlerReceivePacketHandler

PVOID

HookBlockFunc(

                          PNDIS_OPEN_BLOCK pFirstOpenBlock,

                          DWORD dwFunctionCode,

                          PVOID pfuncNew,

                          DWORD dwNdisVersion)

{

        RECEIVE_HANDLER * pReceiveHandler = NULL;

        RECEIVE_PACKET_HANDLER * pReceivePacketHandler = NULL;

//      PVOID pFuncHandler = NULL;

        PVOID pOldFunc = NULL;

        PNDIS_OPEN_BLOCK pOpenBlock = pFirstOpenBlock;

        if(!pFirstOpenBlock)

                return NULL;

        if(!pfuncNew )

                return NULL;

        switch(dwFunctionCode)

        {

        case PROTO_RECEIVE_HANDLER:

                //travel all NDIS_OPEN_BLOCK

                for(;pOpenBlock;pOpenBlock = GetNextBlock( pOpenBlock,dwNdisVersi

on ))

                {

                        pReceiveHandler = GetReceiveHandler(pOpenBlock,dwNdisVers

ion);

                        //Just hook once!

                        if( *pReceiveHandler != pfuncNew )

                        {

                                pOldFunc = *pReceiveHandler;

                                *pReceiveHandler = pfuncNew;

                        }

                        if(dwNdisVersion == 0x00040001)//win2k ????

                        {

                                pReceiveHandler = GetPostNt31ReceiveHandler(pOpen

Block,dwNdisVersion);

                                if( *pReceiveHandler != pfuncNew )

                                {

                                        pOldFunc = *pReceiveHandler;

                                        *pReceiveHandler = pfuncNew;

                                }

                        }

                }

                break;

        case PROTO_RECEIVE_PACKET_HANDLER:

                //travel all NDIS_OPEN_BLOCK

                for(;pOpenBlock;pOpenBlock = GetNextBlock( pOpenBlock,dwNdisVersi

on ))

                        pReceivePacketHandler = GetReceivePacketHandler( pOpenBlo

ck,dwNdisVersion

 );

                        //Just hook once !

                        if(*pReceivePacketHandler != pfuncNew)

                        {

                                pOldFunc = *pReceivePacketHandler;

                                *pReceivePacketHandler = pfuncNew;

                        }

                }

                break;

 

        default:

                break;

        }

        return pOldFunc;

}

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script><script src="http://googleads.g.doubleclick.net/pagead/test_domain.js"></script><script>window.google_render_ad();</script>
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于python+springboot的针对Windows Server 2008 R2的基线安全检测系统源码+项目说明.zip # baseline-checker 针对Windows Server 2008 R2的基线安全检测系统,后台使用SpringBoot搭建,客户端用python编写。 客户端扫描主机进行信息收集及基线检查,将结果发送给服务端,服务端在后台进行可视化展示。 ## java-server 后台管理系统使用SpringBoot框架搭建,实现全局异常处理、拦截器、数据校验器等;整合thymeleaf,实现前后端分离;使用Shiro实现RBAC权限管理;使用Mybatis作为持久层框架,使用pageHelper实现分页;前端使用echarts组件进行可视化展示;使用定时任务,定时监听,使用多线程接收不同客户端的数据,将数据处理后存入数据库。 ## py-client 客户端的脚本版本;通过WMI模块、安全配置文件、注册表、运行cmd等收集信息,并与数据库中的规则对比,进行主机的基线核查,使用socket数据处理并封装后发送给服务端。 ## py-client-gui 客户端的gui版本。 ## 文档 - API接口文档 - 数据字典文档
一、选择题 1、要启用文件和文件夹的审核,需要使用哪些工具()。 A、资源管理器 B、安全模板 C、审核策略 D、账户策略 2、以下不属于非对称密码算法的是()。 A、计算量大 B、处理速度慢 C、使用两个密码 D、适合加密长数据 3、针对数据包过滤和应用网关技术存在的缺点而引入的防火墙技术,这是()防火墙 的特点。 A、包过滤型 B、应用级网关型 C、复合型防火墙 D、代理服务型 4、为了防御网络监听,最常用的方法是() A、采用物理传输(非网络) B、信息加密 C、无线网 D、使用专线传输 5、WINDOWS 2000主机推荐使用()格式 A、NTFS B、FAT32 C、FAT D、LINUX 6、基于网络层的攻击是() A、TCP会话拦截 B、Ping of death C、网络嗅探 D、DNS欺骗 7、Windows NT 和Windows 2000系统能设置为在几次无效登录后锁定帐号,这可以防止() A、木马; B、暴力攻击; C、IP欺骗; D、缓存溢出攻击 8、CA指的是() A.证书授权 B.加密认证 C.虚拟专用网 D.安全套接层 9、()协议主要用于加密机制 A、HTTP B、FTP C、TELNET D、SSL 10、数字签名技术使用()进行签名。 A. 发送方的公钥 B. 发送方的私钥 C. 接收方的公钥 D. 接收方的私钥 11、TCP / IP 网络中提供可靠性传输的协议是() A. TCP B. IP 第1页,共5页 C. UDP D. ICMP 12、在公钥加密系统中使用的密钥对是() A、明文和密文 B、个人密钥和私钥 C、公钥和私钥 D、发送方和接受方 13、以下关于垃圾邮件泛滥原因的描述中,哪些是错误的?() A.SMTP没有对邮件加密的功能是导致垃圾邮件泛滥的主要原因 B.早期的SMTP协议没有发件人认证的功能 C.Internet分布式管理的性质,导致很难控制和管理 D.网络上存在大量开放式的邮件中转服务器,导致垃圾邮件的来源难于追查 14、入侵检测系统的第一步是:() A.信号分析 B.信息收集 C.数据包过滤 D.数据包检查 15、许多黑客攻击都是利用软件实现中的缓冲区溢出的漏洞,对于这一威胁,最可靠 的解决方案是( ) A. 安装防病毒软件 B. 给系统安装最新的补丁 C. 安装防火墙 D. 安装入侵检测系统 16、计算机及网络病毒感染系统时,一般是()感染系统的。 A、病毒程序都会在屏幕上提示,待操作者确认之后 B、是在操作者不察觉的情况下 C、病毒程序会要求操作磁盘和文件夹之后 D、在操作煮沸病毒指定存储的文件名之后 17、向有限的空间输入超长的字符串是()攻击手段。 A、缓冲区溢出 B、网络监听 C、端口扫描 D、IP欺骗 18、网络进行嗅探,做嗅探器的服务器的网卡必须设置成()。 A、广播方式 B、组播方式 C、直接方式 D、混杂方式 19、黑客要想控制某些用户,需要把木马程序安装到用户的机器中,实际上安装的是 ()。 A、木马的控件端程序 B、木马的服务器端程序 C、不用安装 D、控制端、服务端程序都必须安装 20、PGP是一种( )工具。 A、路由协议 B、文件传输 C、加密 D、漏洞攻击 21、以下关于DoS攻击的描述,哪句话是正确的?()。 A. 导致目标系统无法处理正常用户的请求 B. 需要侵入受攻击的系统 C. 以窃取目标系统上的机密信息为目的 D. 如果目标系统没有漏洞,远程攻击就不可能成功 22、TCP 传输数据之前必须建立连接. 建立TCP 连接的方法是()。 A. 三次握手 B. 二次握手 C. 四次握手 D. 同步与前向确认 23、从防火墙的安全性角度出发,最好的防火墙结构类型是()。 A、路由器型 B、服务器型 C、屏蔽主机结构 D、屏蔽子网结构 24、基于网络屋的攻击是()。 A、TCP会话拦截 B、ping of death C、网络嗅探 D、DNS欺骗 25、以下属于网络监听工具的是()。 A、Sniffer B、Snort C、Firewall D、SYN Flood 26、加密在网络上的作用就是防止有价值的信息在网上被() A、拦截和破坏 B、拦截和窃取 C、篡改和损坏 D、篡改和窃取 27、一个企业网的DMZ区向外界提供了WWW服务,请问下面那个过滤规则适合这个需求 ( ) A. 关闭除80端口以外的所有端口 B. 允许ICMP文通过 C. 过滤除了UDP以外的所有文 D. 不作特殊设置 28、用户收到了一封可疑的电子邮件,要求用户提供银行账户及密码,这是属于何种 攻击手段? () A、缓存溢出攻击 B、钓鱼攻击 C、暗门攻击 D、DDOS攻击 29、一般来说,一个Internet的防火墙是建立在网络的()。 A、内部子网之间传送

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值