tcp扫描器实现原理

一、TCP

常用的端口扫描方式有以下三种:

1.connect扫描

我们知道,常见的TCP的socket实现过程为

更本质的连接和结束的过程是如下这个样子的:


从上面两个图我们可以看出来目标主机的一个端口如果是监听状态(LISTENING或者LINSTEN),那么当我connect目标主机时就能成功,否则说明端口是关闭的。

优点: 编程简单,是需要一个API connect(),比较可靠,因为TCP是可靠协议,当丢包的时候,会重传SYN帧。

缺点: 正因为TCP的可靠性,所以当端口不存在的时候,源主机会不断尝试发SYN帧企图得到ack的应答,多次尝试后才会放弃,因此造成了扫描的时间较长。并且,connect的扫描方式可能较容易被目标主机发现。

2.SYN扫描

上面说到出去开放状态的端口,是在等待其它主机发送SYN帧,所以SYN扫描的原理就是想目标端口发送SUN数据帧,如果源主机收到SYN+ACK数据包,寿命此端口开放,如果收到RST说明此端口关闭。由于SYN扫描并不会完成TCP三次握手过程,所以又叫半开放扫描。

优点: 速度快;如果不被防火墙过滤的话,基本都能收到应答包。

缺点: 扫描行为容易被发现;因为是自己攒包发,是在ip层的,因此不可靠,可能会丢包;实现起来比connect稍复杂。

3.FIN扫描

根据上述四次挥手过程,主动结束的一方会发送FIN帧。当我们发送FIN帧给一个非监听的端口时,会有RST应答,反之,发给一个正在监听的端口时,不会有任何回应。

优点: 隐蔽性好;速度快。

缺点: 只能用于linux系统,windows系统下无效,在windows下,无论端口是否监听,都将回应RST帧,造成无法判断;不可靠,当收不到应答包时,不确定是端口在监听,还是丢包了。

二、UDP

 常见的方式有UDP recvfrom扫描,UDP ICMP端口不可达扫描,我采用的是后者,也就是,给一个端口发送UDP报文,如果端口是开放的,则没有响应,如果端口是关闭的,对方会回复一个ICMP端口不可达报文(对应ICMP首部前两个字段:类型3 代码3,ICMP详见ping那篇文章),

优点:linux windows都能用

缺点:也是不可靠的,因为返回的是错误信息,所以速度相对于TCP的FIN,SYN扫描要慢一些,如果发送的UDP包太快了,回应的ICMP包会出现大量丢失的现象。

三、随便玩玩

在开始编程前可以对端口的开放与否有个感性的认识。

查看当前主机的开放端口可以使用netstat命令。

linux下查看TCP的监听端口:netstat -na -t TCP | grep LISTEN (测试环境 ubuntu 11.04)

windows下查看TCP的监听端口:netstat -na -p TCP | findstr LISTENING (测试环境 winXP)

linux下下扫描端口可以使用端口扫描工具nmap,有多种扫描方式,这里列举几个常用的:

仅进行ping扫描,打印出对扫描做出响应的主机,不做进一步测试(如端口扫描或者操作系统探测):

nmap -sP 192.168.1.0/24

使用频率最高的扫描选项:SYN扫描,又称为半开放扫描,它不打开一个完全的TCP连接,执行得很快:

nmap -sS 192.168.1.0/24

当SYN扫描不能用时,TCP Connect()扫描就是默认的TCP扫描:

nmap -sT 192.168.1.0/24

原文地址:https://www.cnblogs.com/ruiy/p/14278260.html