、  一、实验目的(1)  修改代码,完成下述功能:a) 由本机登录ftp服务器成功(通过用户名、密码验证);b) 无法将ftp内容列表或上传、下载数据;(2) 作业要求:a) 明确提出自己的方案设计,即通过何原理实现上述功能;b) 纸版作业只需要粘贴自己撰写的代码部分;c) 实验结果需要截图证明;二、实验过程1, 学习FTP应用的相关知识FTP(File Transfer Protocal),是文件传输协议的简称。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。用户可以通过它把自己的PC机与世界各地所有运行FTP协议的服务器相连,访问服务器上的大量程序和信息。TCP/IP协议中,FTP标准命令TCP端口号为21,Port方式数据端口为20。FTP协议的任务是从一台计算机将文件传送到另一台计算机,它与这两台计算机所处的位置、联接的方式、甚至是是否使用相同的操作系统无关。假设两台计算机通过ftp协议对话,并且能访问Internet, 你可以用ftp命令来传输文件。每种操作系统使用上有某一些细微差别,但是每种协议基本的命令结构是相同的。FTP支持两种模式,一种方式叫做Standard (也就是 PORT方式,主动方式),一种是 Passive (也就是PASV,被动方式)。 Standard模式 FTP的客户端发送 PORT 命令到FTP服务器。Passive模式FTP的客户端发送 PASV命令到 FTP Server。   下面介绍一个这两种方式的工作原理:   Port模式FTP 客户端首先和FTP服务器的TCP 21端口建立连接,通过这个通道发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。 PORT命令包含了客户端用什么端口接收数据。在传送数据的时候,服务器端通过自己的TCP 20端口连接至客户端的指定端口发送数据。 FTP server必须和客户端建立一个新的连接用来传送数据。   Passive模式在建立控制通道的时候和Standard模式类似,但建立连接后发送的不是Port命令,而是Pasv命令。FTP服务器收到Pasv命令后,随机打开一个高端端口(端口号大于1024)并且通知客户端在这个端口上传送数据的请求,客户端连接FTP服务器此端口,然后FTP服务器将通过这个端口进行数据的传送,这个时候FTP server不再需要建立一个新的和客户端之间的连接。2, 熟悉老师给的防火墙代码熟悉fwfilter.h和pfwapi.h了解简单防火墙的工作方式,和使用方法,熟悉掌握通过各种方法过滤端口的方法。在所给的程序中,主要是添加端口,这里所过滤的端口是远程服务器的的端口,凡是用该端口试图与本机连接都会拒绝。其中端口设置有:任意模式,单一模式,列表模式,范围模式。3, 利用套接字抓包,分析包内容利用已经学过的socket抓包方法,检测本机网卡,试图在所有包中找到需要的内容,获取相关信息。 4,  整合代码,完成实验要求 将两个程序整合,完成实验要求。 方案设计1, FTP分析Ftp工作在应用层,控制命令和数据都是通过TCP协议打包发送的,利用两个TCP链接来完成,一个是控制连接,另一个是数据链接。控制链接主要负责协议命令和服务器响应码的传输,通常是21端口。控制连接一旦建立就一直存在,直到一方关闭通信。数据连接只负责数据的传输,包括文件的上传和下载,以及列表的刷新。数据连接不是一直保持的,当数据传输完毕时会自动断开。PASV命令,这个命令请求服务器监听某个数据端口,并等待一个客户的连接,这条命令的相应包括主机地址和服务器正在收听的端口地址。利用flashx的FTP软件在连接时可以看到登录信息: [17:46:15] [右] PASV[17:46:15] [右] 227 Entering Passive Mode (59,64,159,3,12,27)由此可以看出PASV的命令响应号是227,括号是服务器的ip和端口,其中端口由倒数第2位乘以256加上最后一位,上面的例子就是:12×256+27= 3099。2, Socket抓包套接字已经是学过的知识了,所以这里不再赘述,在分析包时,只需要匹配数据块的前三位是不是227就可以得到pasv命令的响应数据。再利用一点简单的算法就可以得到最后的端口号。3, 防火墙实现为了实现实验要求,一方面我们需要封闭20端口,也就是FTP服务端默认使用的端口,另一方面我们将上面获得的端口号也添加进去,这样就可以封掉PASV命令的端口了。三、实验结果  测试软件为DOS和FTPflashxp 1,先用flsahxp登录FTP,其方式默认为PASV    2,运行防火墙 3,再次登录ftp 软件自己在尝试3次PASV无法连接后会自动转到PORT模式,由于之前已经过滤了20端口,所以port模式也是无法连接的。由登录状态可以看到,用户名和密码是通过的。4,刷新列表和下载数据的测试,先登录到ftp打开防火墙 刷新列表 可以看到,已经无法再得到列表了。 DOS下测试正常登录的效果 打开防火墙后登录 四、关键代码重新定义的TCP结构体typedef struct TCP{    u_short SrcPort;    u_short DstPort;    u_long SeqNum;    u_long AckNum;    u_char DataOff; u_char Flag;    u_short Window;    u_short Chksum;    u_short UrgPtr; //Devil----------------用于接收TCP包中数据的字符串-------------Diy// char num[4];//用于接收FTP命令响应号 char a[45];//接收包内容}TCP,*PTCP;防火墙端口设置  Rule.RemotePort.Type = FILTER_PORT_TYPE_LIST;  Rule.RemotePort.PortList.TotalNumber = 2;  Rule.RemotePort.PortList.Ports[0]= htons(20);  Rule.RemotePort.PortList.Ports[1]=htons(port); 解析TCP包void DecodeTCP(char *pData){ TCP *pTCPHdr = (TCP*)pData; int i=44,j=1; int port1=0,port2=0; pTCPHdr->num[3]='/0'; pTCPHdr->a[44]='/0'; if(pTCPHdr->SrcPort==ntohs(21)&&(strcmp(pTCPHdr->num,"227")==0)) {  //printf("Port:%d->%d/n",ntohs(pTCPHdr->SrcPort),ntohs(pTCPHdr->DstPort));    printf("%s/n",pTCPHdr->a);  //获得端口号的算法   while(pTCPHdr->a[i]!=')')//到最后一个括号处    i--;   i--;   while(pTCPHdr->a[i]!=',')   {//获得第一个端口信息    port1 =  (pTCPHdr->a[i]-48)*j+port1;    j = j*10;    i--;   }    i--;   j=1;   while(pTCPHdr->a[i]!=',')   {//获得第二个端口信息    port2 =  (pTCPHdr->a[i]-48)*j+port2;    j = j*10;    i--;   }   //计算端口   port = port2*256+port1;   printf("%d/n",port); }}五、问题及解决途径问题1:解析pasv命令的响应包在实验过程中,利用sniffer抓包工具认真的对整个FTP登录过程进行研究后得到了227号响应包就是PASV的特征,利用这一点和字符串匹配的方法得到了port端口。问题2:现在的大多数FTP软件都使用的PASV模式,只有当它多次尝试PASV无法连接时才使用PORT模式所以,我们还需要封掉20端口来完成整个FTP的过滤。问题3:有时候会出现本机连本机的端口 Pasv传过来的端口号是3579,虽然封掉了这个端口,但是当上述情况出线时,会获得列表。六、实验心得 1,了解了许多相关防火墙的基础知识,对防火墙的基本原理有了更深的理解和认识,学会了利用简单的程序实现防火墙的基本功能。 2,了解了FTP应用层协议的知识,对FTP的工作原理,工作方式有了更深的映像,同时加深了对计算机网络的了解,有一次学习了伟大的TCP/IP协议栈。 3,复习了以前学过的原始套接字的使用方法。 4,由于程序编写主要是用C语言的方法去写,导致程序有点乱,而且许多算法都是凑出来的,仅仅为了实现这次实验,并不能兼容到更好的软件当中,相信如果以后有时间尽量规范的写代码。这样不但可以养成良好的编程习惯,对于别人和自己来阅读代码也有很大方便。 5,一开始想用范围封掉20和1024以后的端口,后来觉得会影响其他软件的正常运行,再说防火墙也不是封端口的软件,而是保护机器的软件。于是就只封的两个端口,其中有一个是动态变化的。源程序:test.cpp // test.cpp : Defines the entry point for the console application.///*Author:DevilDiyDate:2008-05-25School:Information Engineering 信息工程学院Dept:Information Security  信息安全专业Class:05611      05611班Number:052054-19    052054-19Name:DingYu      丁于Summary:      a) 由本机登录ftp服务器成功(通过用户名、密码验证);        b) 无法将ftp内容列表或上传、下载数据; */#include <WinSock2.h>#include <stdio.h>#include "pfwapi.h"//包含了fwfilter中各接口函数的声明#pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"fwfilter.lib") #define SIO_RCVALL            _WSAIOW(IOC_VENDOR,1) typedef struct IP{    u_char  ver_ihl;        // 版本 (4 bits) + 首部长度 (4 bits)    u_char  tos;            // 服务类型(Type of service)     u_short tlen;           // 总长(Total length)     u_short identification; // 标识(Identification)    u_short flags_fo;       // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)    u_char  ttl;            // 存活时间(Time to live)    u_char  proto;          // 协议(Protocol)    u_short crc;            // 首部校验和(Header checksum) u_long  saddr;      // 源地址(Source address)    u_long  daddr;      // 目的地址(Destination address)    u_int   op_pad;         // 选项与填充(Option + Padding)}IP; typedef struct TCP{    u_short SrcPort;    u_short DstPort;    u_long SeqNum;    u_long AckNum;    u_char DataOff; u_char Flag;    u_short Window;    u_short Chksum;    u_short UrgPtr; //Devil----------------用于接收TCP包中数据的字符串-------------Diy// char num[4];//用于接收FTP命令响应号 char a[45];//接收包内容}TCP,*PTCP; #include "stdafx.h"void DecodeIP(char* pData);//解析IP包void DecodeTCP(char *pData);//解析TCP包 unsigned short port;//全局变量port最终的端口号 VOID Alert(ULONG RuleId, PPACKET_INFO PacketInfo){ if (RuleId == 0)//如果与用户设定规则的ID号相符 {  unsigned long SrcIP =  ntohl(PacketInfo->SrcAddress); //将网络字节形式的IP地址转换为主机形式  unsigned short SrcPort = ntohs(PacketInfo->SrcPort);  unsigned long DstIP =  ntohl(PacketInfo->DestAddress); //将网络字节形式的IP地址转换为主机形式  unsigned short DstPort = ntohs(PacketInfo->DestPort);  //将IP换算为十进制点分形式,在屏幕上打印信息  printf("主机%ld.%ld.%ld.%ld:%d连接本机%d端口!/n",    SrcIP>>24,(SrcIP>>16)%256,(SrcIP>>8)%256,SrcIP%256,SrcPort,DstPort); } }int main(int argc, char* argv[]){ //初始化SOCKET WSADATA wsaData; int iErrorCode = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iErrorCode != NO_ERROR)  printf("Error at WSAStartup()/n");  //创建套接字 SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (sRaw == INVALID_SOCKET)  {  printf("Error at socket(): %ld/n", WSAGetLastError());  WSACleanup();  return 0; }  //获取本机IP地址 char szHostName[56]; if(SOCKET_ERROR==gethostname((char*)szHostName,sizeof(szHostName)-1)) {  printf("无法获取主机名!/n");  return 0; }  hostent* pHost; if((pHost=gethostbyname((char*)szHostName))==NULL)  {  printf("无法获取主机信息!/n");  return 0; }  //绑定端口 SOCKADDR_IN addr_in; memcpy(&addr_in.sin_addr.S_un.S_addr,pHost->h_addr_list[0],pHost->h_length); addr_in.sin_family = AF_INET; addr_in.sin_port = htons(0); if(bind(sRaw,(PSOCKADDR)&addr_in,sizeof(addr_in))==SOCKET_ERROR) {  printf("监听端口绑定失败!/n");  return 0; }; printf("Bingding to interface: %s/n",::inet_ntoa(addr_in.sin_addr));  //设置RAW socket; DWORD OutBuf[10]; DWORD InBufSize = 1; DWORD RecvCount = 0; if(SOCKET_ERROR==WSAIoctl(sRaw,SIO_RCVALL,&InBufSize,sizeof(InBufSize),&OutBuf,sizeof(OutBuf),&RecvCount,NULL,NULL)) {  printf("设置socket失败!/n");  return 0; }  BOOL bRet;     FILTER_RULE Rule; //自定义规则        bRet = PFWInitialize(); //初始化fwfilter    if(!bRet)    {        printf("Initialize personal firewall failed./n");        return -1;    }  char buff[1024]; int nRet; while(1) {   nRet = recv(sRaw,buff,1024,0);  if(nRet>0)  //解析包   DecodeIP(buff);   PFWSetAlertCallback(Alert); //设置告警回调函数           // 设置规则:告警流向本机21端口的TCP协议数据流  Rule.RuleId = 0;  Rule.ActionFlag = FILTER_ACTION_DENY|FILTER_ACTION_ALERT;  Rule.RemoteAddress.Type = FILTER_ADDRESS_TYPE_ANY;  Rule.LocalPort.Type = FILTER_PORT_TYPE_ANY;  Rule.Protocol = FILTER_PROTO_TCP;  Rule.RemotePort.Type = FILTER_PORT_TYPE_LIST;  Rule.RemotePort.PortList.TotalNumber = 3;  Rule.RemotePort.PortList.Ports[0]=htons(20);  Rule.RemotePort.PortList.Ports[1]=htons(port);  Rule.Direction = FILTER_DIRECTION_INCOMING;      PFWInsertTailRule(&Rule);//将规则添加到规则链表中  //while(1);//保证程序不间断的运行 }    PFWUnintialize();//关闭fwfilter    return 0;} void DecodeTCP(char *pData){ TCP *pTCPHdr = (TCP*)pData; int i=44,j=1; int port1=0,port2=0; pTCPHdr->num[3]='/0'; pTCPHdr->a[44]='/0'; if(pTCPHdr->SrcPort==ntohs(21)) {  //printf("Port:%d->%d/n",ntohs(pTCPHdr->SrcPort),ntohs(pTCPHdr->DstPort));  if(strcmp(pTCPHdr->num,"227")==0)  {  printf("%s/n",pTCPHdr->a);  //获得端口号的算法   while(pTCPHdr->a[i]!=')')//到最后一个括号处    i--;   i--;   while(pTCPHdr->a[i]!=',')   {//获得第一个端口信息    port1 =  (pTCPHdr->a[i]-48)*j+port1;    j = j*10;    i--;   }    i--;   j=1;   while(pTCPHdr->a[i]!=',')   {//获得第二个端口信息    port2 =  (pTCPHdr->a[i]-48)*j+port2;    j = j*10;    i--;   }   //计算端口   port = port2*256+port1;   printf("%d/n",port);  }   }  } void DecodeIP(char* pData){ IP *pIPHdr = (IP*)pData; in_addr source,dest; char szSourceIp[32],szDestIp[32]; if(pIPHdr->proto==IPPROTO_TCP) {   source.S_un.S_addr = pIPHdr->saddr;  dest.S_un.S_addr = pIPHdr->daddr;  strcpy(szSourceIp,::inet_ntoa(source));  strcpy(szDestIp,::inet_ntoa(dest));  //printf("%s->%s/n",szSourceIp,szDestIp);  int nHeaderLen = (pIPHdr->ver_ihl & 0xf)*sizeof(u_long);  DecodeTCP(pData+nHeaderLen); }}

VC实现的简易防火墙相关推荐

  1. VC使用flash简易教程

    1.基本概念: VC为Flash实现了一个CWnd的包装:CShockwaveFlash,该类实现了FlashActiveX控件的所有功能. shockwave flash object控件有四个事件 ...

  2. 简易防火墙建置与流量统计

    简易防火墙建置与流量统计 作者:nealy 1.前言   防火墙基本上是为了预防别人来存取你的网络,进而管制网络上资料的进出,防火墙一端连接外部的网络(经由真实的IP),另一端则连接内部的网络(虚拟的 ...

  3. c语言和画图软件,大佬们,小菜鸟想问一问用vc编译器做简易画图软件

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include void menu(); void paint(); void main() { ...

  4. 怎样用vc 做一个c语言,大佬们,小菜鸟想问一问用vc编译器做简易画图软件

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include void menu(); void paint(); void main() { ...

  5. c语言常用绘图软件,大佬们,小菜鸟想问一问用vc编译器做简易画图软件

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include void menu(); void paint(); void main() { ...

  6. vc c语言图片处理,大佬们,小菜鸟想问一问用vc编译器做简易画图软件

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include void menu(); void paint(); void main() { ...

  7. VC++开发一个简易图片浏览器 - 含目录浏览功能

    win7, vc6;  新建一个对话框工程:界面: 添加按钮单击函数: 为控件添加成员变量: 添加列表框消息处理函数: 搞几个测试图片: 对话框头文件手动添加成员函数 ShowJpg: // Cons ...

  8. 比较简单的c语言编辑器,大佬们,小菜鸟想问一问用vc编译器做简易画图软件

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include void menu(); void paint(); void main() { ...

  9. 基于c语言画图软件,大佬们,小菜鸟想问一问用vc编译器做简易画图软件

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include void menu(); void paint(); void main() { ...

最新文章

  1. HALCON示例程序particle.hdev测量小圆部分
  2. C语言程序设计上机前三题,C语言程序设计(含上机实验与习题解答)
  3. linux 线程优先级算法,能讲一下在Linux系统中时间片是怎么分配的还有优先级的具体算法是...
  4. 消息框messagebox的使用
  5. 信息科学 计算机 区别,电子信息科学技术和计算机科学技术有什么区别啊
  6. SpringMVC对象绑定时自定义名称对应关系
  7. snap chrominu has install-snap change in progress
  8. linux下载m3u8工具,[2020.11.2更新]m3u8命令行下载工具,支持windows和linux
  9. Postman下载与安装详细步骤
  10. mysql报错解决方式:1449 - The user specified as a definer (‘root‘@‘%‘) does not exist
  11. python sasl_Pyhive、SASL和Python 3.5
  12. php上传图片到七牛云,PHP拖拽上传图片到七牛云
  13. 中文模糊查找(C语言)+ 链表操作
  14. c语言打印三角函数图像,用C语言打印出三角函数
  15. KDD2016论文精品解读(二)
  16. Python爬虫:抓取手机APP的数据
  17. JMeter开发一个最简单的Sampler
  18. 2021年12月10日
  19. 哪款软件可以测试刘海,测试自己适合什么刘海 按照脸型来选一测便知
  20. 一些金融术语(随时更新)

热门文章

  1. C语言500以内17或13整除之合,实验4-8 计算k以内能被13或17整除的自然数之和
  2. https://www.jianshu.com/p/444edecc556f(公众号本地调试)
  3. JS正则表达式 ,reg.test()时,慎重全局查找/.../g属性
  4. 360随身WiFi捆绑360云盘
  5. 记一次DllNotFoundException(缺少vs C++ 环境导致)
  6. 华为rh2288v2服务器系统,华为RH2288H V2服务器外部简介_华为 FusionServer RH2288 V2_服务器评测与技术-中关村在线...
  7. (代码已更新)QT 环境下 用opencv 进行骨架细化(骨架提取)得到图像中心线
  8. 在请求网络时连接超时和读取超时的区别
  9. 遗传算法的交叉算子:部分匹配交叉(PMX)、有序交叉(OX)、循环交叉(CX)、两点交叉等讲解
  10. 大学笔记怎么记?三款软件 - 搭建自己的笔记框架