rayyme6/python-port-scanner

GitHub: rayyme6/python-port-scanner

一个支持多线程 Connect 扫描与 Scapy SYN 扫描的轻量级 Python 端口扫描工具,具备服务识别与报告导出功能。

Stars: 1 | Forks: 0

# Python 端口扫描器 一个使用 Python 编写的命令行 TCP 端口扫描器,用于学习网络编程、进行授权的安全评估以及排查网络服务问题。 该扫描器支持多线程 TCP connect 模式,以及使用 Scapy 进行数据包级别的半开 SYN 扫描。它可以扫描自定义端口范围,执行基本的服务和 banner 识别,显示扫描进度,并将结果导出到文本文件。 ## 功能 * 多线程 TCP connect 扫描 * 使用 Scapy 进行半开 TCP SYN 扫描 * 支持主机名和 IPv4 地址 * 支持单个端口、端口范围和混合端口规范 * 基本服务识别 * Banner 抓取 * HTTP 服务探测 * 可配置的超时时间 * 可配置的 connect 扫描线程数 * 实时进度显示 * 纯文本报告导出 * 检测完全无响应或不可达的目标 * 优雅的错误处理 * TCP connect 扫描无需外部依赖 ## 扫描模式 | 模式 | 标志 | 库 | 权限 | 描述 | | ---------------- | ------- | --------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | TCP Connect 扫描 | 默认 | Python `socket` | 无 | 完成完整的 TCP 三次握手。它是多线程的、可靠的,并且在无需管理权限的情况下即可运行。 | | SYN 扫描 | `--syn` | Scapy | Root / Administrator | 发送 TCP SYN 数据包并检查回复,而无需完成握手。目前的实现是按顺序扫描端口,可能比多线程 connect 扫描器慢。 | ### TCP Connect 扫描 默认扫描器使用 Python 的 socket 库尝试完整的 TCP 连接。 当连接成功时,该端口被视为开放: ``` Scanner → SYN Target → SYN-ACK Scanner → ACK ``` 由于完成了完整的连接,目标服务的连接日志中可能会记录此尝试。 ### SYN 扫描 SYN 扫描器使用 Scapy 创建和发送原始 TCP 数据包。 典型的响应解释如下: ``` SYN-ACK response → Open RST response → Closed No response → Filtered, dropped, or unreachable ICMP response → Network device or firewall responded ``` 当端口返回 SYN-ACK 时,扫描器会立即发送一个 TCP 重置(RST)数据包: ``` Scanner → SYN Target → SYN-ACK Scanner → RST ``` 这可以防止正常的 TCP 握手被完成。 ## 要求 * Python 3.8 或更高版本 * 进行 SYN 扫描需使用 Linux 或 macOS * 进行 SYN 扫描需使用 Scapy * 发送原始 SYN 数据包需要 Root 权限 标准的 TCP connect 扫描器仅使用 Python 的标准库。 ## 安装 克隆仓库: ``` git clone https://github.com/YOUR_USERNAME/python-port-scanner.git cd python-port-scanner ``` 创建 Python 虚拟环境: ``` python3 -m venv .venv ``` 激活环境: ``` source .venv/bin/activate ``` 安装项目依赖: ``` pip install -r requirements.txt ``` `requirements.txt` 文件会安装 Scapy,该库仅在 SYN 扫描时需要。 ## 用法 基本语法: ``` python3 port_scanner.py TARGET [OPTIONS] ``` 显示完整的帮助菜单: ``` python3 port_scanner.py --help ``` ## 示例 ### 扫描 TCP 端口 1 到 1024 ``` python3 port_scanner.py 192.168.1.10 ``` 默认的端口范围是 `1-1024`。 这意味着扫描器会检查从 1 到 1024 的每一个 TCP 端口。它不会使用 Nmap 列出的前 1024 个最常见端口。 ### 扫描特定端口 ``` python3 port_scanner.py 192.168.1.10 -p 22,80,443 ``` ### 扫描端口范围 ``` python3 port_scanner.py 192.168.1.10 -p 1-5000 ``` ### 扫描混合端口和范围 ``` python3 port_scanner.py 192.168.1.10 -p 22,80,443,8000-8100 ``` ### 扫描主机名 ``` python3 port_scanner.py example.com -p 80,443 ``` ### 更改超时时间 ``` python3 port_scanner.py 192.168.1.10 -p 1-1024 --timeout 0.5 ``` 较短的超时时间会使扫描更快,但可能会漏掉缓慢的响应。 较长的超时时间在缓慢的网络上更可靠,但可能会显著增加扫描持续时间。 ### 更改线程数 ``` python3 port_scanner.py 192.168.1.10 -p 1-5000 --threads 100 ``` 线程设置仅适用于 TCP connect 扫描。 ### 执行 SYN 扫描 使用虚拟环境时: ``` sudo .venv/bin/python port_scanner.py 192.168.1.10 -p 1-1024 --syn ``` 创建原始数据包通常需要 root 权限。 ### 执行不带 banner 抓取的 SYN 扫描 ``` sudo .venv/bin/python port_scanner.py 192.168.1.10 -p 1-1024 --syn --no-banner ``` 这将执行半开端口发现,而不会为了识别服务而建立额外的完整 TCP 连接。 ### 在 connect 模式下跳过 banner 抓取 ``` python3 port_scanner.py 192.168.1.10 -p 1-65535 --no-banner ``` 当仅需要开放的端口号时,这可以使扫描更快。 ### 将报告保存到文件 ``` python3 port_scanner.py 192.168.1.10 -p 1-1024 -o report.txt ``` 输出文件包含: * 目标主机名或 IP 地址 * 解析后的 IP 地址 * 扫描类型 * 日期和时间 * 扫描持续时间 * 开放端口 * 服务标签 * 抓取到的 banner ## 命令行选项 | 参数 | 用途 | | ----------------- | ---------------------------------------------------------- | | `target` | 目标 IPv4 地址或主机名 | | `-p`, `--ports` | 要扫描的端口,例如 `22,80,443`、`1-1024` 或混合输入 | | `-t`, `--timeout` | 每个端口的超时时间(秒) | | `--threads` | TCP connect 扫描的最大并发线程数 | | `--syn` | 使用 Scapy SYN 扫描器 | | `--no-banner` | 跳过服务和 banner 识别 | | `-o`, `--output` | 将扫描报告写入文本文件 | | `-h`, `--help` | 显示帮助菜单 | 默认值: ``` Ports: 1-1024 Timeout: 1.0 second Threads: 200 Mode: TCP connect scan ``` ## 输出示例 ``` Target: 192.168.100.1 (192.168.100.1) Ports : 1024 Mode : TCP connect scan (socket) scanned 1024/1024 ports. ============================================================== Scan report for 192.168.100.1 (192.168.100.1) Scan type : TCP connect scan (socket) Duration : 5.44s ============================================================== PORT STATE SERVICE BANNER ------ ----- ------- ------------------------------ 23 open Telnet 53 open DNS 80 open HTTP HTTP/1.1 404 Not Found 3 open port(s) found. ``` 在此示例中: * TCP 端口 23 接受了连接。 * TCP 端口 53 接受了连接。 * TCP 端口 80 接受了连接并返回了 HTTP 响应。 * 没有 banner 的端口的服务名称可能基于其常规的端口分配。 ## 工作原理 程序遵循以下一般流程: ``` Read command-line arguments ↓ Resolve the target to an IPv4 address ↓ Parse and validate the port specification ↓ Select TCP connect or SYN scanning ↓ Probe every requested port ↓ Collect open ports ↓ Attempt service and banner identification ↓ Print the results ↓ Optionally save a report ``` ## 端口解析 扫描器接受多种端口格式。 ### 单个端口 ``` 80 ``` ### 多个端口 ``` 22,80,443 ``` ### 端口范围 ``` 1-1024 ``` ### 混合输入 ``` 22,80,443,8000-8100 ``` 重复的端口会自动移除,最终列表会进行排序。 有效的端口号范围是 1 到 65535。 无效的示例包括: ``` 0 65536 100-50 abc ``` ## TCP Connect 扫描 TCP connect 扫描器使用 `socket.connect_ex()` 测试每个端口。 可能的结果包括: ### 开放 连接成功,并且 `connect_ex()` 返回 `0`。 ``` is_open = True got_reply = True ``` ### 关闭 目标主动拒绝连接。 ``` is_open = False got_reply = True ``` 这通常意味着主机可达,但没有应用程序在该端口上监听。 ### 无有效响应 连接尝试超时或被静默丢弃。 ``` is_open = False got_reply = False ``` 可能的原因包括: * 防火墙静默丢弃了探测包 * 主机离线 * 目标地址不正确 * 存在路由问题 * 超时时间过短 * 发生丢包 connect 扫描器使用线程池,以便并发测试多个端口。 ## SYN 扫描 SYN 扫描器使用 Scapy 创建一个包含 IP 层和 TCP 层的数据包: ``` IP(dst=target_ip) / TCP( sport=source_port, dport=destination_port, flags="S" ) ``` 该数据包包含: * 目标 IPv4 地址 * 随机的高位源端口 * 被测试的目标端口 * SYN 标志 * 随机 TCP 序列号 Scapy 发送数据包并等待响应。 ### SYN-ACK 响应 SYN-ACK 通常表示端口开放。 扫描器发送重置数据包以终止半开连接。 ### RST 响应 重置通常表示端口已关闭。 ### 无响应 缺少响应可能意味着被过滤、丢包、目标不可达或主机离线。 ### ICMP 响应 路由器、防火墙或目标系统可能会返回 ICMP 错误。 当前的 SYN 扫描器一次测试一个端口。未来版本可能会使用 Scapy 的批量发送功能来提高性能。 ## 服务和 banner 识别 发现开放端口后,扫描器会尝试进行基本的服务识别。 流程如下: 1. 根据常规端口号分配一个备选服务名称。 2. 打开到该端口的 TCP 连接。 3. 简短等待服务发送 banner。 4. 如果未收到任何内容,则发送通用的 HTTP `HEAD` 请求。 5. 检查响应中是否有可识别的协议。 某些服务会立即发送识别性的 banner。 SSH banner 示例: ``` SSH-2.0-OpenSSH_9.6 ``` FTP banner 示例: ``` 220 FTP Server Ready ``` SMTP banner 示例: ``` 220 mail.example.com ESMTP ``` 对于静默的服务,扫描器会发送: ``` HEAD / HTTP/1.0 Host: TARGET_IP ``` 如果响应以 `HTTP/` 开头,则该服务被识别为 HTTP。 示例: ``` HTTP/1.1 404 Not Found ``` `404 Not Found` 响应依然是 HTTP 服务器接受并处理了请求的证据。这并不代表该端口已关闭。 ## 服务识别准确性 仅基于端口号的服务名称是尽力而为的标签,并非最终确定性的识别。 例如,开放的 TCP 端口 23 会被标记为 `Telnet`,因为端口 23 通常与 Telnet 关联。然而,另一个应用程序也可能被配置为监听该端口。 当扫描器收到以下信息时,会提供更强有力的识别: * 可识别的 banner * SSH 协议字符串 * 有效的 HTTP 响应 * HTTP `Server` 标头 扫描器不会执行完整的服务版本指纹识别,例如: ``` nmap -sV ``` ## 了解端口状态 ### 开放 程序正在该端口上接受 TCP 连接。 ### 关闭 主机有响应,但没有程序在该端口上接受连接。 ### 被过滤 防火墙或网络设备可能正在阻止或静默丢弃探测包。 ### 不可达或无响应 目标可能离线、地址不正确、因路由问题被隔离或受过滤保护。 当前的最终报告仅列出开放端口。 ## 完全无响应的目标 两种扫描引擎都会跟踪目标是否返回了任何响应。 开放端口的响应和明确的拒绝都证实了有设备进行了回复。 如果每个探测都超时且没有回复,扫描器会打印警告,而不是确信地报告该主机没有开放端口。 完全无响应的结果可能意味着: * 目标离线 * 目标更改了 IP 地址 * 防火墙正在静默丢弃数据包 * 启用了无线客户端隔离 * 设备位于不同的 VLAN 上 * 扫描器与目标之间无法进行路由 * 超时时间太短 有用的故障排除命令包括: ``` ping -c 4 192.168.1.10 ``` ``` ip route ``` ``` ip neigh ``` 您还可以检查路由器的 DHCP 客户端或已连接设备列表。 ## 虚拟环境和 `sudo` 建议在虚拟环境中安装 Scapy: ``` python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` 运行此命令: ``` sudo python3 port_scanner.py TARGET --syn ``` 可能会使用 root 用户的 Python 环境,而不是您的虚拟环境。因此,Root 可能无法找到 Scapy。 请使用虚拟环境内的 Python 可执行文件: ``` sudo .venv/bin/python port_scanner.py TARGET --syn ``` 这赋予了脚本原始套接字权限,同时仍使用安装在 `.venv` 中的包。 避免使用以下命令全局安装包: ``` sudo pip install scapy ``` 因为这可能会干扰操作系统管理的 Python 环境。 ## 项目结构 ``` python-port-scanner/ ├── port_scanner.py ├── requirements.txt └── README.md ``` ### `port_scanner.py` 包含: * 命令行界面 * 端口解析 * 主机名解析 * TCP connect 扫描器 * SYN 扫描器 * banner 识别 * 结果格式化 * 文本报告生成 ### `requirements.txt` 包含 SYN 扫描所需的 Scapy 依赖。 ### `README.md` 包含安装说明、用法示例、技术解释、限制和负责任的使用指南。 ## 实际应用 本项目可在授权环境中用于: * 网络故障排除 * 验证服务是否可达 * 检查服务器暴露情况 * 测试防火墙配置 * 审计家庭网络 * 验证云服务器安全组 * 部署后服务验证 * 网络安全实验室练习 * 学习 socket 编程 * 学习 TCP 数据包结构 * 了解 TCP 握手 * 基本的资产和服务发现 * 防御性安全评估 它是一个学习和审计工具,而不是一个漏洞利用框架。 ## 限制 当前的限制包括: * 仅支持 TCP 扫描 * 不支持 UDP 扫描 * 仅支持 IPv4 * 无操作系统指纹识别 * 无漏洞检测 * 无漏洞利用功能 * 基于基本 banner 的服务识别 * 无完整的服务版本指纹识别 * SYN 探测当前按顺序发送 * 最终报告仅列出开放端口 * 无 JSON 或 CSV 输出 * 无多主机或子网扫描 * 扫描结果之间无历史比较 * 向静默的开放服务发送通用 HTTP 探测 * Banner 抓取错误被有意抑制 ## 未来可能的改进 潜在的改进包括: * 并发或批量 SYN 扫描 * UDP 扫描 * IPv6 支持 * 多主机扫描 * CIDR 子网支持 * 报告已关闭和被过滤的端口 * 特定于协议的服务探测 * 服务版本指纹识别 * JSON 报告导出 * CSV报告导出 * 结构化日志记录 * 可配置的重试次数 * 速率限制 * 历史扫描比较 * 自动化测试 * 更好的异常日志记录 * 可选的彩色终端输出 * 操作系统指纹识别 * 与漏洞数据库集成 ## 学习成果 构建该项目展示了对以下知识的掌握: * Python socket 编程 * TCP/IP 网络 * TCP 三次握手 * SYN、ACK、RST 和 ICMP 响应 * 原始数据包构建 * Scapy * 多线程 * 线程池 * 超时 * 命令行应用程序设计 * 参数解析 * DNS 解析 * 错误处理 * Banner 抓取 * 服务识别 * 报告生成 * 防御性网络侦察 ## 负责任的使用 仅扫描您拥有或获得明确测试授权的系统和网络。 授权目标的示例包括: * 您自己的计算机 * 您自己的路由器 * 您的个人家庭实验室 * 大学网络安全实验室 * 拥有书面授权的客户系统 * 明确允许测试的专用公共扫描目标 未经授权的扫描可能违反: * 当地法律 * 计算机滥用法 * 合同 * 可接受使用政策 * 互联网服务提供商政策 * 工作场所或大学安全规则 作者对滥用本软件不承担任何责任。 本项目仅用于教育、授权的安全测试和网络故障排除。
标签:Banner抓取, Python, Scapy, 插件系统, 数据泄露防护, 数据统计, 无后门, 端口扫描, 网络探测, 逆向工具