使用python scapy模块进行端口扫描
环境:
发包机器ubuntu(ip:192.168.0.109),目标机器win7(ip:192.168.0.108),使用kali中的wireshark进行抓包
TCP扫描
TCP(Transmission Control Protocol 传输控制协议)它工作在网络osi模型中的第四层。
所以我们在判断一个端口是否开放时我们可对目标端口进行一次tcp的连接
使用TCP连接时我们用到的是套接字的这个模型,不得不说py创建的套接字真是快,之前使用过C编写套接字模型(😭)。
创建一个套接字,指定协议,指定TCP流。之后直接connect端口,看看成不成成功了。
def Port_scan(Ip, port):
src_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
src_socket.settimeout(3)
try:
if src_socket.connect_ex((Ip,port)) == 0:
print(f"the {Ip} port {port} is open!")
except Exception as e:
print(f"the {Ip} port {port} is not open")
print(e)
finally:
src_socket.close()
在对目标端口 80进行探测以后 我们使用wireshark 进行抓包观察。从第四帧开始可以看到完成了三次握手,src(主机A) dst(主机B) 我们可以看到A向B端口(80)发送了一个syn报文, 之后B应答, 之后A应答接B收到以后双方建立起连接。
顺便在说说tcp的四次挥手。首先时A向B发送FIN报文,
此时A处于FIN_WAIT1状态,B收到FIN之后发送给A ACK报文,之后处于CLOSE_WAIT状态,此时B也同样的发送一个FIN报文此时B处于LAST_ACK状态,客户端收到FIN以后发送ACK给B,之后会进入CLOSE状态
当我们建立不起来连接时,我们可以初步的判断目标端口不开放
SYN扫描
但是使用tcp连接做为检测时因为完成了一次完整的tcp连接所以会在被检测机子上留下连接日志。所以我们可以使用另外一种检测方式syn扫描,syn扫秒是完成了tcp三次握手中的前两步,首先我们向B发送SYN报文,B回应,之后A发送拒绝连接的请求。
相比于上面的tcp扫描SYN扫描需要我们自己构造一个数据包,使用scapy中的sr1()来发包,虽然sr1()的特点是发送并且等待返回包,sr()函数也类似发包加收包。
需要注意的是我们在构造包时packet 那一行中 IP()/TCP()代表的时网络osi模型中的层次关系,不可混乱。判断是否收收到了第二次握手,第二次握手中B给A发送的报文中我们可以看到Flags为0x012 , 为十进制的18我们可以用这一条件判断是否收到了返回包。
def scan(ip,port):
try:
packet = IP(dst=ip)/TCP(dport=port, flags="S") # 构造标志位为syn的数据包
result = sr1(packet,timeout=0.5, verbose=0)
if int(result[TCP].flags) == 18:
time.sleep(0.1)
print(ip, "TCP" , port, "open")
except:
print(ip, "TCP" , port, "not open")
使用wireshark抓包可以清楚的看到了应答的过程