《基于Scapy的综合性网络扫描与通信工具集解析》

news2025/2/3 12:49:12

在网络管理和安全评估中,网络扫描和通信是两个至关重要的环节。Python 的 Scapy 库因其强大的网络数据包处理能力,成为开发和实现这些功能的理想工具。本文将介绍一个基于 Scapy 编写的 Python 脚本,该脚本集成了 ARP 扫描、端口扫描以及 TCP 三次握手和简单聊天功能,为用户提供了一个多功能的网络工具集。

项目概述

Scapy 是一个功能强大的交互式数据包处理程序,允许用户发送、嗅探、解析和伪造网络数据包。通过 Scapy,开发者可以实现复杂的网络操作,如网络扫描、安全审计和网络通信。本文介绍的项目利用 Scapy 库,提供了一个命令行工具,支持 ARP 扫描、端口扫描以及 TCP 三次握手和简单聊天功能。

功能详解

1. ARP 扫描

ARP(地址解析协议)扫描用于检测局域网内活动的主机。通过发送 ARP 请求,ARP 扫描可以确定哪些 IP 地址对应的主机是在线的。

实现方式
  • 获取本地 MAC 地址。

  • 构造 ARP 请求包,发送给目标 IP 地址。

  • 接收并解析 ARP 响应,判断目标主机是否在线。

  • 输出在线主机的 IP 和 MAC 地址。

2. 端口扫描

端口扫描用于检测目标主机上开放的端口。通过发送 TCP SYN 包,端口扫描可以确定哪些端口处于开放状态。

实现方式
  • 构造 TCP SYN 包,发送给目标主机的指定端口。

  • 接收并解析 TCP 响应,判断端口是否开放。

  • 如果端口开放,发送 TCP RST 包关闭连接,避免对目标主机造成影响。

  • 输出开放的端口号。

3. TCP 三次握手及聊天

TCP 三次握手是建立可靠连接的基础。通过模拟 TCP 三次握手,用户可以与目标主机建立连接,并进行简单的聊天。

实现方式
  • 构造 TCP SYN 包,发送给目标主机的指定端口,等待 SYN/ACK 响应。

  • 收到 SYN/ACK 响应后,构造 TCP ACK 包,完成三次握手。

  • 进入聊天模式,接收用户输入的消息并发送给目标主机。

  • 接收并显示目标主机的响应。

  • 用户可以输入 exit 退出聊天。

代码结构

  • 导入模块: 导入 Scapy 库及其他必要的模块。

  • 函数定义: 定义 ARP 扫描、端口扫描和 TCP 三次握手及聊天的功能函数。

  • 命令行参数解析: 使用 argparse 模块解析命令行参数,支持选择不同的功能和指定目标 IP 地址、端口范围等。

  • 主函数: 根据命令行参数调用相应的功能函数。

使用方法

  1. ARP 扫描: 使用 --arp 参数扫描指定 IP 地址或网段,检测在线主机。

    python script.py --arp --ip 192.168.10.1-255
    
  2. 端口扫描: 使用 --port 参数扫描指定 IP 地址的端口,检测开放端口。

    python script.py --port --ip 192.168.10.1 --start-port 20 --end-port 100
    
  3. TCP 三次握手及聊天: 使用 --tcp 参数与指定 IP 地址的目标主机进行 TCP 三次握手,并进入聊天模式。

    python script.py --tcp --ip 192.168.10.1 --dst-port 55555
    

注意事项

  • ARP 扫描和端口扫描仅支持单一 IP 地址,不支持网段。

  • 运行脚本可能需要管理员权限,尤其是在发送和接收数据包时。

  • 使用这些工具时,请确保遵守相关法律法规,避免未经授权的网络扫描和通信。

结论

本文介绍的基于 Scapy 的网络工具集,提供了一个简洁而强大的解决方案,用于执行 ARP 扫描、端口扫描以及 TCP 三次握手和简单聊天。通过灵活的命令行参数,用户可以根据需要选择不同的功能,进行网络探测和通信。无论是在网络管理、安全审计还是学习和实验中,这个工具集都将是一个有价值的助手。

希望本文的介绍能够帮助读者更好地理解和使用这个基于 Scapy 的网络工具集,为网络操作和管理提供便利。

