端口扫描程序的设计与实现(共19页).doc

上传人:飞****2 文档编号:19333600 上传时间:2022-06-06 格式:DOC 页数:19 大小:126.50KB
返回 下载 相关 举报
端口扫描程序的设计与实现(共19页).doc_第1页
第1页 / 共19页
端口扫描程序的设计与实现(共19页).doc_第2页
第2页 / 共19页
点击查看更多>>
资源描述

《端口扫描程序的设计与实现(共19页).doc》由会员分享,可在线阅读,更多相关《端口扫描程序的设计与实现(共19页).doc(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精选优质文档-倾情为你奉上端口扫描程序的设计与实现摘 要计算机信息网络的发展加速了信息化时代的进程,但是随着社会网络化程度的增加,对计算机网络的依赖也越来越大,网络安全问题也日益明显。端口扫描技术是发现安全问题的重要手段之一。本程序是在Windows系统中使用C语言用MFC完成的一个端口扫描程序。此程序主要完成了TCP connect()扫描和UDP扫描功能。TCP扫描支持多线程,能对单个指定的主机进行扫描或对指定网段内的主机进行逐个扫描。能扫描特定的部分端口号或对指定的端口段内的端口进行逐个扫描。此端口扫描程序能快速地进行TCP扫描,准确地检测出对TCP协议开放的端口。而对于UDP扫描只支持

2、单线程,速度较慢。扫描结果以列表的形式直观地展现出来。关键词:端口扫描、TCP扫描、UDP扫描、TCP多线程扫描专心-专注-专业目 录 1 引言1.1 课题的背景及意义网络中每台计算机犹如一座城堡,这些城堡中,有些是对外完全开放的,有些却是大门紧闭的。入侵者们是如何找到,并打开它们的城门呢?这些城门究竟通向何处?在网络中,把这些城堡的“城门”称之为计算机的“端口”。端口扫描是入侵者搜索信息的几种常用方法之一,也正是这一种方法最容易暴露入侵者的身份和意图。一般说来,扫描端口有以下目的:判断目标主机上开放了哪些服务判断目标主机的操作系统如果入侵者掌握了目标主机开放了哪些服务,运行何种操作系统,他们

3、就能使用相应的手段实现入侵。而如果管理员先掌握了这些端口服务的安全漏洞,就能采取有效的安全措施,防范相应的入侵。1.2 端口扫描现状计算机信息网络的发展加速了信息化时代的进程,但是随着社会网络化程度的增加,对计算机网络的依赖也越来越大,网络安全问题也日益明显。端口扫描技术是发现安全问题的重要手段之一。一个端口就是一个潜在的通信通道,也就是一个入侵通道。对目标计算机进行端口扫描,能得到许多有用的信息。扫描器通过选用远程TCP/IP不同的端口的服务,并记录目标给予的回答,通过这种方法,可以搜集到很多关于目标主机的各种有用的信息,从而发现目标机的某些内在的弱点。2 系统设计2.1 系统主要目标本程序

4、主要实现了:简易的TCP connect()扫描,支持多线程;UDP扫描功能;能对单个指定的主机进行扫描或扫描指定网段内的主机;能扫描特定的部分端口号或对指定的端口段内的端口进行逐个扫描;2.2 开发环境及工具测试平台:Windows XP Professional使用软件:Visual C+ 6.0开发语言:C语言2.3 功能模块与系统结构作为端口扫描程序,首先需要完成的功能就是对于系统操作系统的服务端口进行扫描,返回扫描结果。对于端口的扫描,包括对于本机系统服务端口,局域网内目标机系统,以及远程IP的系统服务端口进行扫描。有些时候,用户并不需要去扫描整个系统的所有端口,因为这样的话不仅会浪

5、费大量的时间,而且可能导致难以找到自己需要了解的端口的扫描结果。所以,对于选择性地对端口进行扫描也非常重要。这当然也是扫描程序需要实现的功能之一。用户在等待扫描的时候,往往希望知道它的工作进度。这样用户可以更好地控制自己的操作。站在用户的角度思考,设置进度是程序需要完成的,这样就能知道程序扫描的进度。系统必须提供的服务是功能需求的基本,本着站在用户角度思考的原则,做出如上叙述需求,从简列举如下:扫描功能;地址选择功能;端口选择功能;进度显示功能;端口扫描程序功能模块如下图所示:端口扫描系统操作显示设置地址设置端口设置协议开始扫描进度显示结果显示程序运行流程图:开始开始扫描设置扫描参数(IP、端

6、口、协议)读入用户设置的IP、端口号、协议nowAddr=StartAddri=0初始化进度条进行TCP扫描nowAddr=EndAddri+itotalPort进行UDP扫描显示打开端口AfxBeginThread(DoScanPort_TCP,&inforabout,0,0,0,NULL)nowAddr+nowAddr=EndAddrnowAddr=StartAddri=0ih_addr_listi!= NULL; i+ )/*对每一个IP地址进行处理*/pszAddr = inet_ntoa (*(struct in_addr *)pHost-h_addr_listi);break;3.

