scapy实现一个端口扫描器(基于tcp三次握手扫描)——简析

由头

上篇转载了一篇文章如何用Scapy写一个端口扫描器?,介绍了几种基于tcp协议扫描的端口扫描原理和实现的scapy代码,然而自己实践的时候,wireshark抓包发现基于tcp三次握手的扫描方式,并没有真正建立起连接,于是便有了此篇博客。

错误代码分析

错误的数据包流量抓取地址

在client进行第三次握手之前,客户端发送了一个rst包,直接拒绝了client进行的第三次握手。
群里的好友提供的思路是设置iptables,禁止linux内核发送rst包

iptables -A OUTPUT -p tcp –tcp–flags RST RST -d serverIP -j DROP

可是这样设置之后,虽然没有发送rst包了,第三次握手并未完成。
原因是,第三次握手用了一个新的端口,需要设置成第一次握手相同的端口,并设置ack、seq的值才可以完成三次握手。

#! /usr/bin/python

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *

dst_ip = "192.168.168.168"
src_port = RandShort()
dst_port=80

tcp_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)
        print "Open"
elif (tcp_connect_scan_resp.getlayer(TCP).flags == 0x14):
    print "Closed"'nonetype'>

正确的scapy脚本

#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *

dst_ip = "192.168.168.168"
client_port = 8888 
dst_port=80

second_server_response = sr1(IP(dst=dst_ip)/TCP(sport=8888,dport=dst_port,flags="S"),timeout=10)
third_client_seq   = second_server_response.ack;
third_client_ack   = second_server_response.seq+1;
if(str(type(second_server_response))==""):
    print "Closed"
elif(second_server_response.haslayer(TCP)):
    if(second_server_response.getlayer(TCP).flags == 0x12):
        send_rst = sr(IP(dst=dst_ip)/TCP(sport=8888,dport=dst_port,seq=third_client_seq,ack=third_client_ack,flags="A"),timeout=10)
        print "Open"
elif(second_server_response.getlayer(TCP).flags == 0x14):
    print "Closed"

正确的数据包

三次握手数据包

你可能感兴趣的:(python)