Jteckz/tcp-port-scanner-

GitHub: Jteckz/tcp-port-scanner-

一个基于 C++17 的多线程 TCP connect 扫描器,用于教学演示端口扫描原理并支持服务 Banner 抓取。

Stars: 0 | Forks: 0

# TCP 端口扫描器 ![C++](https://img.shields.io/badge/C%2B%2B-17-blue.svg) ![CMake](https://img.shields.io/badge/build-CMake-informational.svg) ![Platform](https://img.shields.io/badge/platform-Linux-lightgrey.svg) ![License](https://img.shields.io/badge/license-MIT-green.svg) 一个使用现代 C++ (C++17) 编写的多线程 TCP connect-scanner,旨在 理解像 Nmap 这样的工具在底层的实际工作原理:在带有超时的情况下并行 向一系列端口发起原始 TCP 连接, 并从响应端抓取服务 banner。 ``` Scanning scanme.nmap.org ports 1-1000 with 100 threads... Resolved to 45.33.32.156 PORT STATE SERVICE BANNER 22 open ssh SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.13 80 open http HTTP/1.0 200 OK Server: Apache/2.4.7 ... Scanned 1000 ports in 842 ms. 2 open. ``` ## 目录 - [功能介绍](#what-it-does) - [构建](#build) - [用法](#usage) - [工作原理](#how-it-works-design-notes) - [项目结构](#project-structure) - [文档](#documentation) - [可能的扩展](#possible-extensions) - [局限性](#limitations) - [法律与道德使用](#legal--ethical-use) - [许可证](#license) ## 功能介绍 - **Connect scanning** — 对每个端口发起真实的 TCP 三次握手 (`socket()` + `connect()`),这与 `nmap -sT` 背后使用的技术相同。 - **带超时的非阻塞 connects** — 每个 socket 在 `connect()` 之前被设置为非阻塞, 然后使用 `select()` 等待连接完成或超时,这样单个缓慢/被过滤的端口就不会停滞整个扫描过程。 - **多线程** — 一组工作线程池从共享的 atomic counter 中获取端口并进行并发扫描, 与简单的顺序循环相比,大幅缩短了扫描时间。 - **Banner grabbing** — 成功建立连接后,扫描器会尝试读取服务发送的任何信息 (SSH、FTP、SMTP 会立即进行自我公告),而对于 HTTP 系列端口,它会首先发送一个 `HEAD / HTTP/1.0` 探测请求,因为这些服务在被访问之前会保持沉默。 - **服务名称猜测** — 一个小型的查找表将知名端口 (22、80、443、3306 等)映射到对应的服务名称,就像一个简化的 `/etc/services`。 ## 构建 需要 C++17 编译器和 CMake 3.10+ 版本。 ``` git clone https://github.com//tcp-port-scanner.git cd tcp-port-scanner mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make ``` 这将生成 `build/scanner`。 ## 用法 ``` ./scanner [start_port] [end_port] [options] ``` | 选项 | 描述 | 默认值 | |---|---|---| | `-t ` | 并发工作线程数 | 100 | | `-T ` | 每个端口的连接超时时间(毫秒) | 500 | | `--no-banner` | 跳过 banner 抓取以加快扫描速度 | 关闭 | | `-h`, `--help` | 显示用法 | | ### 示例 ``` # 扫描主机的 well-known ports ./scanner 192.168.1.10 1 1000 # Full port range,更多线程,更严格的 timeout ./scanner scanme.nmap.org 1 65535 -t 200 -T 300 # 快速扫描,无 banner grabbing ./scanner 10.0.0.5 1 1024 --no-banner ``` ## 工作原理(设计笔记) - **`PortScanner`**(`include/scanner.hpp`,`src/scanner.cpp`)拥有扫描 配置和结果。`run()` 通过 `getaddrinfo` 解析一次目标主机, 然后启动 `numThreads` 个工作线程,每个线程运行 `workerLoop()`。 - 每个工作线程不断从一个单一的 `std::atomic` 计数器(`nextPort_`)中认领下一个端口索引,而不是使用受锁保护的 队列 — 对于简单的“获取下一个整数”任务来说,这种同步方式开销更低。 - **超时处理**:阻塞式的 `connect()` 在被过滤或受防火墙保护的端口上可能会挂起很长时间。 将 socket 设置为非阻塞,并让 `connect()` 与 `select()` 的超时进行赛跑,意味着单个无响应的端口 最多只会消耗 `connectTimeoutMs` 的时间,而不是操作系统的默认 TCP 超时 (通常为 60 秒以上)。 - **线程安全**:只有共享的结果向量需要 mutex (`resultsMutex_`);每个工作线程的 socket、缓冲区和局部变量对该线程都是私有的。 ## 项目结构 ``` tcp-port-scanner/ ├── CMakeLists.txt ├── README.md ├── AI_COLLABORATION.md # how AI was used in building this, and what I verified myself ├── include/ │ └── scanner.hpp └── src/ ├── scanner.cpp └── main.cpp ``` ## 文档 除了本 README 之外,此代码库还包含两份说明文档: - **[AI_COLLABORATION.md](AI_COLLABORATION.md)** — 如实记录了在开发过程中是如何使用 AI 的, 哪些是我自己指导和验证的,以及真正的调试工作是在哪里进行的。 - 一份完整的**从零开始的构建指南**(PDF),涵盖了网络基础、 每一个设计决策,以及对 socket/多线程代码的逐行解释 — 它是作为一份教学文档编写的,而不仅仅是 API 文档。 ## 可能的扩展 - IPv6 支持(为简单起见,目前仅支持 IPv4) - SYN 扫描(使用 raw sockets,需要 root 权限)以取代完整的 connect 扫描 - UDP 扫描 - CIDR 范围 / 多主机输入 - 用于脚本化的 JSON 输出 ## 局限性 这是一个 **connect scanner**,而不是 SYN/隐身扫描器 — 它会完成 完整的 TCP 握手,因此它会出现在目标日志中,并且在面对极大量端口时,扫描速度比 raw-socket 扫描慢。它被定位为一个学习项目,而不是 Nmap 的替代品。 ## 法律与道德使用 仅对你拥有、控制或获得明确测试授权的主机运行此程序 — 例如 [scanme.nmap.org](https://nmap.org/book/legal-issues.html),这是 Nmap 项目专门维护的一个合法的公共扫描目标。未经授权扫描 系统可能会违反计算机滥用法,即使 没有造成任何损害。 ## 许可证 MIT — 参见 [LICENSE](LICENSE)(如果你 还没有添加,可以通过 GitHub 的“Add file”流程添加一个,或者在使用 `gh repo create` 时附带 `--license MIT`)。
标签:Bash脚本, C++, DNS查询工具, TCP协议, 插件系统, 数据擦除, 端口扫描器, 网络安全, 隐私保护