基于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实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2