7、2 分割字符串函数的实现由于扫描结果是使用静态字符串保存的,所以最后显示的时候,需要用到分割字符串函数,来将字符串中扫描出的端口号分离出来显示。本函数主要是通过Find()函数来查找用作分隔符的字符串在待查找的字符串中的位置,然后通过Add()函数将分隔符之间的字符保存进数组中,来达到分割字符的目的。 while( -1 != pos ) if( -1 = pre_pos ) pos = source.Find(division,pos); else pos = source.Find(division,(pos+1); if( -1 = pre_pos ) iFirst = 0; if( -

8、1 = pos ) nCount = source.GetLength(); else nCount = pos; else iFirst = pre_pos+len; if( -1 != pos ) nCount = pos - pre_pos - len; else nCount = source.GetLength()-pre_pos-len; dest.Add(source.Mid(iFirst,nCount); pre_pos = pos; 3.3 获取待扫描的IP地址通过判断选择的哪个Radio Button的值,来选择从对应的IP Address控件中读入用户输入的值,若是单个的

9、IP则将开始地址StartAddr和结束地址EndAddr都赋值为IP Address控件的值;若是IP范围,则第一个IP地址赋值给StartAddr,最后一个IP地址赋值给EndAddr。void CPortScanDlg:setAddr(DWORD& StartAddr,DWORD& EndAddr)switch(m_conf_IP.m_IP)case 0:m_conf_IP.m_IP_Self.GetAddress(StartAddr);m_conf_IP.m_IP_Self.GetAddress(EndAddr);break;case 1:m_conf_IP.m_IP_Design.G

10、etAddress(StartAddr);m_conf_IP.m_IP_Design.GetAddress(EndAddr);break;case 2:m_conf_IP.m_IP_Start.GetAddress(StartAddr);m_conf_IP.m_IP_End.GetAddress(EndAddr);break;default:break;3.4 获取待扫描的端口号首先读入用户设置的允许的最大线程数。再通过判断选择的哪个Radio Button的值,来选择从对应的Edit Box控件中读入用户输入的值。若是指定的端口号,则循环读入Edit Box中的端口号 (一个端口号占用一行,

11、一次读入一行),每行的字符不超过9字符,再在读入的每行字符的末尾添加字符串结束标记 0,再通过atoi()函数把字符型转换为整型,存放在定义的数组结构中,并保存端口号的总个数。若是端口范围,则第一个端口号的值和最后一个端口号的值分别读入存放在定义的结构体中。void CPortScanDlg:setPort(tag_PORTS *pScanParam,int& ThreadNum)ThreadNum=m_conf_Port.m_ThreadNum;switch(m_conf_Port.m_Port)case 0:short nCount = 0;char buff10;for(int i=0;

12、 inArrOfPortsnCount+= atoi(buff);pScanParam-nCount = nCount;pScanParam-bSepecifiedPort=0;break;case 1:pScanParam-bSepecifiedPort=1;pScanParam-iStartPort=m_conf_Port.m_StartPort;pScanParam-iEndPort=m_conf_Port.m_EndPort;break;default:break;3.4.1 指定端口号的初始化首先试着读取DefaultPorts.txt文件中保存的端口号,若读入成功,则显示该文本文档

13、中保存的值;若该文件不存在或读入异常,则显示默认设置的值。void conf_Port:ReadDefaultPorts()tryCStdioFile f(DefaultPorts.txt, CFile:modeRead|CFile:typeText);CString s, ss;while (f.ReadString(ss)s += ss;s += rn;GetDlgItem(IDC_EDIT_DesignPort)-SetWindowText(s);f.Close();catch(.)CString s = 13rn37rn123rn135rn139rn489rn1002;GetDlgIt

14、em(IDC_EDIT_DesignPort)-SetWindowText(s);3.4.2 指定端口号的保存在运行端口扫描时会将指定端口保存进文本文档DefaultPorts.txt中,若此文件不存在,则创建此文件。void conf_Port:SaveDefaultPorts()CStdioFile f(DefaultPorts.txt, CFile:modeCreate|CFile:modeWrite|CFile:typeText);char buff10;for(int i=0; im_DesignPort.GetLineCount(); i+)int len = m_DesignPo

15、rt.GetLine(i, buff, 9);if (len != 0)bufflen = 0;f.WriteString(buff);f.WriteString(rn);f.Close();3.5 TCP connect() 扫描这是最基本的TCP扫描。操作系统提供的connect()系统调用,用来与每一个感兴趣的目标计算机的端口进行连接。如果端口处于侦听状态,那么connect()就能成功。否则,这个端口是不能用的,即没有提供服务。这个技术的一个最大的优点是,你不需要任何权限。系统中的任何用户都有权利使用这个调用。另一个好处就是速度。如果对每个目标端口以线性的方式,使用单独的connect

16、()调用,那么将会花费相当长的时间,你可以通过同时打开多个套接字,从而加速扫描。使用非阻塞I/O允许你设置一个低的时间用尽周期,同时观察多个套接字。但这种方法的缺点是很容易被发觉,并且被过滤掉。目标计算机的logs文件会显示一连串的连接和连接是出错的服务消息,并且能很快的使它关闭。3.5.1 基本原理调用connect()函数,根据返回值来判断端口是否打开的,connect()函数返回0说明建立连接成功,说明该端口是打开的,就将该端口保存进静态字符串变量中,然后关闭连接,则线程数减一。RunThreadNum是用来控制最大线程数量的。UINT CPortScanDlg:DoScanPort_T

17、CP(LPVOID lp)ret=connect(sock,(struct sockaddr*)&sin,sizeof(sin);if(ret=0)str.Format(%d,ntohs(sin.sin_port);showout_tcp+=str+|;closesocket(sock);RunThreadNum-;3.5.2 扫描多个主机多端口多线程的实现扫描多个主机是使用for循环来实现逐个扫描的,多端口也是使用for循环来实现逐个扫描的。最大线程数量是通过变量RunThreadNum的值来控制的,当其值大于允许的最大线程数maxthread时,便Sleep等待,直到存活的线程数小于max

18、thread,经过测试最大线程数maxthread设置为150效果较好,不宜大于200。多线程的创建是通过调用AfxBeginThread()函数来实现的。for(nowAddr=StartAddr;nowAddr=EndAddr;nowAddr+)for(int i=0;imaxthread)Sleep(20); hThreadTcp=AfxBeginThread(DoScanPort_TCP,&inforabout,0,0,0,NULL);CloseHandle(hThreadTcp);Sleep(10);.3.5.3 扫描结果的显示首先判断静态字符串变量showout_tcp是否为空,若

19、为空说明没有端口是打开的。若存在打开的端口,则调用分割字符串函数将打开的端口号提取出来存放到Array数组中,再分别显示出来。if(showout_tcp!=)ArrayNum = Split_CString(showout_tcp,Array,|);temp=0;while(temp 1)cksum += *buffer+;size -= sizeof(USHORT);if(size)cksum += *(UCHAR*)buffer;cksum = (cksum 16) + (cksum & 0xffff); cksum += (cksum 16);return (USHORT)(cksum

20、);3.6.3 发送UDP数据包先调用WSASocket()函数创建sock套接字,再调用setsockopt()函数设置套接字选项,再将UDP、IP头部填充好,最后调用sendto()函数将构造的数据包发送到目的IP地址的扫描的端口。USHORT CPortScanDlg:Send_UDPinfo(UINT S_ADR,UINT D_ADR,USHORT DF_SPT,USHORT SCAN_DPT) if (sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED)=INVALID_SOCKET) if (C

21、heck_Ret = setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&FLAG,sizeof(FLAG) total_len,0,(struct sockaddr *)&DEST_ADDR,sizeof(DEST_ADDR);closesocket(sock);return 0;3.6.4 接收ICMP数据包首先定义一个套接字集合,并将其清空,再把读数据的套节字加入到套接字集合中,再通过select()函数检查套节字是否可读:1.如果没有则返回1给主调函数,表示没有收到返回的ICMP_PORT_UNREACH错误数据报,则说明该端口是打开的。2.

22、如果有可读的套接字,就再通过FD_ISSET()函数检查需要读取的套接字是否在可读的套接字集合中:(1)如果可读的套接字中没有需要读取的套接字,则返回1给主调函数,表示没有收到返回的ICMP_PORT_UNREACH错误数据报,则说明该端口是打开的。(2)如果可读的套接字中有需要读取的套接字,则调用recvfrom()函数从套接口上接收数据,如果没有数据,则说明该套接口不是用来传送数据的,则可以判断为返回的ICMP_PORT_UNREACH错误数据报,则说明该端口是关闭的。USHORT CPortScanDlg:Get_ICMPinfo(UINT ICMP_SOCK, LPSOCKADDR_I

23、N SOURCE_ADDRESS) FD_ZERO(&rset);FD_SET(ICMP_SOCK, &rset);if(RECV_MSG = select(ICMP_SOCK,&rset,NULL,NULL,&tv) 0)if(FD_ISSET(ICMP_SOCK,&rset)RECV_MSG = recvfrom(ICMP_SOCK,(char *)&icmpheader,sizeof(I_IPDATA),0,(LPSOCKADDR)&SOURCE_ADDRESS,&Recv_Slen);if(RECV_MSG = 0)return 0;return 1; 4 测试报告4.1 TCP扫描检

24、测4.1.1扫描本机1.IP设置(1)IP设置为本地IP(10.15.66.158):(2)IP设置为127.0.0.1:2.端口设置为0-1024,最大线程数设置为100,协议选择TCP3.扫描结果(1)IP设置为本地IP(10.15.66.158)的扫描结果:(2)IP设置为127.0.0.1的扫描结果:设置为扫描本地IP和设置为扫描127.0.0.1时扫描结果会有差别:扫描127.0.0.1时扫描不出端口139,具体原因还不清楚。4.1.2扫描网络中其他主机1.设置IP(经过ping命令发现IP为10.15.66.44的主机能ping通)2.端口设置为0-1024,最大线程数设置为100

25、,协议选择TCP。扫描结果如下:由扫描结果可知能正常扫描,能正确扫描出能进行TCP连接的端口4.1.3 扫描IP段1.设置IP2.端口设置为扫描指定端口,最大线程数设置为100,协议选择TCP3.扫描结果由扫描结果可知能正常扫描,但由于没有先判断主机是否在线,所以对不在线的主机也发送了连接请求,导致扫描速度较慢。4.2 UDP扫描检测4.2.1 扫描本机1.IP设置(1)IP设置为本地IP(10.15.66.158):(2)IP设置为127.0.0.1:2. 由于是单线程,扫描速度较慢,端口设置为扫描指定端口,协议选择UDP3.扫描结果:IP设置为本地IP(10.15.66.138)的扫描结果

26、和IP设置为127.0.0.1的扫描结果相同:用UDP协议扫描本机的端口,由于收不到发送的ICMP_PORT_UNREACH错误数据报,导致结果误判为所有端口都是打开的。4.1.2扫描网络中其他主机1.设置IP(经过ping命令发现IP为10.15.66.44的主机能ping通)2. 由于单线程,扫描速度较慢,端口设置为扫描指定端口,同扫描本机的设置。协议选择UDP3.扫描结果如下由扫描结果可知能正常扫描。4.3 TCP、UDP一起扫描IP设置为10.15.66.44,端口设置为指定端口,协议选择TCP和UDP,扫描结果如下:由扫描结果可知能正常扫描,但由于TCP扫描使用多线程速度较快,而UD

27、P扫描则是单线程,所以速度较慢,若同时进行两种协议的扫描,会使整体速度下降很大,所以不建议选择两种协议同时进行扫描。结 论本设计经过近1个多月的努力,基本满足了一个端口扫描程序的基本要求。完成后的程序实现了TCP connect()扫描和UDP扫描功能,TCP扫描支持多线程,能大大加快扫描速度。能对单个指定的主机进行扫描或扫描指定网段内的主机。能对指定的端口段内的端口进行逐个扫描,或扫描特定的部分端口号,以避免在不需要了解的端口号上浪费时间。进度条显示,能方便用户随时知道扫描的进度。系统设计期间,学习到很多课堂上没有的知识,还积累了很多实践经验,增强了动手能力和解决实际问题的能力。通过这次的课

28、程设计,对网络编程有了更深入的了解,进一步熟悉了TCP和UDP协议的内容,掌握了TCP、UDP扫描端口的基本原理,学会了运用sock套接字构造UDP数据包并发送,以及如何接收ICMP数据包。对编程思想有了进一步的体会,养成了一些良好的编程习惯。系统虽然完成,但还有很多不足之处,希望自己能不断学习和实践,争取以后做得更好。虽然此软件实现了支持多线程的TCP connect()扫描功能,和单线程的UDP扫描功能。但也还有很多不足之处,如扫描功能单一:不支持TCP SYN扫描、TCP FIN 扫描以及IP段扫描等功能,对UDP扫描不支持多线程功能,而且在扫描主机前没有发送ICMP报文去判断主机是否在线,还需要进一步完善。限于作者知识水平和经验有限,此程序还有许多有待完善和改正的地方,恳请各位老师和读者批评指正。参考文献 1 甘刚、闫丽丽、盛志伟、冼进Linux/UNIX网络编程中国水利水电出版社2008年第1版。2 范建华、胥光辉、张涛 等译TCP/IP详解 卷1:协议机械工业出版社2009年第1版。3 黄维通Visual C+面向对象与可视化程序设计(第2版)清华大学出版社2007年第2版4 郑莉、董渊、张瑞丰C+语言程序设计(第3版)清华大学出版社2004年第3版

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