基于Scapy库与线程池技术的并发TCP SYN半开扫描算法研究及实现

2024-03-13 09:36

本文主要是介绍基于Scapy库与线程池技术的并发TCP SYN半开扫描算法研究及实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

现了一个基于Python的TCP SYN扫描工具,采用Scapy库构造和解析网络报文,并采用线程池技术提高扫描效率。

实现原理

TCP SYN扫描的原理是利用了TCP连接建立过程中的三次握手特性,以半开连接(Half-open scanning)的方式探测目标主机的服务端口是否开放。具体步骤如下:

  1. 三次握手过程:
  • 在正常情况下,客户端(即扫描器)发起一个TCP连接时,会发送一个SYN(同步序列编号)报文到服务器。
  • 服务器接收到SYN报文后,如果该端口处于监听状态,则会回复一个SYN+ACK(同步并确认)报文作为回应。
  • 客户端在接收到SYN+ACK之后,通常会回复一个ACK(确认)报文完成三次握手,然后双方就可以开始传输数据。
  1. SYN扫描技术:
  • 在TCP SYN扫描中,扫描器模拟正常的连接请求,向目标主机和指定端口发送一个SYN报文。
  • 如果目标端口是开放的,它会返回一个SYN+ACK报文;若端口未打开或被防火墙阻止,则会返回一个RST(复位)报文。
  • 但是,不同于正常的连接建立过程,扫描器在接收到SYN+ACK报文后,并不会继续完成第三次握手(即不发送ACK),而是直接丢弃这个连接尝试,因此不会建立起完整的连接。
  • 根据收到的响应类型,扫描器就能判断端口的状态:收到SYN+ACK则认为端口开放,收到RST则认为端口关闭或不可达。

运行流程

本TCP SYN扫描工具的执行过程如下:

  1. 初始化阶段:
  • 引入必要的Python库,包括scapy.all、argparse、logging以及concurrent.futures.ThreadPoolExecutor。
  • 设置Scapy运行时日志级别为ERROR,以减少无关输出。
  • 定义命令行参数解析器argparse.ArgumentParser,用于接收用户输入的被扫描主机IP地址(通过"-H"或"–host"指定)和端口范围(通过"-p"或"–ports"指定,默认值为"1-1024")。
  1. 参数处理阶段:
  • 解析用户输入的参数,若同时提供了主机IP地址和端口范围,则将端口范围字符串按’-'分割后转化为整数列表,并生成相应的端口号序列。
  1. 扫描准备阶段:
  • 函数tcpSynScan_single(target, port)针对单个目标端口进行TCP SYN半打开扫描。该函数构造一个SYN标志设置为“S”的TCP数据包并发送至指定主机和端口,根据返回的数据包判断端口状态。
  1. 并发扫描阶段:
  • 函数tcpSynScan_parallel(target, ports)利用线程池ThreadPoolExecutor实现对目标主机多个端口的同时扫描。
  • 将目标主机IP地址与待扫描的端口列表作为参数传递给executor.map()函数,它会并发地调用tcpSynScan_single对每个端口执行扫描操作。
  • 扫描结果以布尔值形式存储在results变量中,对应表示各个端口是否开放。
  1. 结果展示阶段:
  • 使用zip(ports, results)将扫描结果与原始端口号配对,然后循环遍历这些配对信息。
  • 对于检测到开放的端口,在控制台输出格式化的信息,内容包括:扫描主机IP地址、端口号以及其状态(开放或关闭)。

综上所述,整个项目实现了从参数接收、并发扫描到结果显示的完整TCP SYN扫描流程,有效地提升了扫描效率且保持了对目标主机端口状态准确判断的能力。

代码实现

执行单个端口的TCP SYN扫描。
tcpSynScan_single(target, port):针对单个目标端口执行TCP SYN半打开扫描技术。通过发送一个SYN标志设置为“S”的TCP报文至指定IP地址的目标主机和端口,并监测其响应。若目标端口对SYN报文返回SYN+ACK(表示端口开放),则函数返回True;否则,若收到RST(复位)标志或无响应,则认为端口关闭,函数返回False。

def tcpSynScan_single(target, port):"""执行单个端口的TCP SYN扫描。参数:- target: 目标主机的IP地址。- port: 要扫描的端口号。返回值:- 如果端口对SYN报文响应为开放(SA),则返回True;- 如果端口响应为关闭(RST),或无响应,则返回False。"""send = sr1(IP(dst=target) / TCP(dport=port, flags="S"), timeout=2, verbose=0)if (send is None):return Falseelif send.haslayer("TCP"):if send["TCP"].flags == "SA":return Trueelif send["TCP"].flags in ["RA", "R"]:  # RST响应return Falseelse:return False

并行执行TCP SYN扫描。
tcpSynScan_parallel(target, ports):在给定的目标主机上并发地对多个端口执行tcpSynScan_single函数,利用线程池ThreadPoolExecutor以优化资源分配与提高扫描速度。该函数接收一个IP地址和端口列表作为输入参数,扫描完成后将打印出所有开放端口的相关信息。


