端口扫描的方式
-
TCP全连接扫描:模拟客户端发起TCP连接的过程,执行完整的三次握手来确定端口是否开放。扫描器会调用操作系统级别的
connect()
函数来尝试与目标主机的某个端口建立连接。如果端口开放并监听连接,目标主机将回应一个ACK确认数据包,从而建立起连接。这种方式相对容易被防火墙和IDS(入侵检测系统)捕获。成功建立连接,则为open;收到RST则为close。
eg. telnet IP port,nc
-
TCP半连接扫描:又称SYN扫描,是为了减少痕迹和避免引起警报而设计的更隐蔽的扫描方式。扫描器只发起TCP连接的第一次握手,即发送一个SYN数据包。如果目标端口开放,它会回应一个SYN+ACK数据包。这时,并不会完成第三次握手(即不发送ACK),源ip会发送一个RST(复位)数据包来终止连接。这样就不需要建立完整的连接,降低了被检测的风险。
源ip收到ACK+SYN则为open;收到RST则为close。
eg. masscan 默认SYN探测;socket;nmap默认SYN探测;很多扫描器都是这种方式,所以很多IDS会检测这项
-
UDP扫描:发送空的(没有数据)UDP报头到每个目标端口。一般如果返回ICMP port unreachable说明端口是关闭的,而如果没有回应或有回应(有些UDP服务是有回应的但不常见)则认为是open,但由于UDP的不可靠性,无法判断报文段是丢了还是没有回应,所以一般扫描器会发送多次,然后根据结果再判断。这也是为什么UDP扫描这么慢的原因。
-
秘密扫描:如FIN扫描、Xmas Tree扫描、Null扫描等,这些扫描方式通过发送非标准的TCP数据包(如只有FIN标志位的包或多个标志位同时置位的包)来探测端口状态,这些扫描方式的目的在于尽量减少在目标主机上产生的日志信息,以及避免触发防火墙规则或入侵检测系统的警报。
如果没有响应,说明端口开放;如果返回了RST,说明端口关闭;返回ICMP ERROR,则说明端口被过滤了。
端口扫描
针对单个端口扫描
使用Python的socket库的connect()方法进行tcp扫描 原理:指定IP和端口号,连接到特定主机对应的远程socket,连接失败会抛出timeout错误,通过判断是否连接成功来判断端口是否开放。
-
首先使用
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
建立一个基于网络并且使用TCP协议的套接字; -
然后使用connect()尝试建立连接,需要的参数为IP和端口号;
-
最后根据判断返回的结果是成功还是超时,来判断端口是否开放。
代码示例:
|
|
批量端口扫描
-
可以保存一批端口作为默认端口,要确定哪些作为默认端口:常用的,比如3389、3306等等,以及在网上看别人工具定义的默认端口
-
制定端口范围进行扫描
-
一个个扫,但是网络I/O非常耗时,程序会耗费很多时间在等待上
-
利用协程进行提效:在一个协程进入IO等待时,会自动切换到其他协程继续执行,也就是最大化的利用了IO等待时间,这个过程一直都是单线程,只是程序在一个协程进入等待后切换到另一个协程给CPU处理,而对于CPU来说则一直是同一个程序在给它发任务,CPU是感受不到区别的。
我们每扫一个端口都要建立一次连接,而每次建立连接都会有一次等待,那我们就把每一个要建立的连接都放到一个协程里,在一个连接也就是协程进入IO等待后,系统会自动切换去建立下一个连接,这样效率就会大大提升,这个切换时自动的,完全不需要我们去做什么。
python中可以使用gevent
库来实现协程
- 使用
gevent.spawn(start_scan)
创建协程 - 使用
gevent.join()
或者gevent.joinall()
执行协程 - 协程的数量等于我们要扫描的次数。
- 创建队列来保存要扫描的IP和port,根据队列长度创建协程,之后每个协程在执行任务的时候就把队列里的信息提取出来一个,当把队列空了的时候,任务也就处理完了。
- 如果有端口开着但是没扫到,可以考虑增长超时时间
nmap不同扫描模式的说明
-sT
:全连接扫描,Nmap会调用系统底层的connect与目标端口建立连接-sS
:半连接扫描(nmap默认SYN探测)-sN
:null扫描,标志位全为0-sF
:FIN扫描,标志位FIN=1,其余为0-sA
:ACK扫描,不能用来确定端口开放状态,但是可以用来映射防火墙规则集,确定是否有状态监测防火墙,以及对哪些端口进行了过滤。当扫描被过滤系统时,无论是开启或关闭的端口都会返回RST数据包,则Nmap会标记为 unfiltered ;若端口没有响应包或收到ICMP不可达报错,则标记为 filtered。-sU
:UDP扫描-sV
:探测服务版本-A
:全面扫描-O
:目标主机的系统版本-Pn
:跳过主机发现,默认目标主机在线-n
:不进行反向DNS解析;反向DNS解析会解析出主机名称,可以推断这个主机的用途;比较耗时