TCP全开扫描原理
端口开放:
1,主机A向主机B发送“SYN”请求
2,主机B收到主机A的请求,返回给主机A“SYN+ACK”响应
3,主机A收到来自主机B的响应,并回应给主机B“ACK”
端口不活跃:
端口关闭:
1,主机A向主机B发送“SYN”请求
2,主机B返回给主机A“RST”回应
目标主机处于非活跃状态或有防火墙:
1,主机A向主机B发送“SYN”请求
2,主机B没有任何回应
程序编写
from scapy.all import *
#目标主机ip地址
dst_ip = "192.168.72.2"
#随机自己主机的发送端口
src_port = RandShort()
#指定扫描目标80端口
dst_port = 80
#flag=S表示请求
packet_syn = IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S")
#发送数据包,并接受回应
response = sr1(packet_syn,timeout=1)
#判断回应是否为空
if(str(type(response))="<class 'NoneType'>"):
print("The port %s is closed" % (dst_port))
#判断回应的协议类型
elif(response.haslayer(TCP)):
#判断回应中的flag值是否为“SYN+ACK”
if(response.getlayer(TCP).flags == 0x12):
#接收回应中的ACK
seq1 = response.ack
#接收回应中seq,并对其加1
ack1 = response.seq+1
#构造ACK回应包
packet_ack = IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,seq=seq1,ack=ack1,flags=0x10)
send(packet_ack)
print("The port %s is Open" % (dst_port))
#判断回应中的flag值是否为“RST”
elif(response.getlayer(TCP).flags = 0x14):
print("The port %s is Closed" % dst_port)
运行结果:
拓展:
可以将发包和判断回应组合成一个函数,然后使用循环遍历端口号,加上多线程进行快速扫描。源码赞不提供,请读者自行开发。