项目地址:https://github.com/2678509359/Scapy-based-network-scanning-tool

基于scapy的网络扫描工具-源码

import logging
import random
import argparse

from scapy.arch import get_if_hwaddr
from scapy.config import conf
from scapy.layers.inet import TCP, IP
from scapy.layers.l2 import ARP
from scapy.packet import Raw
from scapy.sendrecv import sr1, send

# 配置Scapy日志级别
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)


def scapy_ip(start, end=10, network='192.168.10.'):
    local_mac = get_if_hwaddr(conf.iface)
    for i in range(start, start + end):
        ip = f'{network}{i}'
        try:
            pkg = ARP(op=1, psrc=ip, hwsrc=local_mac, pdst=ip)
            reply = sr1(pkg, timeout=3, verbose=False)
            if reply and ARP in reply and reply[ARP].op == 2:
                print(f'{ip} 在线,MAC 地址: {reply[ARP].hwsrc}')
        except Exception as e:
            continue


def scapy_port(ip, start_port=20, end_port=100, src_ip='192.168.10.101'):
    for port in range(start_port, end_port + 1):
        try:
            pkg = IP(src=src_ip, dst=ip) / TCP(dport=port, flags='S')
            reply = sr1(pkg, timeout=1, verbose=False)
            if reply and reply.haslayer(TCP) and reply[TCP].flags == 0x12:  # SYN/ACK
                print(f'端口 {port} 开放')
                # 发送 RST 包关闭连接
                rst = IP(src=src_ip, dst=ip) / TCP(dport=port, flags='R', seq=reply[TCP].ack)
                send(rst, verbose=False)
        except Exception as e:
            continue


def scapy_tcp_handshake(ip, dst_port=55555, src_port=None):
    if src_port is None:
        src_port = random.randint(1024, 65535)

    # 第一次握手
    pkg_1 = IP(dst=ip) / TCP(sport=src_port, dport=dst_port, flags='S')
    reply = sr1(pkg_1, timeout=2, verbose=False)

    if not reply or not reply.haslayer(TCP) or reply[TCP].flags != 0x12:  # SYN/ACK
        print("未收到 SYN/ACK 响应或响应不完整")
        return

    # 第二次握手
    seq_ack = reply[TCP].ack
    ack_seq = reply[TCP].seq + 1
    pkg_2 = IP(dst=ip) / TCP(sport=src_port, dport=dst_port, flags='A', seq=ack_seq, ack=seq_ack)
    send(pkg_2, verbose=False)

    print("三次握手成功,开始发送聊天信息...")

    while True:
        message = input("输入消息发送 (或 'exit' 退出): ")
        if message.lower() == 'exit':
            break
        pkg_chat = IP(dst=ip) / TCP(sport=src_port, dport=dst_port, flags='PA', seq=ack_seq, ack=seq_ack) / message
        reply = sr1(pkg_chat, timeout=2, verbose=False)

        if reply and reply.haslayer(TCP) and reply[TCP].flags == 0x10:  # ACK
            ack_seq += len(message)
            try:
                received = reply[Raw].load.decode('utf-8')
                print(f"收到响应: {received}")
            except UnicodeDecodeError:
                print("收到的响应无法解码为 UTF-8")
        elif reply is None:
            print("未收到响应")
        else:
            print("握手失败或连接关闭")


def parse_arguments():
    parser = argparse.ArgumentParser(description="Scapy 网络工具集", formatter_class=argparse.RawTextHelpFormatter)
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--arp", action="store_true", help="执行 ARP 扫描")
    group.add_argument("--port", action="store_true", help="执行端口扫描")
    group.add_argument("--tcp", action="store_true", help="执行 TCP 三次握手及聊天")

    parser.add_argument("--ip", type=str, required=True, help="目标 IP 地址或网段(例如 192.168.10.1 或 192.168.10.0/24)")

    parser.add_argument("--start-port", type=int, default=20, help="端口扫描起始端口(默认: 20)")
    parser.add_argument("--end-port", type=int, default=100, help="端口扫描结束端口(默认: 100)")
    parser.add_argument("--dst-port", type=int, default=55555, help="TCP 目标端口(默认: 55555)")

    return parser.parse_args()


