精华内容
下载资源
问答
  • 端口扫描
  • 本设计通过端口扫描器的研究来提高对计算机安全的认识。利用TCPconnect扫描原理,扫描主机通过TCP/IP协议的三次握手与目标主机的指定端口建立一次完整的连接,如果目标主机该端口有回复,则说明该端口开放。利用多...
  • 一个简单的java端口扫描程序 可以实现端口的扫描
  • 机遇TCI的端口扫描课程设计,计算机网络,包含全部代码,设计思路,以及实验报告!
  • 计算机网络课程设计——端口扫描器的实现 1.利用Socket通信机制实现一个多线程的端口扫描器。 2.设计要求: 2.1用户界面:用户可以输入IP地址或IP地址段;输入端口号或端口号范围;列表显示主机名、开放的端口及...
  • 计算机端口扫描工具

    2018-03-04 18:31:49
    计算机端口扫描工具,快速扫面可用端口,方便快捷,实用
  • 广工 计算机网络课程设计 端口扫描器的设计与实现 代码和报告
  • TCP connect扫描是最基本的扫描,操作系统提供的connect()系统调用,用来与每一个感兴趣的目标计算机端口进行连接。如果端口处于侦听状态,那么connect()就能成功。否则,这个端口是不能用的,即没有提供服务...
  • 网络端口扫描成(计算机专业毕业设计)比较简单的一个小程序奥,每个人都能看得懂
  • 瓜大计算机学院《网络原理》实验报告2
  • 2. 演示:使用端口扫描对一台主机进行扫描,并显示出结果(一台主机上有哪些端口是打开的)。对一个网段进行 IP扫描,显示出结果(一个网段内有哪些主机是开机的)。 3. 在使用 ICMP Echo扫描时,要求程序能够判断...
  • 计算机网络课程设计 报告 及源代码 欢迎大家踊跃下载
  • 计算机网络——简单的端口扫描

    千次阅读 2017-07-31 21:49:08
    计算机网络的学习中,不由得觉得这门课的零碎知识点异常之多,同时因为学习的课本是老外的教材——自顶向下方法,因此学习起来不免觉得吃力,但是从老外的教材里更能从一定高度理解计算机网络的知识体系,也是乐在...

    在计算机网络的学习中,不由得觉得这门课的零碎知识点异常之多,同时因为学习的课本是老外的教材——自顶向下方法,因此学习起来不免觉得吃力,但是从老外的教材里更能从一定高度理解计算机网络的知识体系,也是乐在其中,同时做英语的习题感觉也很有趣味,从各方面来说可以说是获益良多,认识了很多专业词汇。节课之后,便想做一个简单的端口扫描器,用的语言是java,因为实现界面很简单,同时也有封装好的Socket类可以使用,主要思路如下:

    在主程序界面里输入指定主机名或ip地址,按下start按钮,就可以扫描主机的常用端口是否打开。内部设置了常用端口号:21, 22, 23, 25, 26, 69, 80, 110, 143,443, 465, 995, 1080, 1158,1433, 1521, 2100, 3128, 3306, 3389,7001, 8080, 8081, 9080, 9090, 43958。也可以自行修改。程序实现原理就是利用Java建立Socket去连接目标ip的指定端口,如果能连接上就证明该端口开放。反之,若在超时之前都没有连接上,则该端口是关闭的,同时会产生异常。同时考虑到单线程操作效率较低,也利用了Java可以多线程编程的特点,使用了多线程扫描目标主机的一个端口是否开放,因此最终显示结果中端口的排列顺序是随机的,且内部设定最多同时运行10个线程(可以根据实际情况更改)。

    主要运用的网络知识就是套接字的使用。以及java内部的List容器,java的界面设计,界面布局,以及简单的泛型编程的用法。

    主要代码如下:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.net.SocketAddress;
    import java.net.UnknownHostException;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    
    
    public class ScanPort extends JFrame {
    	/**
    	 * 端口扫描启动主程序
    	 */
    	private static final long serialVersionUID = 1L;
    
    	String str1 = " 常见端口有:";
    	String str2 = "ftp:21,22,telnet:23,smtp:25,http:80";
    	String str3 = "dns:53,tftp:69,snmp:161,162";
    	String str4 = "1158,1433,1521,2100,3128,26,69";
    	String str5 = "3306,3389,7001,8080,8081,110,143";
    	String str6 = "9080,9090,43958,443,465,995,1080";
    
    	JButton jb1 = new JButton("strat");
    	JTextArea jta = new JTextArea();
    	JScrollPane jsp = new JScrollPane(jta);
    	JTextField jtf = new JTextField(17);
    	String IP = "";//待扫描IP或域名
    	List <Integer>portList = new LinkedList<Integer>();// 定义一个List容器表示扫描的团口的List集合
    	Integer[] ports = new Integer[] { 21, 22, 23, 25, 26, 53,69, 80, 110, 143,
    			443,465,69,161,162,135,995,1080,1158,1433,1521,2100, 3128, 3306, 3389,
    			7001, 8080, 8081, 9080, 9090, 43958 ,135,445,1025,1026,1027,1028,1055,5357};
    	// 常见端口集合
    
    	public ScanPort() {
    		this.add(getPanel(), BorderLayout.SOUTH);
    		jsp.setBorder(BorderFactory.createEtchedBorder());
    		jsp.setBackground(Color.cyan);
    		this.add(jsp, BorderLayout.CENTER);
    		this.add(getPanel2(), BorderLayout.NORTH);
    		this.add(getPanel3(), BorderLayout.WEST);
    		this.setBounds(300, 60, 600, 600);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setTitle("ScanPort");
    		jta.setTabSize(4);
    		jta.setFont(new Font("标楷体", Font.BOLD, 16));
    		jta.setLineWrap(true);// 激活自动换行功能
    		jta.setWrapStyleWord(true);// 激活断行不断字功能
    		portList.addAll(Arrays.asList(ports));
    		//将ports中的值加入到set中,并去掉重复的
    
    		jb1.addActionListener(new ActionListener() {
    
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				// TODO Auto-generated method stub
    				
    				IP = jta.getText();
    				//ip为文本框内输入的字符串
    				scanPorts(IP, portList, 10, 800);
    				//超时时间设定为800,线程数设定为10
    			}
    
    		});
    		this.setVisible(true);
    	}
    
    	/**
    	 * 多线程扫描目标主机指定List端口集合的开放情况
    	 * 
    	 * @param ip
    	 *            待扫描IP或域名
    	 * @param portList
    	 *            待扫描的端口的List集合
    	 * @param threadNumber
    	 *            线程数
    	 * @param timeout
    	 *            连接超时时间
    	 * */
    	
    	public void scanPorts(String ip, List<Integer> portSet,int threadNumber, int timeout) {
    		ExecutorService threadPool = Executors.newCachedThreadPool();
    		//线程池
    		for (int i = 0; i < threadNumber; i++) {
    			//10个线程 加入到线程池里
    			ScanMethod scanMethod2 = new ScanMethod(ip, portSet,threadNumber, i, timeout);
    			threadPool.execute(scanMethod2);
    		}
    		threadPool.shutdown();
    		while (true) {
    			if (threadPool.isTerminated()) {
    				System.out.println("扫描结束");
    				break;
    			}
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}// end of while
    	}
    
    
    
    	/*
    	 * 扫描方式:针对一个待扫描的端口的List集合进行扫描
    	 */
    	private class ScanMethod implements Runnable {
    		private String ip; // 目标IP
    		private List<Integer> portList; // 待扫描的端口的List集合
    		private int threadNumber, serial, timeout; // 线程数,这是第几个线程,超时时间
    
    		public ScanMethod(String ip, List<Integer> portList, int threadNumber,int serial, int timeout) {
    			this.ip = ip;
    			this.portList = portList;
    			this.threadNumber = threadNumber;
    			this.serial = serial;
    			this.timeout = timeout;
    		}
    
    		public void run() {
    			int port = 0;
    			Integer[] ports = portList.toArray(new Integer[portList.size()]); // List转数组
    			try {
    				InetAddress address = InetAddress.getByName(ip);  //如果输入的是主机名,尝试获取ip地址
    				Socket socket;//定义套接字
    				SocketAddress socketAddress;//传递ip和端口
    				if (ports.length < 1)
    					//若数组没有元素,返回,不执行
    					return;
    				for (port = 0 + serial; port <= ports.length - 1; port += threadNumber) {
    					//每次运行10个线程
    					socket = new Socket();
    					//为对象分配内存空间
    					socketAddress = new InetSocketAddress(address, ports[port]);
    					try {
    						socket.connect(socketAddress, timeout);
    						//对目标主机的指定端口进行连接,超时后连接失败
    						socket.close();
    						//关闭端口
    						System.out.println("端口 " + ports[port] + " :开放");
    						jta.append("端口 " + ports[port] + " :开放\n");
    						//在文本区域里更新消息
    					} catch (IOException e) {
    						System.out.println("端口 " + ports[port] + " :关闭");
    						jta.append("端口 " + ports[port] + " :关闭\n");
    						//产生异常表示端口关闭
    					}
    				}
    			} catch (UnknownHostException e) {
    				e.printStackTrace();
    			}
    		}
    		//end of run()
    	}//end of ScanMethod
    	
    	public JPanel getPanel() {
    		JPanel jp = new JPanel();
    		jp.add(jb1, BorderLayout.CENTER);
    		jp.setBorder(BorderFactory.createRaisedBevelBorder());
    		jp.setBackground(Color.lightGray);
    		return jp;
    	}
    
    	public JPanel getPanel2() {
    		JPanel jp = new JPanel();
    		JLabel jl = new JLabel();
    		jl.setText("请输入主机名或ip地址,将扫描该主机的常见端口号:");
    		jp.add(jl);
    		jp.add(jtf);
    		jp.setBorder(BorderFactory.createRaisedBevelBorder());
    		jp.setBackground(Color.LIGHT_GRAY);
    		return jp;
    	}
    
    	public JPanel getPanel3() {
    		JLabel jl1 = new JLabel(str1);
    		JLabel jl2 = new JLabel(str2);
    		JLabel jl3 = new JLabel(str3);
    		JLabel jl4 = new JLabel(str4);
    		JLabel jl5 = new JLabel(str5);
    		JLabel jl6 = new JLabel(str6);
    		JPanel jp = new JPanel();
    		jp.setLayout(new GridLayout(6, 1));
    		jp.add(jl1);
    		jp.add(jl2);
    		jp.add(jl3);
    		jp.add(jl4);
    		jp.add(jl5);
    		jp.add(jl6);
    		jp.setBorder(BorderFactory.createEtchedBorder());
    		//蚀刻边框
    		return jp;
    	}
    
    	public static void main(String[] args) {
    		new ScanPort();
    	}
    
    }



    展开全文
  • 1.利用Socket通信机制实现一个多线程的端口扫描器。 2.设计要求: 2.1用户界面:用户可以输入IP地址或IP地址段;输入端口号或端口号范围;列表显示主机名、开放的端口及开放端口上相应的服务名称。 2.2端口的...
  • 主要介绍了Go语言实现的简单网络端口扫描方法,实例分析了Go语言网络程序的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • c#版端口扫描器,可以扫描多主机、多端口。 运行环境:.Net Framweork4
  • 计算机网络实验,,,滑窗协议 端口扫描 csdm\cd ,实验报告,代码,实验截图等,仅供参考学习
  • 网络端口扫描器源码

    2013-04-25 16:01:07
    扫描机器当前使用的网络端口情况。该代码在vc++上编译成功,并能运行。
  • 在VB6.0+WinMe环境下开发,并在WinMe和WinXP操作系统下调试通过,主要功能有本地监听,端口扫描,Ping主机的程序。 该程序在本地监视的界面下,用户首先添加需要监听的端口,并通过另一个界面显示出来,点击界面上的...
  • 网络端口扫描

    2006-09-12 15:07:41
    闪电1.0 是一个多线程的端口扫描工具,用于进行狂速端口扫描。它具有极快的速度 和方便友好的操作界面,能快速地对大网段范围进行 Connect方式端口扫描。同时具有获取端口标识的功能,可以用来快速地获取端口标识...
  • 山东大学计算机网络课程设计中的一个题目,实现对对底层数据包直接获取,并简单分析出IP,端口等相关数据,支持简单的数据破解。端口扫描支持对特定主机的一个或者多个端口开放功能的检测。项目用IDEA编写。
  • 端口扫描

    千次阅读 2018-10-13 19:00:27
    端口扫描是指人为发送一组端口扫描消息,视图以此了解某台计算机的弱点,并了解其提供的计算机网络服务类型。 端口最常用也是最强大的工具是nmap,在nmap的端口扫描方式中,所有的扫描方式都是以-s[x]的形式,若是...

    0x01 端口扫描介绍

    端口扫描是指人为发送一组端口扫描消息,视图以此了解某台计算机的弱点,并了解其提供的计算机网络服务类型。

    端口最常用也是最强大的工具是nmap,在nmap的端口扫描方式中,所有的扫描方式都是以-s[x]的形式,若是ACK扫描则是-sA,若是UDP扫描则是-sU

    0x02 端口状态

    nmap提供了6个端口状态,帮助我们了解目标。

    open

    此端口对外为开放状态

    closed

    此端口关闭,但是有可能是管理员的欺骗手段导致,或是防火墙所致

    filtered

    次扫描被过滤,不过出现这种现象并不代表一定是被某些专业的设备过滤了,也许是因为网络阻塞造成的,建议遇到这种情况分不同的时间段再次进行扫描

    unfiltered

    未被过滤状态意味着端口可以访问,但是nmap并不能判断目标端口处于开放状态还是关闭状态,这里需要重申的是目标端口是否可以访问与是否开放并无太大联系。需要注意的是,当我们使用ACK扫描时才会呈现出这种状态,这时我们可以换一种方式去进行扫描,以便进一步确认。

    open|filtered

    开放还是过滤的,如果nmap发出的探测报文并没有得到目标端口的响应,可能是收到了某些专业设备的阻挡,此时可以换一种方式进一步确认。

    closed|filtered

    该状态用于nmap不能确定端口是关闭的还是被过滤的。值得注意的是,它只可能出现在IPID Idle扫描中。

    0x03 时序选项

    在nmap中,可以使用-T(0-5)启用时序选项。

    -T0(偏执的) 非常慢的扫描,用于IDS逃避

    -T1(鬼祟的) 缓慢的扫描,用于IDS逃避

    -T2(文雅的) 减低速度以减低对宽带的消耗,此选项一般不常用

    -T3(普通的) 默认,根据目标的反应自动调整时间

    -T4(野蛮的) 快速扫描,常用扫描方式,需要在很好的网络环境下进行扫描,请求可能会淹没目标

    -T5(疯狂的) 极速扫描,这种扫描方式以牺牲准确度来提升扫描速度

    0x04 常用扫描方式

    -p选项

    指定一个端口,可以唯一指定一个,也可以指定一个范围

    如果既想扫描TCP、又想扫描UDP,可以在端口前面加上T:选项和U:,分别代表TCP协议或UDP协议。注意必须指定-sU以及一个TCP扫描类型(如-sS、-SF、-sT)。如果没有给定协议限定符,端口号会被加到所有协议列表。

    -F选项

    快速扫描默认的有限的端口,在nmap中的nmap-services包含了默认扫描的端口,也可以使用--daradir选项指定自己的nmap-services文件。

    -r选项

    使用该选项不会对端口进行随机顺序扫描,默认情况下,nmap是随机扫描端口的。

    –port-ratio选项

    使用该选项会扫描指定一定概率以上的端口。

    0x05 TCP SYN扫描

    nmap -sS [ip地址]
    

    SYN的扫描方式相对来说是比较隐蔽的扫描方式,很难被防火墙或是管理员发现,因为它并不会进行TCP的链接,SYN扫描可以明确区分出端口的开放状态,这是一种高效且非常有用的扫描方式。

    namp发送一个SYN请求,如果收到RST:目标主机端口关闭;收到SYN/ACK:目标主机端口开放

    0x06 TCP链接扫描

    nmap -sT [ip地址]
    

    当SYN扫描可用时,它通常是更好的选择。

    namp发送一个SYN请求,如果收到RST:目标主机端口关闭;收到SYN/ACK:目标主机端口开放

    0x07 UDP扫描

    nmap -sU -p [端口] [ip地址]
    

    UDP扫描发送空的UDP扫描到目标端口,这里需要注意的是,UDP头是没有任何数据的,这就使nmap可以轻松识别目标端口的开放状态,如果返回ICMP端口不可达错误就认为该端口是关闭的;未收到回应就说明是被过滤的;被响应了则说明是开放状态。

    0x08 隐蔽扫描

    隐蔽扫描有三个选项:

    • -sN Null扫描 如果目标端口是关闭的,会响应一个RST数据包;如果端口是开放的,则不会响应任何消息
    • -sF FIN扫描 如果收到目标响应的RST数据包,说明端口是开放的;没有收到RST数据包则说明端口是关闭的
    • -sX 如果目标端口开放则会响应一个RST标志包

    这些扫描方式会躲过一些无状态防火墙的过滤,这比SYN扫描、UDP扫描会有更好的效果,更加隐蔽。

    0x09 TCP ACK扫描

    nmap -sA [ip地址]
    

    TCP ACK扫描有一个致命的缺点,它不能确定端口是开放的还是被过滤的。当扫描未被过滤的系统时,开放的和关闭的都会返回RST报文。但是可以利用它来扫描防火墙的配置,用它来发现防火墙规则,确定它们是有状态的还是无状态的,哪些端口是被过滤的。

    0x0A TCP窗口扫描

    nmap -sW [ip地址]
    

    有时开放端口用正数表示窗口大小,关闭窗口的大小为0,所以,当收到RST包时,根据窗口的值时正数还是0来判断端口是开放的还是关闭的。

    0x0B 自定义TCP扫描

    namp -sT --scanflags [标志位(多个标志位之间不用分隔符隔开)]
    如:namp -sT --scanflags SYNURG [ip地址]
    

    若不指定基本类型,则默认为SYN扫描

    oxoC 空闲扫描

    空闲扫描允许进行端口完全欺骗。利用僵尸主机进行伪装。

    namp -sI [僵尸主机]:[端口] [目标主机ip]
    
    展开全文
  • C# 网络编程 端口扫描

    2008-11-10 15:58:36
    c# 源码,网络编程,端口扫描,可以扫描计算机打开的端口和没打开的端口
  • 对211.81.169.1-255 用 portscan进行端口扫描,可以查看对方和自己的漏洞,从而进行攻击和防范。
  • 计算机网络端口大全,对网管有一些用。例如 5632 pcAnywere 你会看到很多这个端口的扫描,这依赖于你所在的位置。当用户打开pcAnywere时,它会自动扫描局域网C类网以寻找可能得代理(译者:指agent而不是proxy)。...
  • 常用计算机网络端口

    万次阅读 2018-03-17 09:55:55
    一、概述我们知道,一个计算机端口号可达65535个,其中0-1023是公认端口号,即已经公认定义或为将要公认定义的软件保留的,而1024-65535是并没有公共定义的端口号,用户可以自己定义这些端口的作用。二、常用端口在...

    一、概述

    我们知道,一个计算机端口号可达65535个,其中0-1023是公认端口号,即已经公认定义或为将要公认定义的软件保留的,而1024-65535是并没有公共定义的端口号,用户可以自己定义这些端口的作用。

    二、常用端口

    在这里我记录了几个常用的端口的意义与作用:

    端口服务作用
    20、21FTPFTP服务器以及客户端所开放的端口,用于上传、下载。进行FTP文件传输中,客户端首先连接到FTP服务器的21端口,进行用户的认证,认证成功后,要传输文件时,服务器会开一个端口为20来进行传输数据文件。
    22SshPcAnywhere建立的TCP和这一端口的连接可能是为了寻找ssh。这一服务有许多弱点,如果配置成特定的模式,许多使用RSAREF库的版本就会有不少的漏洞存在。
    23Telnet远程登录,SSH的英文全称是Secure SHell。通过使用SSH,你可以把所有传输的数据进行加密,这样“中间人”这种攻击方式就不可能实现了,而且也能够防止DNS和IP欺骗。还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。SSH有很多功能,它既可以代替telnet,又可以为ftp、pop、甚至ppp提供一个安全的“通道”。
    25SMTPSMTP服务器所开放的端口,用于发送邮件。
    53DNS服务域名服务器(Domain Name Server)。在Internet上域名与IP地址之间是一一对应的,域名虽然便于人们记忆,但机器之间只能互相认识IP地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成,DNS就是进行域名解析的服务器。
    69Trival File Transfer许多服务器与bootp一起提供这项服务,便于从系统下载启动代码。它们也可用于系统写入文件。
    79Finger Server入侵者用于获得用户信息,查询操作系统,探测已知的缓冲区溢出错误,回应从自己机器到其他机器Finger扫描。
    80HTTP用于网页浏览。
    102Message transfer agent消息传输代理。Message transfer agent(MTA)-X.400 over TCP/IP。
    137、138、139NETBIOS Name Service其中137、138是UDP端口,当通过网上邻居传输文件时用这个端口。而139端口:通过这个端口进入的连接试图获得NetBIOS/SMB服务。这个协议被用于windows文件和打印机共享和SAMBA。还有WINS Regisrtation也用它。
    110SUN公司的RPC服务所有端口常见RPC服务有rpc.mountd、NFS、rpc.statd、rpc.csmd、rpc.ttybd、amd等
    113Authentication Service这是一个许多计算机上运行的协议,用于鉴别TCP连接的用户。使用标准的这种服务可以获得许多计算机的信息。但是它可作为许多服务的记录器,尤其是FTP、POP、IMAP、SMTP和IRC等服务。通常如果有许多客户通过防火墙访问这些服务,将会看到许多这个端口的连接请求。记住,如果阻断这个端口客户端会感觉到在防火墙另一边与E-MAIL服务器的缓慢连接。许多防火墙支持TCP连接的阻断过程中发回RST。这将会停止缓慢的连接。
    119Network News Transfer ProtocolNEWS新闻组传输协议,承载USENET通信。这个端口的连接通常是人们在寻找USENET服务器。多数ISP限制,只有他们的客户才能访问他们的新闻组服务器。打开新闻组服务器将允许发/读任何人的帖子,访问被限制的新闻组服务器,匿名发帖或发送SPAM。
    161SNMPSNMP允许远程管理设备。所有配置和运行信息的储存在数据库中,通过SNMP可获得这些信息。
    443Https网页浏览端口,能提供加密和通过安全端口传输的另一种HTTP。
    3389windows远程终端windows远程终端
    8080WWW代理服务8080端口同80端口,是被用于WWW代理服务的,可以实现网页浏览,经常在访问某个网站或使用代理服务器的时候,会加上“:8080”。
    展开全文
  • 端口扫描实验报告

    2013-12-21 13:30:56
    端口扫描 设计并实现一个端口扫描程序,检测某个IP或某段IP的计算机的端口工作情况。
  • Windows网络编程之端口扫描实验

    千次阅读 2017-04-08 22:38:42
    在“计算机网络”课程中,我们知道完成一次TCP 连接需要完成三次握手才能建立。端 口扫描正是利用了这个原理,通过假冒正常的连接过程,依次向目标主机的各个端口发送连 接请求,并根据目标主机的应答情况判断目标...

    实验三 端口扫描实验

    1 实验类型
    验证型实验
    2 实验目的
    1.了解端口扫描的基本概念和工作原理;
    3 背景知识
    1. 端口扫描原理
    在“计算机网络”课程中,我们知道完成一次TCP 连接需要完成三次握手才能建立。端
    口扫描正是利用了这个原理,通过假冒正常的连接过程,依次向目标主机的各个端口发送连
    接请求,并根据目标主机的应答情况判断目标主机端口的开放情况,从而分析并对一些重要
    端口实施攻击。
    端口扫描的方式有两种,一种称为完整扫描,一次连接过程如下图所示:
    完整扫描连接过程示意图
    另一种扫描方式称为半开扫描,出于欺骗的目的,半开扫描在收到服务端的应答信号(SYN+ACK)后,不再发送响应信号(ACK)。一次连接过程如下图所示:
    这里写图片描述
    半开扫描连接过程示意图
    这里写图片描述
    4 实验内容
    1、编写一个利用全连接的端口扫描程序,能显示目标主机的端口开放情况。要求能在命令
    行输入要扫描的目标主机和端口范围。比如:scan ... nnnn-mmmm。
    代码如下:

    #include<stdio.h>
    #include<WINSOCK2.H>
    #include<string.h>
    #include<iphlpapi.h>
    #pragma comment(lib,"WS2_32.lib")
    int main(){
        WSADATA WSAData;
        sockaddr_in addr; //用来创建socket的结构体
        char IpAddress[100]; //待扫描的主机IP地址
        char startPort[10],endPort[10]; //开始和结束的端口号
        printf("请输入要扫描的主机IP地址:");
        gets(IpAddress);
        printf("请输入开始扫描的端口号:");
        gets(startPort);
        printf("请输入开始结束的端口号:");
        gets(endPort);
    
        if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0){ //初始化Winsock2.2
              printf("无法完成初始化...");
              return 0;
        }
        addr.sin_family=AF_INET;
        addr.sin_addr.S_un.S_addr=inet_addr(IpAddress); //将点分十进制的IP地址转换为网络字节序
        for(int i=atoi(startPort);i<=atoi(endPort);i++){ //atoi函数将字符串型端口转换为int型的值
            SOCKET s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//和每一个端口建立相关的socket,用于TCP连接
            if(s==INVALID_SOCKET){  //若端口建立失败,则程序结束
                printf("建立Socket失败,错误代码:%d",WSAGetLastError());  
                return 0;
            }
            addr.sin_port=(htons(i));//将端口设置为遍历的每一个端口,用于TCP连接
            if((connect(s,(sockaddr*)&addr,sizeof(sockaddr)))==-1){
                   printf("端口关闭,端口号为:%d\n",i);
            }else{
                          printf("端口开启,端口号为:%d\n",i);
            }
            closesocket(s); //得到端口是否开启后关闭socket
        }
        if(WSACleanup()==SOCKET_ERROR){
               printf("WSACleanUp出错!!!");
        }  //做一些清除工作
        system("pause");
        return 0;
    }

    实验结果:
    这里写图片描述

    以上代码效率非常低,提高效率可以通过多开几个线程来同时扫描。多线程下的扫描这里就不写了,下面把相关的函数放在下面,可以字节动手写下:

    在windows下,我们可以调用SDK win32 api来编写多线程的程序,下面就此简单的讲一下:
    创建线程的函数
    代码如下:
    HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
    SIZE_T dwStackSize, // initial stack size
    LPTHREAD_START_ROUTINE lpStartAddress, // thread function
    LPVOID lpParameter, // thread argument
    DWORD dwCreationFlags, // creation option
    LPDWORD lpThreadId // thread identifier
    );
    在这里我们只用到了第三个和第四个参数,第三个参数传递了一个函数的地址,也是我们要指定的新的线程,第四个参数是传给新线程的参数指针。eg1:

    复制代码 代码如下:

    #include <iostream>
    #include <windows.h>
    using namespace std;
    DWORD WINAPI Fun(LPVOID lpParamter)
    {
          while(1) { cout<<"Fun display!"<<endl; }
    }
    int main()
    {
        HANDLE hThread = CreateThread(NULL, 0, Fun, NULL, 0, NULL);
        CloseHandle(hThread);
        while(1) { cout<<"main display!"<<endl;  }
        return 0;
    }

    我们可以看到主线程(main函数)和我们自己的线程(Fun函数)是随机地交替执行的,但是两个线程输出太快,使我们很难看清楚,我们可以使用函数
    VOID Sleep(
    DWORD dwMilliseconds // sleep time
    );
    来暂停线程的执行,dwMilliseconds表示千分之一秒,所以Sleep(1000);表示暂停1秒
    eg2:
    复制代码 代码如下:

    #include <iostream>
    #include <windows.h>
    using namespace std;
    DWORD WINAPI Fun(LPVOID lpParamter)
    {   
          while(1) { cout<<"Fun display!"<<endl; Sleep(1000);}
    }
    int main()
    {
          HANDLE hThread = CreateThread(NULL, 0, Fun, NULL, 0, NULL);
          CloseHandle(hThread);
          while(1) { cout<<"main display!"<<endl;  Sleep(2000);}
          return 0;
    }

    执行上述代码,这次我们可以清楚地看到在屏幕上交错地输出Fun display!和main display!,我们发现这两个函数确实是并发运行的,细心的读者可能会发现我们的程序是每当Fun函数和main函数输出内容后就会输出换行,但是我们看到的确是有的时候程序输出换行了,有的时候确没有输出换行,甚至有的时候是输出两个换行。这是怎么回事?下面我们把程序改一下看看:
    eg3:
    代码如下:

    #include <iostream>
    #include <windows.h>
    using namespace std;
    DWORD WINAPI Fun(LPVOID lpParamter)
    {
          while(1) { cout<<"Fun display!\n"; Sleep(1000);}
    }
    int main()
    {
          HANDLE hThread = CreateThread(NULL, 0, Fun, NULL, 0, NULL);
          CloseHandle(hThread);
          while(1) { cout<<"main display!\n";  Sleep(2000);}
          return 0;
    }

    我们再次运行这个程序,我们发现这时候正如我们预期的,正确地输出了我们想要输出的内容并且格式也是正确的。下面我就来讲一下此前我们的程序为什么没有正确的运行。多线程的程序时并发地运行的,多个线程之间如果公用了一些资源的话,我们并不能保证这些资源都能正确地被利用,因为这个时候资源并不是独占的,举个例子吧:

    eg4:
    加入有一个资源 int a = 3
    有一个线程函数 selfAdd() 该函数是使 a += a;
    又有一个线程函数 selfSub() 该函数是使a -= a;
    我们假设上面两个线程正在并发欲行,如果selfAdd在执行的时候,我们的目的是想让a编程6,但此时selfSub得到了运行的机会,所以a变成了0,等到selfAdd的到执行的机会后,a += a ,但是此时a确是0,并没有如我们所预期的那样的到6,我们回到前面EG2,在这里,我们可以把屏幕看成是一个资源,这个资源被两个线程所共用,加入当Fun函数输出了Fun display!后,将要输出endl(也就是清空缓冲区并换行,在这里我们可以不用理解什么事缓冲区),但此时main函数确得到了运行的机会,此时Fun函数还没有来得及输出换行就把CPU让给了main函数,而这时main函数就直接在Fun display!后输出main display!,至于为什么有的时候程序会连续输出两个换行,读者可以采用同样的分析方法来分析,在这里我就不多讲了,留给读者自己思考了。
    那么为什么我们把eg2改成eg3就可以正确的运行呢?原因在于,多个线程虽然是并发运行的,但是有一些操作是必须一气呵成的,不允许打断的,所以我们看到eg2和eg3的运行结果是不一样的。
    那么,是不是eg2的代码我们就不可以让它正确的运行呢?答案当然是否,下面我就来讲一下怎样才能让eg2的代码可以正确运行。这涉及到多线程的同步问题。对于一个资源被多个线程共用会导致程序的混乱,我们的解决方法是只允许一个线程拥有对共享资源的独占,这样就能够解决上面的问题了。
    代码如下:
    HANDLE CreateMutex(
    LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD
    BOOL bInitialOwner, // initial owner
    LPCTSTR lpName // object name
    );

    该函数用于创造一个独占资源,第一个参数我们没有使用,可以设为NULL,第二个参数指定该资源初始是否归属创建它的进程,第三个参数指定资源的名称。
    代码如下:

    HANDLE hMutex = CreateMutex(NULL,TRUE,”screen”);这条语句创造了一个名为screen并且归属于创建它的进程的资源
    代码如下:
    BOOL ReleaseMutex(
    HANDLE hMutex // handle to mutex
    );
    该函数用于释放一个独占资源,进程一旦释放该资源,该资源就不再属于它了,如果还要用到,需要重新申请得到该资源。申请资源的函数如下
    代码如下:
    DWORD WaitForSingleObject(
    HANDLE hHandle, // handle to object
    DWORD dwMilliseconds // time-out interval
    );

    第一个参数指定所申请的资源的句柄,第二个参数一般指定为INFINITE,表示如果没有申请到资源就一直等待该资源,如果指定为0,表示一旦得不到资源就返回,也可以具体地指定等待多久才返回,单位是千分之一秒。好了,该到我们来解决eg2的问题的时候了,我们可以把eg2做一些修改,如下
    eg5:
    代码如下:

    #include <iostream>
    #include <windows.h>
    using namespace std;
    HANDLE hMutex;
    DWORD WINAPI Fun(LPVOID lpParamter)
    {
           while(1) {
                     WaitForSingleObject(hMutex, INFINITE);
                     cout<<"Fun display!"<<endl;
                     Sleep(1000);
                     ReleaseMutex(hMutex);
            }
      }
    int main()
    {
          HANDLE hThread = CreateThread(NULL, 0, Fun, NULL, 0, NULL);
          hMutex = CreateMutex(NULL, FALSE, "screen");
          CloseHandle(hThread);
          while(1) {
                   WaitForSingleObject(hMutex, INFINITE);
                   cout<<"main display!"<<endl; 
                   Sleep(2000);
                   ReleaseMutex(hMutex);
          }
          return 0;
    }
    展开全文
  • 端口扫描

    2014-07-27 23:30:24
    端口扫描器通过选用远程TCP/IP协议不同的端口的服务,记录目标计算机端口给予回答的方法,可以收集到很多关于目标计算机的各种有用信息(比如是否有端口在侦听,是否允许匿名登录,是否有可写的FTP目录,是否能用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 36,976
精华内容 14,790
关键字:

计算机网络端口扫描