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"</type '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中可以使用scapy库来实现端口扫描探测。scapy一个强大的网络包处理工具,可以用于构建、发送和解析网络数据包。 下面是使用scapy实现端口扫描探测的基本步骤: 1. 导入必要的模块和库: ```python from scapy.all import * import sys ``` 2. 定义一个函数来发送TCP SYN包并接收响应: ```python def scan_port(target_ip, port): src_port = RandShort() # 随机选择源端口号 response = sr1(IP(dst=target_ip)/TCP(sport=src_port, dport=port, flags="S"), timeout=1, verbose=0) if response is None: return "Closed" elif response.haslayer(TCP) and response.getlayer(TCP).flags == 0x12: send_rst = sr(IP(dst=target_ip)/TCP(sport=src_port, dport=port, flags="AR"), timeout=1, verbose=0) return "Open" elif response.haslayer(TCP) and response.getlayer(TCP).flags == 0x14: return "Closed" ``` 3. 定义一个函数来扫描指定范围的端口: ```python def scan_ports(target_ip, start_port, end_port): for port in range(start_port, end_port+1): result = scan_port(target_ip, port) print(f"Port {port}: {result}") ``` 4. 在主程序中调用函数进行端口扫描: ```python if __name__ == "__main__": target_ip = sys.argv[1] # 从命令行参数获取目标IP地址 start_port = int(sys.argv[2]) # 从命令行参数获取起始端口号 end_port = int(sys.argv[3]) # 从命令行参数获取结束端口号 scan_ports(target_ip, start_port, end_port) ``` 这样,你就可以通过运行Python脚本,并传入目标IP地址、起始端口号和结束端口号来实现端口扫描探测了。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值