def main():
    args = parse_arguments()

    if args.arp:
        if '/' in args.ip:
            # 处理网段
            network, mask = args.ip.split('/')
            start_ip = int(network.split('.')[-1])
            end_ip = start_ip + (0xFFFFFFFF << (32 - int(mask))) - 1
            scapy_ip(start=start_ip, end=end_ip - start_ip + 1, network=f"{network}.{start_ip // 256}.{start_ip % 256}.")
        else:
            scapy_ip(start=int(args.ip.split('.')[-1]), network=args.ip.rsplit('.', 1)[0] + '.')

    if args.port:
        if '/' in args.ip:
            print("端口扫描不支持网段,请提供一个单一的IP地址。")
        else:
            scapy_port(args.ip, args.start_port, args.end_port)

    if args.tcp:
        if '/' in args.ip:
            print("TCP 握手不支持网段,请提供一个单一的IP地址。")
        else:
            scapy_tcp_handshake(args.ip, args.dst_port)


if __name__ == '__main__':
    main()

基于scapy的网络扫描工具-源码解析

这段代码是一个使用 Scapy 库编写的 Python 脚本,用于执行网络扫描和 TCP 三次握手及聊天功能。以下是对代码的详细分析:

导入模块

  • logging: 用于配置 Scapy 的日志级别。

  • random: 用于生成随机端口号。

  • argparse: 用于解析命令行参数。

  • scapy 相关模块: 用于网络数据包的构造、发送和接收。

函数定义

scapy_ip(start, end, network)
  • 功能: 执行 ARP 扫描,检测指定网段内的在线主机。

  • 参数:
    • start: 起始 IP 地址的最后一个八位字节。

    • end: 结束 IP 地址的最后一个八位字节。

    • network: 网络前缀(例如 192.168.10.)。

  • 实现:
    • 获取本地 MAC 地址。

    • 遍历指定范围内的 IP 地址,发送 ARP 请求并等待响应。

    • 如果收到 ARP 响应且操作码为 2(表示 ARP 回复),则打印在线主机的 IP 和 MAC 地址。

scapy_port(ip, start_port, end_port, src_ip)
  • 功能: 执行端口扫描,检测指定 IP 地址的开放端口。

  • 参数:
    • ip: 目标 IP 地址。

    • start_port: 起始端口号。

    • end_port: 结束端口号。

    • src_ip: 源 IP 地址。

  • 实现:
    • 遍历指定范围内的端口号,发送 SYN 包并等待响应。

    • 如果收到 SYN/ACK 响应,则打印开放端口,并发送 RST 包关闭连接。

scapy_tcp_handshake(ip, dst_port, src_port)
  • 功能: 执行 TCP 三次握手,并启动一个简单的聊天功能。

  • 参数:
    • ip: 目标 IP 地址。

    • dst_port: 目标端口号。

    • src_port: 源端口号(可选,默认随机生成)。

  • 实现:
    • 执行 TCP 三次握手。

    • 进入一个循环,接收用户输入的消息并发送给目标 IP 和端口。

    • 接收并打印来自目标的响应。

parse_arguments()
  • 功能: 解析命令行参数。

  • 实现:
    • 使用 argparse 创建一个参数解析器。

    • 定义互斥的参数组(ARP、端口扫描、TCP 握手)。

    • 定义其他必要的参数(IP 地址、端口范围等)。

main()
  • 功能: 主函数,根据命令行参数调用相应的功能。

  • 实现:
    • 解析命令行参数。

    • 根据参数调用 scapy_ipscapy_portscapy_tcp_handshake 函数。

命令行参数

  • --arp: 执行 ARP 扫描。

  • --port: 执行端口扫描。

  • --tcp: 执行 TCP 三次握手及聊天。

  • --ip: 目标 IP 地址或网段。

  • --start-port: 端口扫描起始端口(默认 20)。

  • --end-port: 端口扫描结束端口(默认 100)。

  • --dst-port: TCP 目标端口(默认 55555)。

注意事项

  • ARP 扫描不支持网段,需要提供单一 IP 地址。

  • 端口扫描和 TCP 握手不支持网段,需要提供单一 IP 地址。

  • 代码中使用了 Scapy 的 sr1send 函数发送和接收数据包,这些操作可能需要管理员权限。

