Windows防火墙设计实验报告

时间:2024.4.20

网络安全大型作业

(Windows防火墙设计)

实验报告

班级:08计算机网络

姓名:

学号:V2008410

日期:20##-3-3


一、实验目的和要求

1、学习Windows下防火墙设计技术

2、实现一个简单的Windows下的防火墙软件

3、分析simpleFW软件不足之处

4、根据要求理解两个SPI程序,并自己进行扩展,增加新的功能

二、实验原理

1.Windows的Hook技术:Hook分为Hook消息和Hook函数调用

Hook函数调用是指截获特定进程或者系统对某个API函数的调用,使得API的执行流程转向特定的代码,后者称为注入代码,注入代码一般保存在注入DLL中。

2.Windows报文截获技术:原始套结字(Raw Socket)和替换系统自带的WINSOCK动态连接库

3.Windows SPI原理:Winsock2.0引入的一个功能就是允许开发者可以编写自己的服务提供者接口程序,即SPI程序。SPI以DLL方式存在,工作在应用层,为上层程序提供结构函数。

4.SimpleFW基本技术:Windows程序设计中几乎所有的动作都是利用消息来触发。但是消息是和窗口绑定在一起的,一般拥有窗口才能接收消息。在特殊情况下,线程也可以接收消息在SimpleFW中,当一个程序访问Winsock会弹出对话框,让用户选择是否允许访问。这个过程通过IP_Moniter.dll发送给UI一个用户自定义消息来实现。

三、实验环境和采用的工具

1、操作系统为Windows XP

2、编程工具为VC++ 6.0

四、简要分析实验原型软件(SimpleFW)的不足

1.原型软件不能记录访问规则,每次打开防火墙都需要用户重新设定,这样带来了很大的不便

2.原型软件不能灵活的对访问规则进行修改删除,这样一旦制定下来的规则都不能发生变化

3.原型软件没有自定义规则的功能,这样对于每一个应用程序第一次访问网络都需要进行询问,这样对用户使用来说比较不方便

4.原型软件没有基本的日志功能

5.原型软件不能对应用程序进行监控甚至是进行关键字匹配告警,只能进行简单的访问控制

6.原型软件只是简单的串行化,不能同时有多个应用程序访问

7.原型软件外观比较简陋,需要进一步修饰

8、原型软件没有流量监控功能,用户不知流量使用情况

9、原型软件缺少清理无用规则的功能

10、原型软件缺少修补系统漏洞的功能

五、在实验原型软件上新增的功能

5.1功能1

流量监控

5.1.1功能1描述

该功能可以实时监控用户当前使用的流量以及到目前为止用户设置时间内所使用的总流量

5.1.2功能1实现流程

#include "stdafx.h"

#include "MFNetTraffic.h"

#include "float.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

#include "winperf.h"

// Construction/Destruction

MFNetTraffic::MFNetTraffic()

{

       lasttraffic = 0.0;

       CurrentInterface = -1;

       CurrentTrafficType = AllTraffic;

       GetInterfaces();

}

MFNetTraffic::~MFNetTraffic()

{

      

}

PERF_OBJECT_TYPE *FirstObject(PERF_DATA_BLOCK *dataBlock)

{

  return (PERF_OBJECT_TYPE *) ((BYTE *)dataBlock + dataBlock->HeaderLength);

}

PERF_OBJECT_TYPE *NextObject(PERF_OBJECT_TYPE *act)

{

  return (PERF_OBJECT_TYPE *) ((BYTE *)act + act->TotalByteLength);

}

PERF_COUNTER_DEFINITION *FirstCounter(PERF_OBJECT_TYPE *perfObject)

{

  return (PERF_COUNTER_DEFINITION *) ((BYTE *) perfObject + perfObject->HeaderLength);

}

PERF_COUNTER_DEFINITION *NextCounter(PERF_COUNTER_DEFINITION *perfCounter)

{

  return (PERF_COUNTER_DEFINITION *) ((BYTE *) perfCounter + perfCounter->ByteLength);

}

