一个包过滤型个人防火墙软件的开发
毕业设计(论文)
题目: 一个包过滤型防火墙软件的开发
学 班 级: 专
2011 年 6 月
一个包过滤型防火墙软件的开发
学生姓名:
学 号:
班 级:
所在院(系):
指导教师:
完成日期:
一个包过滤型个人防火墙软件的开发
摘 要
随着病毒、木马、黑客攻击等问题的出现,网络安全形势日渐严峻,网络安全产品也被人们重视起来。防火墙作为最早出现的网络安全产品和使用量最大的安全产品,也受到用户和研发机构的青睐。防火墙放置在外部网络与计算机之间作为隔离设备,可以识别并屏蔽非法请求,有效防止跨越权限的数据访问。 本文使用VC++ 6.0作为开发工具实现了一个包过滤型个人防火墙软件。系统主要包括两大模块,一是核心模块设计,即DLL工程,实现了封包截获、管制动作和协议封包的解析任务。其中实现网络封包截获功能主要是利用Winsock 2 SPI技术,此后再利用控管规则对过往封包进行合法性检查和过滤,方法是首先利用Winsock 2 SPI技术建立winsock钩子,用它来截获winsock的调用,然后作出相应动作处理,动作处理需通过控管规则的检查后,确定socket连接是否允许通过,而控管规则由用户层设置;二是用户模块设计,即EXE工程,实现用户界面和负责与DLL模块的通信,提供了3个主要界面,即封包监视、控管规则、控管规则设置。最后通过测试和应用,基本达到了预期的设计,解决了终端用户的网络连接安全问题。
关键词: 网络安全;网络协议封包;个人防火墙;动态链接库;Winsock 2 SPI;
The Design of A Personal Firewall Based on Packet Filter
Abstract
With computer viruses, Trojans, hacker attacks and other problems, the network security situation is increasingly grim, network security products are also paid attention. Network firewall appeared as the first security products and be used most widely, are concerned by the user and R & D institutions of all ages. Place a firewall between the external network and the computer as an isolation device that can identify and shielding illegal request, it’s can effectively prevent access to data across the authority.
This article uses the VC + + 6.0 as a development tool to implement a packet filter-based personal firewall software. System includes two modules, one core module design, the DLL project to achieve the packet capture, control actions and agreements packet parsing tasks. In which the main function for network packet capture is the use of Winsock 2 SPI technology, this use of control rules in the past then the legitimacy of the packet inspection and filtering, the method is to first use of technology to establish winsock Winsock 2 SPI hook, use it to intercept winsock calls treatment and then make the corresponding action, action processing rules to be checked through the control to determine the socket connection is allowed through, while the control rules set by the user layer; Second, the user module design, the EXE project, responsible for achieving the user interface and DLL The communications module provides three main interfaces, namely, packet monitoring, control rules, control rules set. After testing and application, the design achieve the expected to solve the security problems of user's network connection.
Key words: Network Security;Network Protocol Packets;Personal Firewall;DLL; Winsock 2 SPI;
目录
1 引言 ............................................................................................................................ 1
1.1 课题背景与意义 .............................................................................................. 1
1.2 课题目标 .......................................................................................................... 1
1.3 课题的研究方法 .............................................................................................. 1
2 WINSOCK 2 SPI编程技术 ....................................................................................... 3
2.1
2.2
2.3 WINSOCK 2 SPI基础..................................................................................... 3 传输服务提供者 .............................................................................................. 3 开发平台与开发工具 ...................................................................................... 4
3 系统总体分析与设计 ................................................................................................ 5
3.1
3.2 系统功能定义 .................................................................................................. 5 模块划分 .......................................................................................................... 5
3.2.1 模块划分原则 ............................................................................................... 5
3.2.2 模块结构 ....................................................................................................... 6
3.2.3 模块接口定义 ............................................................................................... 7
3.3
3.4 程序工作流程图 .............................................................................................. 8 控管规则文件结构设计 .................................................................................. 9
3.4.1 控管规则文件需要存储的内容 ................................................................... 9
3.4.2 控管规则文件结构 ..................................................................................... 11
3.5 界面设计 ........................................................................................................ 11
3.5.1 制定界面风格 ............................................................................................. 11
3.5.2 界面设计文档 ............................................................................................. 12
3.6 编码规则 ........................................................................................................ 16
4 核心功能的实现 ...................................................................................................... 17
4.1
4.2 封包截获 ........................................................................................................ 17 访问控管 ........................................................................................................ 21
4.2.1 对服务提供者函数做管制的函数 ............................................................. 21
4.2.2 封包处理函数 ............................................................................................. 22
目录
1 引言 ............................................................................................................................ 1
1.1 课题背景与意义 .............................................................................................. 1
1.2 课题目标 .......................................................................................................... 1
1.3 课题的研究方法 .............................................................................................. 1
2 WINSOCK 2 SPI编程技术 ....................................................................................... 3
2.1
2.2
2.3 WINSOCK 2 SPI基础..................................................................................... 3 传输服务提供者 .............................................................................................. 3 开发平台与开发工具 ...................................................................................... 4
3 系统总体分析与设计 ................................................................................................ 5
3.1
3.2 系统功能定义 .................................................................................................. 5 模块划分 .......................................................................................................... 5
3.2.1 模块划分原则 ............................................................................................... 5
3.2.2 模块结构 ....................................................................................................... 6
3.2.3 模块接口定义 ............................................................................................... 7
3.3
3.4 程序工作流程图 .............................................................................................. 8 控管规则文件结构设计 .................................................................................. 9
3.4.1 控管规则文件需要存储的内容 ................................................................... 9
3.4.2 控管规则文件结构 ..................................................................................... 11
3.5 界面设计 ........................................................................................................ 11
3.5.1 制定界面风格 ............................................................................................. 11
3.5.2 界面设计文档 ............................................................................................. 12
3.6 编码规则 ........................................................................................................ 16
4 核心功能的实现 ...................................................................................................... 17
4.1
4.2 封包截获 ........................................................................................................ 17 访问控管 ........................................................................................................ 21
4.2.1 对服务提供者函数做管制的函数 ............................................................. 21
4.2.2 封包处理函数 ............................................................................................. 22
4.2.3 管制函数 ..................................................................................................... 23
4.2.4 设置函数 ..................................................................................................... 27
5 系统测试 .................................................................................................................. 28
5.1测试方法概述 ................................................................................................. 28
5.2 测试用例及测试结果 .................................................................................... 28
6 结束语 ...................................................................................................................... 34
6.1总结 ................................................................................................................. 34
6.2展望 ................................................................................................................. 34
参考文献 ...................................................................................................................... 35
致 谢 ...................................................................................................................... 37
1 引言
1.1 课题背景与意义
随着网络在各领域应用的越来越广泛,网络安全问题得到了更多的关注。计算机病毒攻击可以导致电脑系统瘫痪;而木马和黑客攻击可致使重要信息被窃取,造成不可估量的损失。所以人们开始寻求如何能在电脑和网络间添加一种可靠保护体系。防火墙就此应运而生。顾名思义,防火墙能够在计算机和网络间形成一道过滤屏障,保证被认可的行为顺利执行,而危险行为则被屏蔽。从而很大程度上增加了网络的安全性。
1.2 课题目标
现在防火墙的花样与种类繁多,让人眼花缭乱。但是防火墙的主要功能是防止外部网络的攻击以达到保护主机的目的。哪些未知的网络IP可能对主机产生攻击可能是未可知的,只有试验过才知道。所以现在防火墙一般与防病毒软件配合使用。这样才能安全的保护主机。
实现的主要的核心功能如下定义:
(1) 根据应用程序访问规则可对应用程序连网动作进行过滤;
(2) 对应用程序访问规则具有自学习功能;
(3) 可实时监控、监视网络活动。
1.3 课题的研究方法
本课题由两大模块构成,分别为DLL模块和EXE模块。
首先利用Winsock 2 SPI技术建立winsock钩子用来截获winsock调用从而拦截TCP/IP封包,并做相应处理。然后设置控管规则访问控制,通过控管规则的检查认证,确定socket连接是否允许通过。在此之后是TCP/IP的封包分析,利
【1】用TIP/IP的封包结构分析截获的数据,提取需要的数据。这些封装在DLL里面。
EXE模块主要是用户页面的制作。这里介绍与DLL模块通信的地方。EXE中与DLL直接通信的小模块主要有两个。一个是完成应用程序初始化的类
CPropertyApp,它继承自CWinApp,是EXE的入口,其实里面封装了WinMain函数;另一个是主窗口模块CMainFrame,这个主窗口并不是EXE显示出来的那个属性页窗口,而是一个隐藏的窗口,它继承自CMrameWnd,是一个无模式窗口,他隐藏显示,充当接受机,用来接受DLL及其他模块发送过来的消息,然后对消息进行相应的处理。
每一个连网的程序连网之前都会建立一个Socket连接。这时钩子程序就会起作用,把截获的底层服务进行“过滤”,及先调用自定义的函数再转给下层服务提供者函数【2】。本文将这一层实现封包过滤的,把规则与功能写到这一层。本层的实现是本课题的核心。
2 WINSOCK 2 SPI编程技术
Winsock 2是Windows Sockets的2.0版本,在此之前的版本是1.1。与1.1版本相比,2.0版本引入了一种新的叫做SPI的编程接口。利用这种技术可以在Socket中插入一曾层,从而可以完成诸如扩展TCP/IP协议栈,网络安全控制等功能,所以这是一个非常强大而且有用的接口,下面介绍这种编程技术。
2.1 WINSOCK 2 SPI基础
Winsock是为上层应用程序提供的一种标准网络接口,上层应用程序不用关心Winsock实现的细节,它为上层应用程序提供透明的服务。
Winsock 2 引入的一个新的功能就是打破服务提供者的透明,让开发者可以编写自己的服务提供者接口程序,即SPI程序。SPI以动态链接库的形式存在,它工作在应用层,为上层API调用接口函数【3】。Winsock 2是一个接口,不是一个协议。作为接口,它只能发现和利用底层传输协议完成通信。
自己编写的SPI程序安装到系统之后,所有的Winsock请求都会发送到这个程序并由它完成网络调用。由于系统提供的SPI已经可以完成网络传输功能,所以自己编写的SPI没有必要重新编写这部分功能。一般可以直接调用系统函数完成网络传输,这样工作的效果就是“钩子程序。
Winsock 2 SPI除了有完成网络传输的传输服务提供者,还有提供友好名称服务的名字空间服务提供者。传输服务提供者能够提供建立通信、传输数据、流量控制和错误控制等服务。名字空间服务提供者把一个网络协议的地址属性和一个或多个用户友好名称关联起来,这样可以起用与协议无关的名字解析方案。
2.2 传输服务提供者
传输服务提供者又分为基础服务提供者和分层服务提供者。基础服务提供者和分层服务提供者都开放相同的SPI接口,所不同的是基础服务提供者位于提供者的最底层。所以编写基础服务提供者和分层服务提供者基本相同。但安装是却需要将基础服务提供者安装在服务提供者加载顺序链的最底端,而分层服务提供
者则根据需要分布在顺序链的中间。
2.3 开发平台与开发工具
开发平台如题说明,以Windows平台为主,重点讨论开发工具的选择。 根据不同的工程选择不同的开发工具,可以有效地提高工作效率。不同的开发工具各有各的优点同时又各有各的不足,在开发中要扬长避短。
目前常用的Windows开发工具有VS 5.0/6.0、VS.net(包括VB、BC、VFP、VJ、C#等一组开发工具)、delphi、C++ Builder,JBuilder、PB等【4】。
在这些开发工具里面,VFP和PB一般用来专门开发数据库系统,它们具有灵活的数据库接口。
VB和Delphi既可以方便地做出复杂的数据库管理系统,又能轻松地完成操作系统级的任务。最优秀的是很容易做出漂亮的界面。
VC和Borland C++着重于系统编程,它们开放接口较多,也最为灵活,而且编译出的程序体积较小,所以比较适合做系统工具类软件。缺点是短时间不容易掌握。其中Borland 使用的VCL类库是为Delphi准备的,并不是真正用C++实现的。
VJ、Jbuilder和Java语言主要面向互联网应用。最大的优势是跨平台。 本课题为防火墙软件,较多的使用系统接口,而且界面简单。另外,防火墙主要传播渠道是互联网,这就要求体积应尽量的小,安装尽量方便。所以选择VC为开发工具。
3 系统总体分析与设计
3.1 系统功能定义
本设计实现的具体功能描述如下:
(1) 封包监视
① 提供封包监视页面。
② 提供清空监视列表,停止/开始监视及停止/开始滚动功能。
(2) 控管规则设置
① 手工添加,删除及修改控管规则。
② 自学习添加控管规则。
③ 控管规则中目的网络IP地址段的设置。
④ 提供控管规则设置页面。
(3) 封包过滤
① DLL给出设置工作模式和设置控管规则的接口函数。工作模式分为
3种形式:放行所有,拒绝所有和过滤。
② DLL根据工作模式和控管规则对过往封包进行过滤。
③ DLL将通过的网络封包通知EXE取走 。
3.2 模块划分
3.2.1 模块划分原则
模块划分是系统分析中非常重要的一部分,下面是模块划分时的基本原则。
(1) 独立性:让模块直接内的关系减到最少。理想的状态就是模块之间没有关系,但这种情况不符合现实。既然是同一个工程,模块之间自然都会存在一定的联系,只要想办法让模块之间的关系尽量简单就可以了。
(2) 接口简单化:让模块之间的接口尽量单纯、简单、易用。即让公用函数和公用变量尽量地少。
(3) 分层处理:吸取Windows操作系统对模块做分层处理的经验。建立一些中间模块,让两端的模块来完成相互调用的透明化。
(4) 容易合并:容易将划分的模块进行合并。例如将一个工程的各个功能模块分别设计成可执行文件,然后用一个总模块将这些模块关联起来组成一个工程。这种情况下,对模块独立性要求较高,模块之间几乎没有任何关系。
(5) 可测试性:尽量使每个模块都可以单独进行测试[6]。
上面的5条是参考原则,既然是参考原则就不会完全执行,完全按照一个教条去执行真的很困难。只要在做模块划分的时候能经常记起这些原则,然后稍加注意就OK了。另外,在这5条原则中,第一条是根本,能把这一条做好,下面的一些就容易实现了。在做模块划分时一定要始终贯穿独立性的思想。
3.2.2 模块结构
根据3.1节的功能定义和3.2节的工作流程图,需要对模块做进一步细化,得出更详细的模块结构。这些模块结构是编程的蓝本,在编写代码的过程中,就要以这些结构为指导。
(1) 模块1.1:用户界面,3.5节详细说明。
(2) 模块1.2:EXE的安装模块,。建立CXInstall类,C++源文件Install.h和Install.cpp。安装函数InstallProvider和卸载函数RemoveProvider
(3) 模块1.3:EXE读写控管规则模块,建立CAclFile类,C++源文件File.h和File.cpp。读控管规则文件ReadAcl,保存控管规则文件SaveAcl,增加一条控管规则AddAcl和删除一条控管规则DelAcl。
(4) 模块1.4:EXE设置DLL的控管规则模块,设置控管规则单独的函数,调用模块1.3读写控管规则模块得到控管规则数据,调用DLL的函数FloControl设置DLL的控管规则。
(5) 模块1.5:EXE设置DLL的工作模式,设置工作模式单独的函数,调用模块1.3读写控管规则模块得到控管规则数据,调用DLL的函数FloControl设置DLL的工作模式。
(6) 模块2.1:DLL封包过滤模块,有分为3块,2.1.1一组Winsock 2SPI钩
子函数C++源文件TcpipDog.h和TcpipDog.cpp;模块2.1.2根据控管规则判断是否可以通行的类CCheckAcl,C++源文件CheckAcl.h和CheckAcl.cpp;模块2.1.3对网络数据包进行分析的类CProtocolInfo,C++源文件ProtocolInfo.h和ProtocolInfo.cpp。
① 模块2.1.1:服务提供者函数模块,入口函数WSPSartup,发送询问消息到EXE,由EXE提供询问界面函数QueryAccess。截获的8个服务提供者函数。设置工作模式、控管规则等设备工作接口函数FloControl。
② 模块2.1.2:访问控管模块,通过检查工作模式和控管规则得到是否放行的函数GerAccessInfo。
③ 模块2.1.3:协议解析模块,得到协议信息处理函数GetProtocolInfo
(7) 模块2.2:DLL更改控管规则模块,设置DLL控管规则数据SetAcl,设置控管规则m_Aclfile,设置工作模式m_iWorkMode。
(8) 模块2.3:DLL更改工作模式模块,设置DLL工作模式函数SetWorkMode。
3.2.3 模块接口定义
模块之间接口有3种方式:
(1) 函数接口
函数接口是最常用而且独立性和封装性最好的接口方式[7]。函数之间通过参数传递进行模块之间的通信,处理过程保持相互独立,函数处理完成把处理结果返回到调用模块。如果每个函数都有单独的接口,那么,函数多了,接口也就多了,也就越来越复杂了。C++利用类的饿概念解决这个问题。类可以将一组函数和变量封装起来,这样就将许许多多的函数转化成一个对象的形式。外部模块使用这个类的实例来引用封装在里面的成员函数个变量。把功能相似、相关的函数分成一组,然后封装在一起,使接口间的关系清晰了很多。类的成员函数和成员变量有公有和私有之分。对于公有函数和变量,外部模块可以直接调用;对于私有函数和变量,外部模块则不能直接调用。利用这种特性,可以把一些只在类里面使用的函数定义为私有函数;把外部模块需要直接调用的函数定义为公有函
数。类似于DLL的导出函数(Export),这样,模块之间的直接接触就会进一步减小,独立性更进一步增加。
(2) 全局变量接口
全局变量接口是一种不提倡的方式。虽然它使用起来确实很过瘾。全局变量多了非常容易出问题。任何地方都可能会对全局变量进行赋值,变量的可控性大大降低,不知道什么时候变量的值就被莫名其妙地改掉了。当然,只要不被那些模块执行的先后顺序和循环语句弄昏头,还是可以使用全局变量的。虽然不提倡使用,但是有些地方使用全局变量与是不可避免的,而且有时候可以减少很多麻烦。使用全局变量的时候需要注意一点,读取变量的多少和位置对程序稳定性的影响并不很大,关键是尽量让赋值的地方单一,改变变量的次数和位置应尽量得到控制。
(3) Windows消息接口
Windows消息接口是一种特殊的接口形式,它是基于Windows操作系统的消息机制[8]。这种接口形式适合于应用程序之间。应用程序是相对独立的模块,如果这两个模块需要通信,则消息接口就是一种理想型的选择。这种接口类似于函数接口,只不过通过操作系统的消息机制来中转一下。Windows消息接口也是一种接口方式,特别是DLL和EXE之间经常用到。在DLL与EXE之间通信使用消息是一种优势,多个应用程序虽然调用同一个DLL,但是它们都拥有独立的模块副本。这时候如果这些模块副本都需要让同一个应用程序做一件事时,就不好处理,因为DLL的重要性和应用程序保护机制导致这些模块副本无法直接调用同一个应用程序的执行模块。这时候就可以通过消息的方式来解决。发送消息是基于窗口句柄的,只要得到这个窗口句柄,不同的DLL副本都向同一个窗口句柄发送消息,自然所有的消息都可以被同一个应用程序接收[9]。
以上3种接口方式以函数接口为优先进行考虑,以增强模块的独立性和可读性。
3.3 程序工作流程图
Winsock 2 SPI是一个DLL程序,它工作在API和DRIVER之间,为上层应
用程序提供服务【5】。EXE与DLL构成软件的主体,也是编写软件的主要工作。流程图如图3.1所示。
图3.1防火墙工作流程图
3.4 控管规则文件结构设计
控管规则文件用来存储控管规则数据,命名为acl.cfg;该数据文件为二进制文件。
3.4.1 控管规则文件需要存储的内容 控管规则文件需要存储的内容如下: (1) 系统设置 (2) 控管设置
(3) 控管规则附加数据,授权访问的远端网络IP地址记录 a.控管规则记录结构说明
(1) 规则编号字段是控管规则的唯一性编号。保留字段,没有使用。 (2) 应用程序名称及路径字段用来保持应用程序的名称和路径。 (3) 远端网络类型,数值的含义如下。
0:表示所有网络
1:局域网
2:约束的网络(自定义) 3:信任的网络(自定义) 4:自定义的网络(自定义) (4) 管制动作,数值的含义如下。
0:放行 1:拒绝
(5) 进出方向,数值的含义如下。
0:出 1:入 2:双向
(6) 服务类型,数值的含义如下。
0:全部
1:TCP(端口为任意,可编辑) 2:UDP(端口为任意,可编辑) 3:FTP(端口为21,不可编辑) 4:TELNET(端口为23,不可编辑) 5:HTTP(端口为任意,可编辑) 6:NNTP(端口为119,不可编辑) 7:POP3(端口为110,不可编辑) 8:SMTP(端口为25,不可编辑) (7) 服务端口,数值的含义如下。
0:表示全部 其他值:表示端口值 b.授权访问的远端IP地址记录结构
授权访问的远端网络IP地址结构如表1所示。
表1 授权访问的远端网络IP地址段记录结构
3.4.2 控管规则文件结构
根据需要存储的内容将控管规则文件划分为3段。
文件头用来存储系统设置,IP地址范围记录和控管规则记录的地址偏移量及其他信息[10];IP
地址范围记录存储区用来存储IP地址范围记录;控管规则记录存储区用来存储控管规则记录。
a. 控管规则结构
控管规则结构如表2所示。
表2 控管规则记录结构表
b. IP地址结构
IP地址段记录结构如表3所示。
表3 IP地址段记录结构表
3.5 界面设计
3.5.1 制定界面风格
界面上反映的功能有:封包监视、控管规则设置。这是两个平行的功能,所以选用Windows的属性页。
3.5.2 界面设计文档 界面设计如下所示。 a. 封包监视界面
封包监视界面用来显示截获的网络封包。每个网络封包的具体内容根据实际需要而定。如图3.2。
图3.2 封包监视界面
封包的字段有:
(1) 应用程序路径和名称 (2) 管制动作(放行或拒绝) (3) 访问起始/结束时间 (4) 使用网络协议 (5) 进/出流量
(6) 本地和远端IP地址/端口 (7) 备注信息
封包监视界面实时接收DLL发送过来的网络封包并立刻显示。
在封包监视界面上设计了几个附加按钮。“停止/开始滚动”用来设置监视列表是否自动滚动;“开始/停止监视”用来设置是否实时监视;“清除”按钮用来清除当前列表。这些功能按钮方面操作。
b. 控管规则界面
控管规则界面用来显示和设置控管规则(如图3.3)。需要说明的是,应用程序设置的优先级高于控管规则设置,只是在应用程序设置为询问时,下面的控管规则设置才有效。
图3.3 控管规则界面
控管规则的设计目的是为了制订对网络访问的控制,所以控管规则的字段可以决定防火墙防范的严密性和灵活程度。控管规则的记录结构为:
应用程序 远端网络 管制动作 进出方向
协议类型
使用端口
控管规则界面给出了“增加”、“删除”、“修改”3个功能按钮用来对控管规则进行不同的操作。其中选择增加和修改时都会弹出控管规则设置界面。
(1) 控管规则设置界面
控管规则设置界面是用来设置控管规则的各个字段(如图3.4)。在“应用程序”栏输入或选择要进行控管的应用程序的完整路径和文件名。
“远端网络”用IP地址范围表示,用来定义网络类型的IP地址范围。本软件工划分为5个类型:所有网络、局域网、受约束的网络、信任的网络和自定义网络。
“动作”用来确定符合这一条控管规则的网络访问动作是放行还是拒绝。 “方向”用来确定这一条控管规则适合于网络访问的连接方向。本机向远端服务器发出连接请求就是出;远端主机向本机发出连接请求则为进。
“类型”是控管规则约定的协议类型。
“端口”是协议所使用的端口。
图3.4 控管规则设置界面
(2) 网络设置界面
网络设置界面用来对各种网络类型的IP地址段进行设置(如图3.5),在上节有关于远端网络类型的介绍。在这个界面上提供对IP地址段的增加、修改和删除功能
图3.5 网络设置界面
3.6 编码规则
变量命名规则如下:
(1) 变量采用代表中文意思的英文单词或单词组合。
(2) 变量一般不用缩写,用英文单词全称。较长的更为习惯的缩写。
(3) 自定义全局变量用m_开头。
(4) 自定义过程变量不用m_开头。
(5) 变量的前缀用变量类型的第一个字母标志变量类型。如,指针类型在前
面多加一个字母P。
(6) 如果是对象,前缀用对象的名称,第一个字母大写。
(7) 变量中有多个单词时,单词的第一个字母大写,其余用小写。
(8) 有了自己的编码规则后,不会出现自己的弄不清楚自己定义的函数之类
的是什么意思。不知道函数是干什么的。以至于思维混乱。
4 核心功能的实现
本课题的核心功能实现封装在DLL里面。下面分析DLL的主要内容。
4.1 封包截获
BOOL WINAPI DllMain是DLL的入口函数,系统调用时的标准接口[12]。做一些初始化工作。主要工作是得到调用这个程序的进程路径和名称并设置DLL调用次数的计数器。
WSPStartup是Windows Sockets应用程序调用SPI的初始化函数。是服务提供者的标准入口函数。这里的工作是根据lpProtocolInfo找出已经被替换的服务提供者路径,然后加载,并利用被替换服务提供者的WSPStartup得到30个服务函数指针。需要先保存这些函数指针,然后将lpProcTable结构中的30个服务函数指针都设置成自己的。这样,相应的函数请求会首先经过我们自己的函数,然后用这些函数可以做适当的处理,再调用原来的,将请求转发,完成整个通信。 int WSPAPI WSPStartup(
)
{
ODS(_T("WSPStartup...")); if(!m_CheckAcl.m_bIsWin9x && m_CheckAcl.CheckStartup() == XF_QUERY WORD wVersionRequested, lpWSPData, lpProtocolInfo, LPWSPDATA LPWSAPROTOCOL_INFOW WSPUPCALLTABLE upcallTable, lpProcTable LPWSPPROC_TABLE && !QueryAccess())
return SOCKET_ERROR; TCHAR sLibraryPath[512];
LPWSPSTARTUP WSPStartupFunc = NULL;
HMODULE hLibraryHandle = NULL;
INT ErrorCode = 0;
if(!GetHookProvider(lpProtocolInfo,sLibraryPath)|| (hLibraryHandle =LoadLibrary(sLibraryPath))==NULL||(WSPStartupFunc=(LPWSPSTARTUP)GetProcAddress(hLibraryHandle, "WSPStartup")) == NULL)
return WSAEPROVIDERFAILEDINIT; if((ErrorCode=WSPStartupFunc(wVersionRequested,lpWSPData,lpProtocolInfo, upcallTable, lpProcTable)) != ERROR_SUCCESS)
return ErrorCode; if( !lpProcTable->lpWSPAccept || !lpProcTable->lpWSPAddressToString || !lpProcTable->lpWSPAsyncSelect || !lpProcTable->lpWSPBind || !lpProcTable->lpWSPCancelBlockingCall ||
!lpProcTable->lpWSPCleanup ||
!lpProcTable->lpWSPCloseSocket || !lpProcTable->lpWSPConnect || !lpProcTable->lpWSPDuplicateSocket || !lpProcTable->lpWSPEnumNetworkEvents || !lpProcTable->lpWSPEventSelect || !lpProcTable->lpWSPGetOverlappedResult || !lpProcTable->lpWSPGetPeerName || !lpProcTable->lpWSPGetSockName || !lpProcTable->lpWSPGetSockOpt || !lpProcTable->lpWSPGetQOSByName || !lpProcTable->lpWSPIoctl ||
!lpProcTable->lpWSPJoinLeaf || !lpProcTable->lpWSPListen ||
!lpProcTable->lpWSPRecv ||
!lpProcTable->lpWSPRecvDisconnect || !lpProcTable->lpWSPRecvFrom || !lpProcTable->lpWSPSelect || !lpProcTable->lpWSPSend || !lpProcTable->lpWSPSendDisconnect || !lpProcTable->lpWSPSendTo || !lpProcTable->lpWSPSetSockOpt || !lpProcTable->lpWSPShutdown || !lpProcTable->lpWSPSocket || !lpProcTable->lpWSPStringToAddress ) return WSAEINVALIDPROCTABLE; EnterCriticalSection(&gCriticalSection); NextProcTable = *lpProcTable; lpProcTable->lpWSPSocket = WSPSocket; = WSPCloseSocket; = WSPConnect; = WSPAccept; = WSPSend; lpProcTable->lpWSPCloseSocket lpProcTable->lpWSPConnect lpProcTable->lpWSPAccept lpProcTable->lpWSPSend lpProcTable->lpWSPSendTo lpProcTable->lpWSPRecv = WSPSendTo; = WSPRecv; = WSPRecvFrom; lpProcTable->lpWSPRecvFrom
//以上是我们截获并要用自己定义的函数。
LeaveCriticalSection(&gCriticalSection); return 0;
}
XfIoControl是供EXE调用的。用来设置DLL的配置信息和得到DLL的反馈信息,这个函数为EXE提供接口,EXE通过这个函数来设置工作模式,或得到截获的网络封包信息。
QueryAccess是在应用程序提交连网请求时,如果发现控管规则中没有关于这个应用程序的控管规则,并且工作模式为询问,则向拥护发出询问,是否让这个程序通行。
GetHookProvider用来读取注册表得到系统的SPI的DLL路径和文件信息。这个信息是安装时自己写入的。根据pProtocolInfo信息取出自己保存的、已经被本程序替换的服务提供者路径。
GetRightEntryIdItem是供GetHookProvider()调用的扩展函数,用来得到保存系统服务提供者路径的注册表键名。及得到已经被本程序替换的服务提供者的dwCatalogEntryId。
XfShutdown调用系统服务提供者函数WSPShutdown,关闭一个Socket连接。并设置相应的错误代码。
截获的服务提供者函数:
过滤WSPSocket。WSPSocket是用来创建Socket的函数【15】,首先调用底层函数得到新创建的Socket,然后设置新建Socket的协议信息,并调用自定义函数CheckSocket为这个Socket建立Session,然后保存相应的信息。
过滤WSPCloseSocket。转发之前首先调用自定义函数CheckCloseSocket删除相应的Session。
过滤WSPConnect。当一个Socket建立连接后调用这个函数,转发之前先调用访问控制函数CheckConnect,检查是否放行。如果不放行,返回错误;如果放行,调用底层WSPConnect函数进行转发。
过滤WSPAccept。用来接受一个连接请求。首先调用底层函数,然后对连接的合法性进行检查,如果不允许通过,关闭这个连接
过滤WSPSend。这个函数用来发送面向连接的数据,先检查是否允许通过,
然后进行转发。
过滤WSPSendTo。这个函数用来发送面向无连接的数据,先检查是否允许通过,然后进行转发。
过滤WSPRecv。这个函数用来接收面向连接的数据。首先判断是不是重叠操作并且设置回调函数。如果设置,则用自定义函数AddOverlapped保存参数信息,然后用自己的回调函数代替原来的并转发。转发后根据返回值判断操作是否成功,如果成功,则调用控管函数对操作的合法性进行判断;否则直接返回。
过滤WSPRecvFrom。这个函数用来接收面向连接的数据。首先判断是不是重叠操作并且设置回调函数。如果设置,则用自定义函数AddOverlapped保存参数信息,然后用自己的回调函数代替原来的并转发。转发后根据返回值判断操作是否成功,如果成功,则调用控管函数对操作的合法性进行判断;否则直接返回。
4.2 访问控管
编写一个CCheckAcl。它封装了一组对访问权限进行控制的函数。访问权限主要是由控管规则设置决定。另外还封装了一组网络封包操作函数。下面是一些主要函数及相应代码。
4.2.1 对服务提供者函数做管制的函数
CheckStartup:应用程序连网前的访问控制权限。在服务提供者函数WSPStartup中对访问权限进行控制。WSPStartup是Winsock 2 SPI入口函数,每个应用程序连网时调用且仅调用一次这个函数。
CheckSocket:检查WSPSocket函数,Socket用来创建Socket,在Socket创建时没有必要进行控管,所以仅仅用来创建Session并保存协议信息。
CheckCloseSocket:WSPCloseSocket函数的预处理函数,用来删除相应的Session。
CheckConnet:检查连接是否合法。在服务提供者函数WSPConnet调用系统WSPConnet函数建立之前,用CheckConnet调用SetSession填充一些网络封包信息,然后调用GetAccessInfo判断这个连接是否被允许通过。
CheckAccept:检查是否允许接受这个Socket连接。在服务提供者函数WSPAccept调用系统函数WSPAccept接受一个Socket连接后,用CheckAccept调用SetSession设置网络封包信息,然后调用GetAccessInfo检查这个Socket连接是否允许通过。
CheckSend:在发送面向连接的数据前检查是否放行。在服务提供者函数WSPSend调用系统函数WSPSend发送数据前,用CheckSend调用SetSessionEx和GetProtocolInfo设置网络封包信息,然后调用GetAccessInfo检查是否允许这个发送操作通过。
CheckSendTo:在发送面向连接的数据前检查是否放行。在服务提供者函数WSPSendTo调用系统函数WSPSendTo发送数据前,用CheckSendTo调用SetSessionEx和GetProtocolInfo设置网络封包信息,然后调用GetAccessInfo检查是否允许这个发送操作通过。
CheckRecv:在接收面向连接的数据时检查是否放行。在服务提供者函数WSPRecv调用系统函数WSPRecv发送数据后,用CheckRecv调用SetSessionEx和GetProtocolInfo设置网络封包信息,然后调用GetAccessInfo检查是否允许这个接收操作通过【17】。
CheckRecvFrom:在接收面向连接的数据时检查是否放行。在服务提供者函数WSPRecvFrom
调用系统函数WSPRecvFrom发送数据后,用CheckRecvFrom调用SetSessionEx和GetProtocolInfo设置网络封包信息,然后调用GetAccessInfo检查是否允许这个接收操作通过。
4.2.2 封包处理函数
InitializeSession 对网络封包记录进行初始化。
CreateSession 创建一个新的网络封包记录。根据参数s和nProtocol得出协议信息,并将时间和应用程序信息一并写进这个新建的网络封包记录里。
DeleteSession 从已有的网络封包记录中删除一条。在删除之前首先调用SendSessionToApp函数,将需要删除的记录发送给EXE。
FinallySession将所有没有结束的网络封包记录全部发送到EXE中,有EXE显示在封包监视界面上。
SendSessionToApp将传递过来的网络封包记录保存到进程间的共享变量里,然后通过消息告诉EXE从变量中取出封包。
GetSessionAndSetSessionNullEXE用来得到封包数据并在得到后将缓冲区清空。
4.2.3 管制函数
IsLocalIP:判断IP地址是否为本机IP,同时判断本次调用DLL的应用程序是否为需要放行的超级进程。
GetAccessInfo:得到访问权限信息。调用GetAccessFromAcl扩展函数进一步得到访问的权限信息。
GetAccessFromWorkMode:从工作模式判断是否放行。
GetAccessFromAcl:用网络封包记录和控管规则进行对比,得到连接的访问权限。这个函数首先检查网络封包记录的完整性。如果数据不完整则直接放行。然后判断目的地址是否为本机,或应用进程是否为超级进程,如果是则放行,否则利用控管规则继续判断。如图4.1所示。
图4.1 控管规则比对流程图
int CCheckAcl::GetAccessFromAcl(SESSION *mSession) {
//下面的判断语句表示:如果控管规则文件无效,进程名无效,是本机IP或是超级进程,则返回放行动作。
if(_tcscmp(m_AclFile.mAclHeader.sSignature,XF_INVALID_PROCE
SS)==0||_tcscmp(m_sGuiPathName,m_sProcessName)==0||IsLocalIP(&mSession->ulRemoteIP) )
return XF_PASS;
iRet;
int
//下面5行表示:从工作模式判断是否放行。
if((iRet = GetAccessFromWorkMode()) != XF_FILTER)
return iRet;
BOOL IsOne = TRUE; DWORD
iIndex = 0;
BYTE bAction = ACL_ACTION_PASS; //下面的代码表示:
//没有匹配的控管规则:执行询问
//有完全匹配的控管规则:按照控管规则的控管动作返回 //没有完全匹配和控管规则但是有与进程匹配的控管规则: //按最后一条与进程匹配的控管规则的管制动作取反【19】 COMPARE:
if(!IsOne) iIndex ++;
iIndex = FindAcl(m_sProcessName, iIndex); if(iIndex >= m_AclFile.mAclHeader.ulAclCount) {
if(IsOne) {
if(m_bIsWin9x)
}
}
{ }
if(!QueryAccess())
return XF_DENY;
else
return XF_PASS;
else
return XF_QUERY;
else { }
if(bAction == ACL_ACTION_DENY)
return XF_PASS;
else
return XF_DENY;
if(IsOne) IsOne = FALSE;
bAction = m_AclFile.mpAcl[iIndex].bAction;
if(m_AclFile.mpAcl[iIndex].bDirection!=ACL_DIRECTION_IN_
OUT&&mSession->bDirection!=m_AclFile.mpAcl[iIndex].bDirection)
goto COMPARE;
if(m_AclFile.mpAcl[iIndex].bServiceType!=ACL_SERVICE_TYP
E_ALL&&mSession->bProtocol!=m_AclFile.mpAcl[iIndex].bServiceType)
goto COMPARE;
if(m_AclFile.mpAcl[iIndex].bRemoteNetType!=ACL_NET_TYPE
_ALL&&FindIP(mSession->ulRemoteIP)!=m_AclFile.mpAcl[iIndex].
bRemoteNetType)
goto COMPARE;
if(m_AclFile.mpAcl[iIndex].uiServicePort!=ACL_SERVICE_POR
T_ALL&&mSession->uiPort!=m_AclFile.mpAcl[iIndex].uiServicePort) }
FindAcl:根据应用程序和名称从控管规则中查找与之相匹配的记录。 FindIP:从实际连接的目的IP计算出自定义的IP类型【20】 4.2.4 设置函数
(1)SetWorkMode设置DLL的工作模式 (2)GetWorkMode得到DLL当前的工作模式 (3)SetAcl更新DLL的控管规则数据
goto COMPARE;
if(m_AclFile.mpAcl[iIndex].bAction == ACL_ACTION_DENY)
return XF_DENY;
return XF_PASS;
5 系统测试
5.1测试方法概述
目前软件测试主要采用两种方法,一种是黑盒测试,另一种是白盒测试。
黑盒测试,英文是Black Box Testing,又称功能测试或者数据驱动测试。黑盒测试是根据软件的规格对软件进行的测试,这类测试不考虑软件内部的运作原理,因此软件对用户来说就像一个黑盒子。 软件测试人员以用户的角度,通过各种输入和观察软件的各种输出结果来发现软件存在的缺陷,而不关心程序具体如何实现的一种软件测试方法。
白盒测试,英文是White Box Testing。又称结构测试或者逻辑驱动测试。白盒测试是把测试对象看作一个打开的盒子。利用白盒测试法进行动态测试时,需要测试软件产品的内部结构和处理过程,不需测试软件产品的功能。白盒测试是知道产品内部工作过程,可通过测试来检测产品内部动作是否按照规格说明书的规定正常进行,按照程序内部的结构测试程序,检验程序中的每条通路是否都有能按预定要求正确工作,而不顾它的功能,白盒测试的主要方法有逻辑驱动、基路测试等,主要用于软件验证。
由于测试工具及环境等因素限制,本课题多采用黑盒测试。 5.2 测试用例及测试结果 测试一:
(1) 操作系统: Win2000。
(2) 操作步骤:启动EXE→进入控管规则对话框→修改应用程序设置→单击“取消”按钮→提示保存时选择不保存→重新进入控管规则对话框查看结果。
(3) 测试结果:控管规则对话框上仍然保留着修改后的值,而没有恢复到修改前的状态。
(4) 原因:在选择修改时,虽然没有保存到控管规则文件里,但是没有对界面做恢复操作。而且在取消操作时没有必要再通知DLL改变控管规则。
(5) 解决办法:首先去掉通知DLL的代码。然后加入对话框恢复操作的代
码,如下所示。
void CMainSheet::OnCancel()
{
if(!GetDlgItem(ID_APPLY_NOW)->IsWindowEnabled()) return; MB_YESNO) if(AfxMessageBox(GUI_ACL_MESSAGE_ACL_ASK_SAVE,
== IDYES)
}
测试二:
(1) 操作系统: WinXP。
(2) 操作步骤:启动EXE→启动IE→询问是否通过→确定通过→编辑控管
规则。
(3) 测试结果:没有显示要编辑控管规则。
(4) 原因:界面是否为询问的变量CAcl::m_EnableComboApplication没有
恢复为TRUE。 { } GetDlgItem(ID_APPLY_NOW)->EnableWindow(FALSE); if(m_AclFile.ReadAcl() != XERR_SUCCESS) { } CAcl *dlgAcl = (CAcl*)this->GetPage(2); dlgAcl->Refresh(); AfxMessageBox(GUI_ACL_MESSAGE_ACL_READ_ERROR); return; OnApply(); return;
(5) 解决办法:在“Edit”按钮的事件中,在弹出AclSet之前加入一行代码,
如下所示。
void CAcl::OnAclButtonEdit()
{
… …
CAclSet::m_tmpAcl = m_AclFile.mpAcl[m_iListIndex];
CAclSet::m_EnableComboApplication = TRUE;
int iRet = ShowDlg();
… …
}
测试三:
(1) 操作系统: WinXP。
(2) 操作步骤:启动EXE→设置控管应用程序(以迅雷为例,拒绝所有)→
运行迅雷查看运行结果。
(3) 测试结果:迅雷不能使用,证明结果成功。(结果见5.1—5.5)
图5.1 设置应用程序(迅雷)控管规则为拒绝所有
图5.2 设置控管规则后结果显示
图5.3 询问是否放行操作
图5.4 封包监视信息
图5.5 应用程序运行结果
6 结束语
6.1总结
通过本次课题的研究,使我对网络安全方面的知识有了更深层次的了解。同时在王静老师的指导下,也使我对C++这门语言有了一定的认知与定位。相信这对于我以后的工作将会大有裨益。
这次课题成功的实现了一个简单的个人防火墙的基本功能,使其可以根据应用程序访问规则可对应用程序连网动作进行过滤;并且对应用程序访问规则具有一定自学习功能;同时实现了实时监控、监视网络活动。虽然界面和功能方面可能并不是那么强大,但是基本可以满足个人计算机在防火墙端的基本需求。
6.2展望
当今防火墙的种类现在非常多。用到截获数据包的技术也是数不胜数。包括WinCapp抓包、NDIS中间层抓包。本次我利用的是Winsock截获底层服务提供者函数来实现我的设计。在以后的日子里我希望可以尝试用其他方式来实现本课题,丰富自己的知识种类。
通过对其他商用防火墙的了解,我们可以知道,单纯的防火墙软件的功能是有限的。只有将防火墙软件和让病毒软件整合起来才能更好的实现“安全”的意义。所以在未来我希望能够将防病毒软件整合在其中。同时更加丰富软件的功能,使其功能和界面更加人性化。
参考文献
[1] Davis Chapman(美国).学用vc++6.0[M].北京:清华大学出版社,1999
[2] 朱雁辉.Windows防火墙与网络封包截获技术[M].北京:电子工业出版
社,2002
[3] 郑莉,董渊.C++语言程序设计[M].北京:清华大学出版社,2001
[4] 黎连业,张维,向东明.防火墙及其应用技术[M].北京:清华大学出版社,2004
[5] 孙鑫等.vc++深入详解[M].北京:电子工业出版社,2006
[6] 龚波.MFC技术内幕[M].北京:机械工业出版社,1999
[7] 阎慧等.防火墙原理与技术[M].北京:机械工业出版社,2004,11
[8] Bruce Eckel. Thinking in Java, Third Edition[M]. Prentice Hall PTR .2003,8
[9] 彭珺,高珺. 计算机网络信息安全及防护策略研究[J]. 计算机与数字工
程.2011,(01)
[10] 朱冲 等. 基于内核2.6的Linux包过滤型防火墙的设计与实现[J]. 计算机
系统应用. 2008,(10)
[11] 吴玉,娄智. 基于操作系统内核的包过滤防火墙系统的设计与实现[J]. 湖南
工程学院学报. 2006,(02)
[12] (美)William Stallings著. 王海欣,陈弘毅 译.网络安全基础:应用与标准(第3
版) [M]. 北京:清华大学出版社, 2007
[13] 李峰,陈向益. TCP/IP协议分析与应用编程[M]. 北京:人民邮电出版社.
2008,11
[14]Andrew S. Tanenbaum 等著. Computer Networks, Fourth Edition(英文影印版)
[M]. 北京:清华大学出版社. 2004, 10
[15]吴功勋,董大凡,王珺,刘乾 编著.计算机网络高级软件编程技术[M]. 北京:
清华大学出版社.2008
[16] 丁展,刘海英等. VC++网络通信编程实用案例精选. 北京: 人民邮电出版
社,2001
[17] 殷肖川,刘志宏,姬伟峰,万映辉. 李增智,唐亚哲主审. 网络编程与开发
技术.西安: 西安交通大学出版社,2004
[18] Greg Holden(美). 王斌,孔璐译. 防火墙与网络安全-入侵检查和VPNS.
北京:清华大学出版社,2003
[19] 马安鹏. VC++ 6.0程序设计导学. 北京: 清华大学出版社,2002
[20] 朱雁辉,朱雁冰. Windows防火墙与网络封包截获技术.北京:电子工业出版
社,2002
[21] 黄维通,姚瑞霞. VC++6.0程序设计教程. 北京:机械工业出版社,2004
致 谢
本文是在王静老师的热情关心和指导下完成的,他渊博的知识和严谨的治学作风使我受益匪浅,在防火墙技术分析和设计、网络编程技术、网络数据包分析等方面得到了指导老师的很大帮助,对顺利完成本课题起到了极大的作用。在此向他表示我最衷心的感谢!
同时也感谢李龙同学在课题研究初期给予了帮助,有了一个很好的开端!也感谢周国震同学在写论文背景的时候给我的提示。使我的论文有了良好的开头,为顺利完成论文起到了很好的帮助。
转眼间大学四年的生活即将结束,我们在这里所学习的知识和经验在这次课题中得以体现,而在这个过程中我们所得到的也将影响我们一生。我希望我可以永远保持一颗求知的心去工作,去生活。感谢我的大学,感谢我生命中的所有人。
最后向在百忙之中评审本文的各位专家、老师表示衷心的感谢!
作者简介:
姓 名: 王佳亮 性别: 男
出生年月:1987年11月21日 民族: 汉 E-mail:[email protected]