开放端口扫描方式

发布时间:2025-12-09 11:48:23 浏览次数:1

端口扫描器

参考:https://www.imooc.com/article/286803

常见的端口扫描类型

1. TCP 连接扫描2. TCP SYN 扫描(也称为半开放扫描或stealth扫描)3. TCP 圣诞树(Xmas Tree)扫描4. TCP FIN 扫描5. TCP 空扫描(Null)6. TCP ACK 扫描7. TCP 窗口扫描8. UDP 扫描

1、TCP连接扫描

若客户端想要连接服务器80端口时,会先发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器(本例中为80端口)。如果端口是开放的,则服务器会接受这个连接并返回一个带有 SYN 和 ACK 标识的数据包给客户端。随后客户端会返回带有 ACK 和 RST 标识的数据包,此时客户端与服务器建立了连接。

  • 如果完成一次三次握手,那么服务器上对应的端口肯定就是开放的。

  • 当客户端发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器后,如果服务器端返回一个带 RST 标识的数据包,则说明端口处于关闭状态

nmap的-sT模式
#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80tcp_connect_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)if(str(type(tcp_connect_scan_resp))==""):    print( "Closed")elif(tcp_connect_scan_resp.haslayer(TCP)):    if(tcp_connect_scan_resp.getlayer(TCP).flags == 0x12):        send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="AR"),timeout=10)# 全连接 AR => ACK+RST        print( "Open")elif (tcp_connect_scan_resp.getlayer(TCP).flags == 0x14):    print( "Closed")

2、TCP SYN 扫描

客户端向服务器发送一个带有 SYN 标识和端口号的数据包,这种技术主要用于躲避防火墙的检测。

  • 如果目标端口开发,则会返回带有 SYN 和 ACK 标识的 TCP 数据包。但是,这时客户端不会返回 RST+ACK 而是返回一个只带有 RST 标识的数据包。

  • 如果目标端口处于关闭状态,那么同之前一样,服务器会返回一个 RST 数据包

nmap的-sS模式
#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80stealth_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)if(str(type(stealth_scan_resp))==""):    print ("Filtered")elif(stealth_scan_resp.haslayer(TCP)):    if(stealth_scan_resp.getlayer(TCP).flags == 0x12):        send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="R"),timeout=10)# 连接 R==>RST        print( "Open")    elif (stealth_scan_resp.getlayer(TCP).flags == 0x14):        print ("Closed")elif(stealth_scan_resp.haslayer(ICMP)):    if(int(stealth_scan_resp.getlayer(ICMP).type)==3 and int(stealth_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):        print ("Filtered")

3、TCP 圣诞树(Xmas Tree)扫描

在圣诞树扫描中,客户端会向服务器发送带有 PSH,FIN,URG 标识和端口号的数据包给服务器。

  • 如果目标端口是开放的,那么不会有任何来自服务器的回应。

  • 如果服务器返回了一个带有 RST 标识的 TCP 数据包,那么说明端口处于关闭状态。

  • 如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 状态码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定是否处于开放状态。

nmap -sX模式
#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80xmas_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="FPU"),timeout=10)if (str(type(xmas_scan_resp))==""):    print( "Open|Filtered")elif(xmas_scan_resp.haslayer(TCP)):    if(xmas_scan_resp.getlayer(TCP).flags == 0x14):        print( "Closed")elif(xmas_scan_resp.haslayer(ICMP)):    if(int(xmas_scan_resp.getlayer(ICMP).type)==3 and int(xmas_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):        print ("Filtered")

4、FIN扫描

FIN 扫描会向服务器发送带有 FIN 标识和端口号的 TCP 数据包。

  • 如果没有服务器端回应则说明端口开放。

  • 如果服务器返回一个 RST 数据包,则说明目标端口是关闭的。

  • 如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 代码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定端口状态。

nmap -sF模式
#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80fin_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="F"),timeout=10)if (str(type(fin_scan_resp))==""):    print ("Open|Filtered")elif(fin_scan_resp.haslayer(TCP)):    if(fin_scan_resp.getlayer(TCP).flags == 0x14):        print ("Closed")elif(fin_scan_resp.haslayer(ICMP)):    if(int(fin_scan_resp.getlayer(ICMP).type)==3 and int(fin_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):        print ("Filtered")

5、TCP 空扫描(Null)