PERF_COUNTER_BLOCK *GetCounterBlock(PERF_INSTANCE_DEFINITION *pInstance)

{

  return (PERF_COUNTER_BLOCK *) ((BYTE *)pInstance + pInstance->ByteLength);

}

PERF_INSTANCE_DEFINITION *FirstInstance (PERF_OBJECT_TYPE *pObject)

{

  return (PERF_INSTANCE_DEFINITION *)  ((BYTE *) pObject + pObject->DefinitionLength);

}

PERF_INSTANCE_DEFINITION *NextInstance (PERF_INSTANCE_DEFINITION *pInstance)

{

  PERF_COUNTER_BLOCK  *pCtrBlk = GetCounterBlock(pInstance);

  return (PERF_INSTANCE_DEFINITION *) ((BYTE *)pInstance + pInstance->ByteLength + pCtrBlk->ByteLength);

}

char *WideToMulti(wchar_t *source, char *dest, int size)

{

  WideCharToMultiByte(CP_ACP, 0, source, -1, dest, size, 0, 0);

  return dest;

}

/*

Window NT/2000: When calling the RegQueryValueEx function with hKey set to the

HKEY_PERFORMANCE_DATA handle and a value string of a specified object, the

returned data structure sometimes has unrequested objects. Don't be surprised;

this is normal behavior. When calling the RegQueryValueEx function, you should

always expect to walk the returned data structure to look for the requested object.

*/

//得到接口号为interfaceNumber的接口流量

double MFNetTraffic::GetTraffic(int interfaceNumber)

