实验5:端口扫描器的设计与实现(一)实验目的和内容:目的:加深对TCP/IP的理解,学习端口扫描技术和原理,熟悉socket编程。内容:实现一个扫描器,使用TCPconnect进行端口扫描,并对扫描结果进行记录。(二)课程设计要求:Windows或Linux环境下,程序在单机上运行;使用端口扫描器对一台主机进行扫描,并显示出结果;对一个网段进行IP扫描,显示出结果;编程语言不限;提供友好的用户界面。(三)端口扫描技术:“端口”是专门为计算机通信而设计的,它不是硬件,不同于计算机中的“插槽”,可以说是个“软插槽”。“端口”是由计算机的通信协议TCP/IP协议定义的。其中规定,用IP地址和端口作为套接字,它代表TCP连接的一个连接端,一般称为Socket。具体来说,就是用[IP:端口]来定位一台主机中的进程。计算机就像一座大楼,这个大楼有好多入口(端口),进到不同的入口中就可以找到不同的公司(进程)。端口与进程是一一对应的,入侵者通过扫描端口,便可以判断出目标计算机有哪些通信进程正在等待连接。(四)扫描端口的目的:端口扫描是入侵者搜集信息的几种常用手法之一,也正是这一过程最容易使入侵者暴露自己的身份和意图。•判断目标主机上开放了哪些服务;•判断目标主机的操作系统。如果入侵者掌握了目标主机开放了哪些服务,运行何种操作系统,他们就能够使用相应的手段实现入侵。(五)端口的分类:端口是一个16bit的地址,用端口号进行标识不同的作用。端口一般分为两类。•熟知端口号(公认端口号):由因特网指派名字和号码公司ICANN负责分配给一些常用的应用层程序固定使用的熟知端口,其数值一般为0~1023。•一般端口号:用来随时分配给请求通信的客户进程。(六)扫描原理的基础知识:TCP/IP模型四层结构TCP与UDP协议TCP报文结构TCP连接和释放过程(七)TCP/IP模型四层结构:(八)TCP与UDP协议:Internet的网络通信大多是建立在这两个协议之上的,各个主机遵循着TCP/IP协议封装数据包进行通信。传输控制协议TCP(TransmissionControlProtocol):TCP提供可靠的、面向连接的运输服务,用于高可靠性数据的传输。TCP具有完善的错误检测与恢复、顺序控制和流量控制等功能。注重可靠性的场合一般使用TCP协议,例如FTP、Telnet。用户数据报协议UDP(UserDatagramProtocol):UDP在传送数据之前不需要先建立连接。远地主机的运输层在收到UDP数据报后,不需要给出任何确认。广泛应用于只需一次的C/S模式的请求-应答查询,或者要求提供高效率数据传输的场合。注重实时性、传输率、吞吐量的场合一般使用UDP,如QQ。(久)TCPconnect扫描:实现原理:通过调用socket函数connect()连接到目标计算机上,完成一次完整的三次握手过程。如果端口处于侦听状态,那么connect()就能成功返回。否则,这个端口不可用,即没有提供服务。优点:稳定可靠,不需要特殊的权限。缺点:扫描方式不隐蔽,服务器日志会记录下大量密集的连接和错误记录,并容易被防火墙发现和屏蔽。实验设计流程:1.原理概述通过调用socket函数connect()连接到目标计算机上,完成一次完整的三次握手过程。如果端口处于侦听状态,那么connect()就能成功返回。否则,这个端口不可用,即没有提供服务。2.运行环境本扫描软件用java语言开发,可稳定的运行在linux和windows环境下。3.基本设计思路用户界面:使用java里面的swing包来开发用户界面;端口扫描:使用socket函数connect()连接目标计算机来判定是否目标计算机开放了要测试的端口;Ip扫描:通过测试一些经常开放的端口,如果能连接其中一个,则该ip地址在该网段内使用着,否则可以判断未使用。测试的常用端口越多,得到的结果越精确,但运行的速度越慢。4..功能模块设计本软件有两个功能模块,分别是指定主机的端口扫描和指定网段的ip扫描.。5.程序流程及主要算法核心算法是TCP的连接函数Socketsocket=newSocket(portscan.getIp(),portscan.getPort());根据连接结果判断指定的端口是否开放。if(socket.isConnected()){jta2.append(portscan.getPort()+\n);}6.程序使用说明在ip扫描面板上点击“开始”按钮进行ip地址的扫描,为了提高ip地址的扫描速度,这里使用了多线程的并发机制,大大提高了扫描的速度。在port扫描面板上点击“开始端口扫描”按钮,对输入的ip地址的指定端口范围进行扫描。在linux下运行:在linux下运行时,有一个非常惊人的发现(相对于我来说),在linux下进行端口扫描时,3分钟左右就可以扫描一遍所有的(65535个)端口,而在windows下,每秒钟只能扫描1个端口。难怪企业级服务器最好的选择是linux,unix!7.程序分析与总结本程序使用java语言开发,可以稳定的运行在windows和linux系统下,在ip扫描时由于扫描的速度比较慢,故使用了多线程的并发机制,大大提高了运行速度。附录A-源程序代码文件说明源代码为java的工程,在bin目录下有编译好的字节码文件,可以直接运行。附录B-参考文献Java语言程序设计基础篇Java语言程序设计进阶篇源代码如下:代码1:Main.java(程序运行的入口)publicclassMain{/***@paramargs*/publicstaticvoidmain(String[]args){newPortScannerFrame();}}代码2:IPScan.java(实现网段内ip地址的扫描)importjava.io.IOException;importjava.net.InetAddress;importjava.net.InetSocketAddress;importjava.net.Socket;importjava.net.UnknownHostException;importjava.util.ArrayList;publicclassIPScan{Socketsocket;StringstartIP;StringendIP;ArrayListIntegerportArray=newArrayListInteger();publicIPScan(){this.setPortArray();}publicIPScan(StringstartIP,StringendIP,intport){this.startIP=startIP;this.endIP=endIP;}publicIPScan(StringstartIP){this.startIP=startIP;}publicArrayListIntegergetPortArray(){returnportArray;}publicvoidsetPortArray(){portArray.add(80);//portArray.add(135);//portArray.add(443);portArray.add(445);//portArray.add(843);//portArray.add(902);//portArray.add(912);portArray.add(8080);}publicsynchronizedvoidplusIP(){String[]ipcodes=startIP.split([.]);inttemp=Integer.parseInt(ipcodes[3]);temp++;startIP=ipcodes[0]+.+ipcodes[1]+.+ipcodes[2]+.+temp;System.out.println(startIP);}publicSocketgetSocket(){returnsocket;}publicvoidsetSocket(Socketsocket){this.socket=socket;}publicStringgetStartIP(){returnstartIP;}publicvoidsetStartIP(StringstartIP){this.startIP=startIP;}publicStringgetEndIP(){returnendIP;}publicvoidsetEndIP(StringendIP){this.endIP=endIP;}}代码三:PortScan.javaimportjava.io.IOException;importjava.net.*;importjavax.swing.JOptionPane;importjavax.swing.JTextArea;publicclassPortScan{Stringip;Socketsocket;intport=0,endPort=65525;publicPortScan(){this.ip=127.0.0.1;this.port=8000;}publicStringgetIp(){returnip;}publicvoidsetIp(Stringip){this.ip=ip;}publicintgetPort(){returnport;}publicvoidsetPort(intport){this.port=port;}publicintgetEndPort(){returnendPort;}publicvoidsetEndPort(intendPort){this.endPort=endPort;}}代码四:PortScannerFrame.java(程序的主要窗体)importjava.awt.BorderLayout;importjava.awt.Color;importjava.awt.GridLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.IOException;importjava.net.Socket;importjava.net.UnknownHostException;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjavax.swing.*;publicclassPortScannerFrameextendsJFrameimplementsActionListener{JTabbedPanejtp=newJTabbedPane();//卡片布局JPanelipPanel=newJPanel();JPanelportPanel=newJPanel();JTextFieldipField=newJTextField(192.168.1.100,20);JLabellabel1=newJLabel(请输入起始ip);JTextFieldipField2=newJTextField(192.168.1.130,20);JLabellabel2=newJLabel(请输入终止ip);JButtonstartButton=newJButton(开始);JTextAreajta0=newJTextArea(在该网段下使用的ip地址:\n);JTextAreajta1=newJTextArea(在该网段下未使用的ip地址:\n);//ip扫描结果//端口扫描部分JLabellabel3=newJLabel(请输入要扫描的主机的ip地址:);JTextFieldipFieldForPortScan=newJTextField(127.0.0.1,20);JButtonstartPortScan=newJButton(开始端口扫描);