总结

这段代码提供了一个简单的网络工具集,可以用于 ARP 扫描、端口扫描和 TCP 三次握手及聊天。通过命令行参数可以灵活选择不同的功能。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2291273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Python的药物相互作用预测模型AI构建与优化(上.文字部分)

一、引言 1.1 研究背景与意义 在临床用药过程中,药物相互作用(Drug - Drug Interaction, DDI)是一个不可忽视的重要问题。当患者同时服用两种或两种以上药物时,药物之间可能会发生相互作用,从而改变药物的疗效、增加不良反应的发生风险,甚至危及患者的生命安全。例如,…

Linux环境下的Java项目部署技巧:环境安装

安装 JDK&#xff1a; 第上传 jdk 压缩安装包到服务器 将压缩安装包解压缩&#xff1a; tar -xvf jdk-8uXXX-linux-x64.tar.gz 配置环境变量&#xff1a; 编辑 /etc/profile 文件&#xff0c;在文件末尾添加以下内容&#xff1a; export JAVA_HOME/path/to/jdk //JAVA_HOME…

【系统迁移】将系统迁移到新硬盘中(G15 5520)

文章目录 前言问题描述解决步骤&#xff08;红色为 debug 步骤&#xff09;参考文献 前言 参数&#xff1a; 电脑 dell g15 5520硬盘&#xff1a;1T 自带硬盘 海力士 2230 -> 2T 西数蓝盘 2280 问题描述 电脑硬盘过小&#xff08;且只有一个接口&#xff09;&#xff0c;将…

小智 AI 聊天机器人

小智 AI 聊天机器人 &#xff08;XiaoZhi AI Chatbot&#xff09; &#x1f449;参考源项目复现 &#x1f449; ESP32SenseVoiceQwen72B打造你的AI聊天伴侣&#xff01;【bilibili】 &#x1f449; 手工打造你的 AI 女友&#xff0c;新手入门教程【bilibili】 项目目的 本…

MySql运维篇---008:日志:错误日志、二进制日志、查询日志、慢查询日志,主从复制:概述 虚拟机更改ip注意事项

#先登录mysql mysql -uroot -p1234#通过此系统变量&#xff0c;查看当前mysql的版本中默认的日志格式是哪个 show variables like %binlog\_format%;1.2.3 查看 由于日志是以二进制方式存储的&#xff0c;不能直接读取&#xff0c;需要通过二进制日志查询工具 mysqlbinlog 来查…

理解DeepSeek源代码之如何安装triton包

DeepSeek选择了开源路线&#xff0c;在github上可以下载到所有的源代码还有参数&#xff08;数据集应该没有开源&#xff09;&#xff0c;大语言模型的源代码规模其实非常小&#xff0c;DeepSeek V3的模型函数不过804行&#xff0c;阅读源代码有助于更好理解大语言模型。 1. D…

C++ Primer 标准库类型string

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

为AI聊天工具添加一个知识系统 之83 详细设计之24 度量空间之1 因果关系和过程:认知金字塔

本文要点 度量空间 在本项目&#xff08;为AI聊天工具添加一个知识系统 &#xff09;中 是出于对“用”的考量 来考虑的。这包括&#xff1a; 相对-位置 力用&#xff08;“相”&#xff09;。正如 法力&#xff0c;相关-速度 体用 &#xff08;“体”&#xff09;。例如 重…

如何配置Java JDK

步骤1&#xff1a;点击资源&#xff0c;点击Java下载 https://www.oracle.com/ 步骤2&#xff1a;点击java下载、JDK23下载&#xff0c;下载第一行第一个 步骤3:解压到一个空文件夹下&#xff0c;复制lib地址 步骤4&#xff1a;在设置里面搜索“高级系统设置”&#xff1b;点击…

CodeGPT使用本地部署DeepSeek Coder

目前NV和github都托管了DeepSeek&#xff0c;生成Key后可以很方便的用CodeGPT接入。CodeGPT有三种方式使用AI&#xff0c;分别时Agents&#xff0c;Local LLMs&#xff08;本地部署AI大模型&#xff09;&#xff0c;LLMs Cloud Model&#xff08;云端大模型&#xff0c;从你自己…