{

       try

       {

#define DEFAULT_BUFFER_SIZE 40960L

             

              POSITION pos;

              CString InterfaceName;

              pos = Interfaces.FindIndex(interfaceNumber);

              if(pos==NULL)

                     return 0.0;

              //得到当前的接口名字

              InterfaceName = Interfaces.GetAt(pos);

             

              //为性能数据缓冲

              unsigned char *data = new unsigned char [DEFAULT_BUFFER_SIZE];

              // 从RegQueryValueEx返回的值:本例中忽略改变量

              DWORD type;

              // 缓冲的尺寸

              DWORD size = DEFAULT_BUFFER_SIZE;

              // RegQueryValueEx返回的值

              DWORD ret;

             

              // 从网络对象(索引是510)查询性能数据

              /*

              HKEY_PERFORMANCE_DATA:

              Windows NT/2000/XP: Registry entries subordinate to this key allow you to

              access performance data. The data is not actually stored in the registry;

              the registry functions cause the system to collect the data from its source.

              */

              /*

              */

              while((ret = RegQueryValueEx(

                     HKEY_PERFORMANCE_DATA, "510", NULL, &type, data, &size)) != ERROR_SUCCESS)

              {

                     if(ret == ERROR_MORE_DATA)

                     {

                            // 缓冲尺寸太小,增加内存分配

                            size += DEFAULT_BUFFER_SIZE;        

                            delete [] data;

                            data = new unsigned char [size];

                     }

                     else

                     {

                            // 未定义的错误

                            return 1;

                     }

              }

              //性能数据块

              PERF_DATA_BLOCK *dataBlockPtr = (PERF_DATA_BLOCK *)data;

             

              //枚举链表中第一个对象

              PERF_OBJECT_TYPE *objectPtr = FirstObject(dataBlockPtr);

             

              //遍历链表

              for(int a=0 ; a<(int)dataBlockPtr->NumObjectTypes ; a++)

              {

                     char nameBuffer[255];

             

                     // 判断是否是网络对象索引号是510

                     if(objectPtr->ObjectNameTitleIndex == 510)

                     {

                            // 偏移变量

                            DWORD processIdOffset = ULONG_MAX;

                            // 找到第一个计数器

                            PERF_COUNTER_DEFINITION *counterPtr = FirstCounter(objectPtr);

                            // 遍历链表

                            for(int b=0 ; b<(int)objectPtr->NumCounters ; b++)

                            {

                                   // 判断接收的数据类型是否是我们需要的

                                   if((int)counterPtr->CounterNameTitleIndex == CurrentTrafficType)

                                          processIdOffset = counterPtr->CounterOffset;

                    

                                   // 下一个计数器

                                   counterPtr = NextCounter(counterPtr);

                            }

                            //数据类型不是我们需要的

                            if(processIdOffset == ULONG_MAX) {

                                   delete [] data;

                                   return 1;

                            }

                           

                            // 找到第一个实列(instance)

                            PERF_INSTANCE_DEFINITION *instancePtr = FirstInstance(objectPtr);

                           

                            DWORD fullTraffic;

                            DWORD traffic;

                            //遍历整个实列

                            for(b=0 ; b<objectPtr->NumInstances ; b++)

                            {

                                   wchar_t *namePtr = (wchar_t *) ((BYTE *)instancePtr + instancePtr->NameOffset);           

                                   // 得到这个实列的PERF_COUNTER_BLOCK

                                   PERF_COUNTER_BLOCK *counterBlockPtr = GetCounterBlock(instancePtr);

                                  

                                   // 现在我们得到了接口的名字

                                   char *pName = WideToMulti(namePtr, nameBuffer, sizeof(nameBuffer));

                                   CString iName;

                                   iName.Format("%s",pName);

                           

                                   POSITION pos = TotalTraffics.FindIndex(b);

                                   if(pos!=NULL)

                                   {

                                          fullTraffic = *((DWORD *) ((BYTE *)counterBlockPtr + processIdOffset));

                                          TotalTraffics.SetAt(pos,fullTraffic);

                                   }

                                   // 如果当前的接口就是我们选择的接口

                                   if(InterfaceName == iName)

                                   {

                                          traffic = *((DWORD *) ((BYTE *)counterBlockPtr + processIdOffset));

                                          double acttraffic = (double)traffic;

                                          double trafficdelta;

                                          // 判断处理的接口是否是新的

                                          if(CurrentInterface != interfaceNumber)

                                          {

                                                 lasttraffic = acttraffic;

                                                 trafficdelta = 0.0;

                                                 CurrentInterface = interfaceNumber;

                                          }

                                          else

                                          {

                                                 trafficdelta = acttraffic - lasttraffic;

                                                 lasttraffic = acttraffic;

                                          }

                                          delete [] data;

                                          return(trafficdelta);

                                   }

                                  

                                   //下一个实列

                                   instancePtr = NextInstance(instancePtr);

                            }

                     }

                    

                     // 下一个对象

                     objectPtr = NextObject(objectPtr);

              }

             

              delete [] data;

              return 0;

       }

       catch(...)

       {

              return 0;

       }

}

//枚举安装的接口

BOOL MFNetTraffic::GetInterfaces()