def tcpSynScan_parallel(target, ports):"""并行执行TCP SYN扫描。参数:- target: 目标主机的IP地址。- ports: 要扫描的端口列表。说明:使用线程池并发地对多个端口执行tcpSynScan_single函数。"""with ThreadPoolExecutor(max_workers=50) as executor:  results = executor.map(tcpSynScan_single, [target] * len(ports), ports)for port, is_open in zip(ports, results):status = "开放" if is_open else "关闭"if status == "开放":print("[+] 扫描主机: %-13s 端口: %-5s %s" % (target, port, status))

参数设置

if __name__ == "__main__":logging.getLogger("scapy.runtime").setLevel(logging.ERROR)parser = argparse.ArgumentParser(description='TCP SYN扫描工具')parser.add_argument("-H", "--host", dest="host", help="输入一个被扫描主机IP地址")parser.add_argument("-p", "--ports", dest="ports", default="1-1024", help="输入端口范围,默认为1-1024")args = parser.parse_args()if args.host and args.ports:start, end = map(int, args.ports.split('-'))ports = list(range(start, end + 1))tcpSynScan_parallel(args.host, ports)else:parser.print_help()

优化建议

  1. 线程池参数调整: 目前程序设置的线程池最大工作线程数为50,这一数值可以根据目标主机的网络状况、系统资源和实际需求进行动态调整。可以通过实验评估不同数量的工作线程对扫描效率和系统负载的影响,选择最佳线程数。

  2. 超时时间优化: 代码中sr1()函数的超时时间为2秒,这个值可能不足以应对所有网络环境下的响应情况,可以考虑增加一个配置选项允许用户自定义超时时间,以适应不同的网络延迟。

  3. 错误处理与重试机制: 在网络不稳定或目标主机有防护措施的情况下,单次SYN请求可能会失败。为了提高扫描稳定性,可以添加重试机制,当某端口在首次扫描无响应或者收到非预期响应时,在设定次数内重新尝试发送SYN报文。

  4. 结果存储与展示: 当扫描大量端口时,仅打印出开放端口的信息可能不够全面。可将扫描结果保存至文件,便于后续分析。同时,可考虑提供更详细的结果输出选项,如显示扫描进度、总扫描耗时等信息。

  5. 资源消耗控制: 考虑到大规模扫描可能会导致系统资源(CPU、内存、网络带宽)过度消耗,应引入资源限制策略,例如,根据系统的可用资源动态调节线程池大小,或在检测到系统资源紧张时暂停部分扫描任务。

  6. 合法性检查与合规性: 实施网络扫描前,确保符合当地法律法规和网络使用政策,并对目标IP地址进行合法性验证,防止误操作或其他法律风险。

  7. 性能监控与调优: 可以添加性能监控模块,实时记录并分析扫描过程中的各项指标,包括线程执行情况、CPU和内存占用、网络流量等,为进一步优化提供数据支持。

这篇关于基于Scapy库与线程池技术的并发TCP SYN半开扫描算法研究及实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/804410

相关文章

Java实现视频格式转换的完整指南

《Java实现视频格式转换的完整指南》在Java中实现视频格式的转换,通常需要借助第三方工具或库,因为视频的编解码操作复杂且性能需求较高,以下是实现视频格式转换的常用方法和步骤,需要的朋友可以参考下... 目录核心思路方法一:通过调用 FFmpeg 命令步骤示例代码说明优点方法二:使用 Jaffree(FF

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

Java实现图片淡入淡出效果

《Java实现图片淡入淡出效果》在现代图形用户界面和游戏开发中,**图片淡入淡出(FadeIn/Out)**是一种常见且实用的视觉过渡效果,它可以用于启动画面、场景切换、轮播图、提示框弹出等场景,通过... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细

Python实现获取带合并单元格的表格数据

《Python实现获取带合并单元格的表格数据》由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,所以本文我们就来聊聊如何使用Python实现获取带合并单元格的表格数据吧... 由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,现将将封装成类,并通过调用list_exc

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs

Java进行日期解析与格式化的实现代码

《Java进行日期解析与格式化的实现代码》使用Java搭配ApacheCommonsLang3和Natty库,可以实现灵活高效的日期解析与格式化,本文将通过相关示例为大家讲讲具体的实践操作,需要的可以... 目录一、背景二、依赖介绍1. Apache Commons Lang32. Natty三、核心实现代

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

SpringBoot实现接口数据加解密的三种实战方案

《SpringBoot实现接口数据加解密的三种实战方案》在金融支付、用户隐私信息传输等场景中,接口数据若以明文传输,极易被中间人攻击窃取,SpringBoot提供了多种优雅的加解密实现方案,本文将从原... 目录一、为什么需要接口数据加解密?二、核心加解密算法选择1. 对称加密(AES)2. 非对称加密(R

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

python通过curl实现访问deepseek的API

《python通过curl实现访问deepseek的API》这篇文章主要为大家详细介绍了python如何通过curl实现访问deepseek的API,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编... API申请和充值下面是deepeek的API网站https://platform.deepsee