JAVA安全—反射机制攻击链类对象成员变量方法构造方法

前言 还是JAVA安全&#xff0c;哎&#xff0c;真的讲不完&#xff0c;太多啦。 今天主要是讲一下JAVA中的反射机制&#xff0c;因为反序列化的利用基本都是要用到这个反射机制&#xff0c;还有一些攻击链条的构造&#xff0c;也会用到&#xff0c;所以就讲一下。 什么是反射…

【深度学习】softmax回归的简洁实现

softmax回归的简洁实现 我们发现(通过深度学习框架的高级API能够使实现)(softmax)线性(回归变得更加容易)。 同样&#xff0c;通过深度学习框架的高级API也能更方便地实现softmax回归模型。 本节继续使用Fashion-MNIST数据集&#xff0c;并保持批量大小为256。 import torch …

基础篇03-图像的基本运算

本节将简要介绍Halcon中有关图像的两类基本运算&#xff0c;分别是代数运算和逻辑运算。除此之外&#xff0c;还介绍几种特殊的代数运算。 目录 1.引言 2. 基本运算 2.1 加法运算 2.2 减法运算 2.3 乘法运算 2.4 除法运算 2.5 综合实例 3. 逻辑运算 3.1 逻辑与运算 …

工具的应用——安装copilot

一、介绍Copilot copilot是一个AI辅助编程的助手&#xff0c;作为需要拥抱AI的程序员可以从此尝试进入&#xff0c;至于好与不好&#xff0c;应当是小马过河&#xff0c;各有各的心得。这里不做评述。重点在安装copilot的过程中遇到了一些问题&#xff0c;然后把它总结下&…

Alibaba开发规范_编程规约之命名风格

文章目录 命名风格的基本原则1. 命名不能以下划线或美元符号开始或结束2. 严禁使用拼音与英文混合或直接使用中文3. 类名使用 UpperCamelCase 风格&#xff0c;但以下情形例外&#xff1a;DO / BO / DTO / VO / AO / PO / UID 等4. 方法名、参数名、成员变量、局部变量使用 low…

MATLAB中的IIR滤波器设计

在数字信号处理中&#xff0c;滤波器是消除噪声、提取特征或调整信号频率的核心工具。其中&#xff0c;无限脉冲响应&#xff08;IIR&#xff09;滤波器因其低阶数实现陡峭滚降的特性&#xff0c;被广泛应用于音频处理、通信系统和生物医学工程等领域。借助MATLAB强大的工具箱&…

vector容器(详解)

本文最后是模拟实现全部讲解&#xff0c;文章穿插有彩色字体&#xff0c;是我总结的技巧和关键 1.vector的介绍及使用 1.1 vector的介绍 https://cplusplus.com/reference/vector/vector/&#xff08;vector的介绍&#xff09; 了解 1. vector是表示可变大小数组的序列容器。…

python学opencv|读取图像(五十二)使用cv.matchTemplate()函数实现最佳图像匹配

【1】引言 前序学习了图像的常规读取和基本按位操作技巧&#xff0c;相关文章包括且不限于&#xff1a; python学opencv|读取图像-CSDN博客 python学opencv|读取图像&#xff08;四十九&#xff09;原理探究&#xff1a;使用cv2.bitwise()系列函数实现图像按位运算-CSDN博客…

【VUE案例练习】前端vue2+element-ui,后端nodo+express实现‘‘文件上传/删除‘‘功能

近期在做跟毕业设计相关的数据后台管理系统&#xff0c;其中的列表项展示有图片展示&#xff0c;添加/编辑功能有文件上传。 “文件上传/删除”也是我们平时开发会遇到的一个功能&#xff0c;这里分享个人的实现过程&#xff0c;与大家交流谈论~ 一、准备工作 本次案例使用的…

使用真实 Elasticsearch 进行高级集成测试

作者&#xff1a;来自 Elastic Piotr Przybyl 掌握高级 Elasticsearch 集成测试&#xff1a;更快、更智能、更优化。 在上一篇关于集成测试的文章中&#xff0c;我们介绍了如何通过改变数据初始化策略来缩短依赖于真实 Elasticsearch 的集成测试的执行时间。在本期中&#xff0…