{

       try

       {

#define DEFAULT_BUFFER_SIZE 40960L

             

              Interfaces.RemoveAll();

              unsigned char *data = (unsigned char*)malloc(DEFAULT_BUFFER_SIZE);

              DWORD type;

              DWORD size = DEFAULT_BUFFER_SIZE;

              DWORD ret;

             

              char s_key[4096];

              sprintf( s_key , "%d" , 510 );

              //RegQueryValueEx的固定调用格式             

              while((ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, s_key, 0, &type, data, &size)) != ERROR_SUCCESS) {

                     while(ret == ERROR_MORE_DATA)

                     {

                            size += DEFAULT_BUFFER_SIZE;

                            data = (unsigned char*) realloc(data, size);

                     }

                     if(ret != ERROR_SUCCESS)

                     {

                            return FALSE;

                     }

              }

              //得到数据块        

              PERF_DATA_BLOCK *dataBlockPtr = (PERF_DATA_BLOCK *)data;

              //得到第一个对象

              PERF_OBJECT_TYPE *objectPtr = FirstObject(dataBlockPtr);

             

              for(int a=0 ; a<(int)dataBlockPtr->NumObjectTypes ; a++)

              {

                     char nameBuffer[255];

                     if(objectPtr->ObjectNameTitleIndex == 510)

                     {

                            DWORD processIdOffset = ULONG_MAX;

                            PERF_COUNTER_DEFINITION *counterPtr = FirstCounter(objectPtr);

                           

                            for(int b=0 ; b<(int)objectPtr->NumCounters ; b++)

                            {

                                   if(counterPtr->CounterNameTitleIndex == 520)

                                          processIdOffset = counterPtr->CounterOffset;

                                  

                                   counterPtr = NextCounter(counterPtr);

                            }

                           

                            if(processIdOffset == ULONG_MAX) {

                                   free(data);

                                   return 1;

                            }

                           

                            PERF_INSTANCE_DEFINITION *instancePtr = FirstInstance(objectPtr);

                           

                            for(b=0 ; b<objectPtr->NumInstances ; b++)

                            {

                                   wchar_t *namePtr = (wchar_t *) ((BYTE *)instancePtr + instancePtr->NameOffset);

                                   PERF_COUNTER_BLOCK *counterBlockPtr = GetCounterBlock(instancePtr);

                                   char *pName = WideToMulti(namePtr, nameBuffer, sizeof(nameBuffer));

                                   DWORD bandwith = *((DWORD *) ((BYTE *)counterBlockPtr + processIdOffset));                          

                                   DWORD tottraff = 0;

                                   Interfaces.AddTail(CString(pName));

                                   Bandwidths.AddTail(bandwith);

                                   TotalTraffics.AddTail(tottraff);  // initial 0, just for creating the list

                                  

                                   instancePtr = NextInstance(instancePtr);

                            }

                     }

                     objectPtr = NextObject(objectPtr);

              }

              free(data);

             

              return TRUE;

       }

       catch(...)

       {

              return FALSE;

       }

}

//返回安装的接口数

int MFNetTraffic::GetNetworkInterfacesCount()

{

       return Interfaces.GetCount()-1;

}

//返回接口名称

BOOL MFNetTraffic::GetNetworkInterfaceName(CString *InterfaceName, int index)

{

       POSITION pos = Interfaces.FindIndex(index);

       if(pos==NULL)

              return FALSE;

       InterfaceName->Format("%s",Interfaces.GetAt(pos));

       return TRUE;

}

//返回接口带宽

DWORD MFNetTraffic::GetInterfaceBandwidth(int index)

{

       POSITION pos = Bandwidths.FindIndex(index);

       if(pos==NULL)

              return 0;

       else

              return Bandwidths.GetAt(pos) / 8;

}

//具体接口接收和发送的数据量

DWORD MFNetTraffic::GetInterfaceTotalTraffic(int index)

{

       DWORD        totaltraffic = 0;

       POSITION    pos;

       pos= TotalTraffics.FindIndex(index);

       if(pos!=NULL)

       {

              totaltraffic = TotalTraffics.GetAt(pos);

              if(totaltraffic == 0.0)

              {

                     GetTraffic(index);

                     pos= TotalTraffics.FindIndex(index);

                     if(pos!=NULL)

                     {

                            totaltraffic = TotalTraffics.GetAt(pos);

                     }

              }

       }

       return(totaltraffic);

}

void MFNetTraffic::SetTrafficType(int trafficType)

{

       CurrentTrafficType = trafficType;

}

5.1.3功能1测试中遇到问题

在测试的过程中遇到的主要问题是源代码运行时出现的错误。

5.2功能2

防火墙规则设置功能

5.2.1功能2描述

防火墙规则设置功能可以对访问添加、修改或者删除自定义规则设置,亦可以对规则编号顺序进行移动,有股则名称、拦截设置和记录设置

5.2.2功能2实现

5.2.3功能2测试中遇到问题