在空扫描中,客户端发出的 TCP 数据包仅仅只会包含端口号而不会有其他任何的标识信息。

  • 如果目标端口是开放的则不会回复任何信息。

  • 如果服务器返回了一个 RST 数据包,则说明目标端口是关闭的。

  • 如果返回 ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明端口被服务器过滤了。

nmap -sN模式
#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80null_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags=""),timeout=10)if (str(type(null_scan_resp))==""):    print( "Open|Filtered")elif(null_scan_resp.haslayer(TCP)):    if(null_scan_resp.getlayer(TCP).flags == 0x14):        print ("Closed")elif(null_scan_resp.haslayer(ICMP)):    if(int(null_scan_resp.getlayer(ICMP).type)==3 and int(null_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):        print ("Filtered")

6、TCP ACK扫描

ACK 扫描不是用于发现端口开启或关闭状态的,而是用于发现服务器上是否存在有状态防火墙的。它的结果只能说明端口是否被过滤。再次强调,ACK 扫描不能发现端口是否处于开启或关闭状态。

  • 客户端会发送一个带有 ACK 标识和端口号的数据包给服务器。如果服务器返回一个带有 RST 标识的 TCP 数据包,则说明端口没有被过滤,不存在状态防火墙。

  • 如果目标服务器没有任何回应或者返回ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明端口被过滤且存在状态防火墙。

nmap -sA模式
#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80ack_flag_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="A"),timeout=10)if (str(type(ack_flag_scan_resp))==""):    print ("Stateful firewall presentn(Filtered)")elif(ack_flag_scan_resp.haslayer(TCP)):    if(ack_flag_scan_resp.getlayer(TCP).flags == 0x4):        print ("No firewalln(Unfiltered)")elif(ack_flag_scan_resp.haslayer(ICMP)):    if(int(ack_flag_scan_resp.getlayer(ICMP).type)==3 and int(ack_flag_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):        print ("Stateful firewall presentn(Filtered)")

7、TCP窗口扫描

TCP 窗口扫描的流程同 ACK 扫描类似,同样是客户端向服务器发送一个带有 ACK 标识和端口号的 TCP 数据包,但是这种扫描能够用于发现目标服务器端口的状态。在 ACK 扫描中返回 RST 表明没有被过滤,但在窗口扫描中,当收到返回的 RST 数据包后,它会检查窗口大小的值。

  • 如果窗口大小的值是个非零值,则说明目标端口是开放的。

  • 如果返回的 RST 数据包中的窗口大小为0,则说明目标端口是关闭的。

nmap -sW模式
#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80window_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="A"),timeout=10)if (str(type(window_scan_resp))==""):    print( "No response")elif(window_scan_resp.haslayer(TCP)):    if(window_scan_resp.getlayer(TCP).window == 0):        print( "Closed")    elif(window_scan_resp.getlayer(TCP).window > 0):        print( "Open")

8、UDP扫描

TCP 是面向连接的协议,而UDP则是无连接的协议。

面向连接的协议会先在客户端和服务器之间建立通信信道,然后才会开始传输数据。如果客户端和服务器之间没有建立通信信道,则不会有任何产生任何通信数据。

无连接的协议则不会事先建立客户端和服务器之间的通信信道,只要客户端到服务器存在可用信道,就会假设目标是可达的然后向对方发送数据。

  • 客户端会向服务器发送一个带有端口号的 UDP 数据包。如果服务器回复了 UDP 数据包,则目标端口是开放的。

  • 如果服务器返回了一个 ICMP 目标不可达的错误和代码3,则意味着目标端口处于关闭状态。

  • 如果服务器返回一个 ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明目标端口被服务器过滤了。

  • 如果服务器没有任何相应客户端的 UDP 请求,则可以断定目标端口可能是开放或被过滤的,无法判断端口的最终状态。

#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=53dst_timeout=10def udp_scan(dst_ip,dst_port,dst_timeout):    udp_scan_resp = sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout)    if (str(type(udp_scan_resp))==""):        retrans = []        for count in range(0,3):            retrans.append(sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout))        for item in retrans:            if (str(type(item))!=""):                udp_scan(dst_ip,dst_port,dst_timeout)        return ("Open|Filtered")    elif (udp_scan_resp.haslayer(UDP)):        return( "Open")    elif(udp_scan_resp.haslayer(ICMP)):        if(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code)==3):            return( "Closed")        elif(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code) in [1,2,9,10,13]):            return( "Filtered")print udp_scan(dst_ip,dst_port,dst_timeout)
开放端口扫描
需要做网站?需要网络推广?欢迎咨询客户经理 13272073477