在此次测试中遇到的问题有:一、局域网内共享的防火墙设置,对自定义IP规则不是很熟悉;二、设置规则开放WEB服务时遇到些许小问题;三、设置规则开放FTP服务的步骤 ;四、关闭或开放特定端口 ;五、设置规则屏蔽或开放IP 对进入防火墙自定义IP规则,增加规则时碰到问题

更多相关推荐:
防火墙技术实验报告

网络攻防对抗实验报告实验名称防火墙技术实验八指导教师专业班级姓名学号电子邮件实验地点实验日期实验成绩一实验目的防火墙是网络安全的第一道防线按防火墙的应用部署位置分类可以分为边界防火墙个人防火墙和分布式防火墙三类...

个人防火墙的应用和配置实验报告

个人防火墙的应用和配置1实验题目简述11题目描述个人防火墙是防止电脑中的信息被外部侵袭的一项技术在系统中监控阻止任何未经授权允许的数据进入或发出到互联网及其他网络系统个人防火墙产品如著名Symantec公司的诺...

防火墙实验报告

南京信息工程大学实验实习报告实验实习名称防火墙实验实习日期20xx1012指导教师朱节中专业10软件工程年级三班次2班姓名曾艺学号20xx2344070得分一实验目的1了解防火墙的相关知识2防火墙的简单实验二实...

防火墙实验报告20xx版

防火墙实验报告1防火墙实验需求描述11实验拓扑12地址描述测试机IP1921681224网关19216811交换机VLAN101921681124F10471011224防火墙E11011124E3111124...

防火墙实验报告

路由器模拟防火墙实验一实验要求与目的路由器实现包过滤防火墙功能了解和熟悉防火墙包过滤功能体现包过滤功能在网络安全的作用了解防火墙在网络安全中的重要性二实验内容实验原理图1了解路由器模拟防火墙具体配置过程2了解路...

创建防火墙实验报告

创建防火墙实验报告班级10网工三班学生姓名谢昊天学号1215134046实验目的和要求1了解防火墙的基本概念2掌握如何使用规则集实现防火墙实验内容与分析设计1WinRoute目前应用比较广泛既可以作为一个服务器...

防火墙实验报告 2

计算机安全实验报告实验题目天网防火墙windows安全设置专业班级计科一班学号姓名李冲指导教师一天网防火墙技术1实验题目简述个人防火墙是防止电脑中的信息被外部侵袭的一项技术在系统中监控阻止任何未经授权允许的数据...

实验7:防火墙配置与NAT配置(标准完成版)

大连理工大学本科实验报告课程名称网络综合实验学院系专业班级1006学号学生姓名赵旭凯20xx年5月23日大连理工大学实验报告学院系软件学院专业软件工程班级1006姓名赵旭凯学号20xx92356组13实验时间2...

入侵检测 VPN 防火墙 实验报告

入侵检测课程设计报告班级学号姓名20xx年6月6日前言随着网络的逐步普及企业内部网络的建设是企业向信息化发展的必然选择企业的网络系统是一个非常庞大而复杂的系统它不仅为现代化发展综合信息管理和办公自动化等一系列应...

《防火墙技术》实验报告参考

实验报告院系:信息学院课程名称:防火墙技术日期:9-5备注:本实验报告用于各学科与计算机应用相关课程的实验,务必按时完成。不交此报告者,本次实验为不合格。实验报告院系:信息学院课程名称:防火墙技术日期:9-19…

防火墙实验报告

实验十六防火墙实验一实验目的学习配置访问控制列表设计防火墙二实验原理1防火墙原理网络的主要功能是向其他通信实体提供信息传输服务网络安全技术的主要目的是为传输服务实施的全过程提供安全保障在网络安全技术中防火墙技术...

实验7:防火墙配置与NAT配置最新完整版

大连理工大学本科实验报告课程名称网络综合实验学院系软件学院专业20xx年3月30日大连理工大学实验报告实验七防火墙配置与NAT配置一实验目的学习在路由器上配置包过滤防火墙和网络地址转换NAT二实验原理和内容1路...

防火墙实验报告(27篇)