ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python信息收集工具源码解析:PyQt5 GUI与渗透测试模块

Python信息收集工具源码解析:PyQt5 GUI与渗透测试模块 简介这是一套面向网络安全初学者与渗透测试从业者的Python信息收集工具源代码基于PyQt5构建图形界面将端口扫描、敏感文件探测、子域名枚举、WHOIS查询、指纹识别与服务器信息收集等功能整合为可视化操作降低命令行使用门槛。资源包共39个文件以14个py源码与12个pyc编译文件为核心辅以6个txt字典、2个ini配置、1个ui界面文件及png图标等压缩包约310KB结构紧凑便于阅读与二次开发。其中字典文件支撑目录爆破与子域名探测配置文件管理目标与参数ui文件对应主窗口布局源码模块划分清晰适合逐模块研读实现思路。目前已有771人学习下载读者可借此理解信息收集各环节的Python实现方式掌握从网络请求到结果输出的完整链路并在此基础上扩展自己的工具集适合作为渗透测试入门与代码实践的参考素材。1. 从一份带 PyQt5 界面的信息收集工具源码说起很多做渗透测试的同行手里都攒着一堆零散的 Python 脚本端口扫描一个、目录爆破一个、Whois 查询又一个跑起来得来回切终端参数记不住还得翻历史命令。这份「Python 信息收集、渗透测试工具源代码」解决的正是这个痛点——它把常见的信息收集能力收进一个 PyQt5 图形界面里点按钮就能触发扫描结果直接回显在窗口里。它适合两类人一是刚入门、想通过读源码理解信息收集流程的新手二是想拿一套现成 GUI 框架改成自己内部工具的老手。源码本身不神秘价值在于把「扫描逻辑」和「界面交互」这两件事拆得比较清楚改起来不费劲。2. 拆开源码看结构PyQt5 界面与扫描逻辑怎么分层拿到一份 GUI 工具源码最怕的就是界面代码和业务逻辑搅在一起改一个按钮结果崩了三个功能。这份源码在结构上做了基本的分层值得先花十分钟摸清楚再动手。2.1 目录结构与模块职责常见做法是把项目根目录分成几个部分入口文件负责启动应用和加载主窗口ui目录放 Qt Designer 生成的界面文件或手写的界面类core或modules目录放具体的扫描逻辑utils放公共函数比如 IP 校验、结果格式化。下面是一个典型的目录布局你拿到源码后可以对照着看project/ ├── main.py # 程序入口创建 QApplication 和主窗口 ├── ui/ │ ├── main_window.py # 主窗口类绑定按钮信号与槽 │ └── main_window.ui # Qt Designer 界面描述文件可选 ├── core/ │ ├── port_scan.py # 端口扫描逻辑 │ ├── whois_query.py # Whois 查询 │ └── subdomain.py # 子域名收集 ├── utils/ │ └── helpers.py # IP 校验、结果导出等 └── requirements.txt # 依赖清单这个分法的好处是界面层只负责「收集用户输入、调用 core 层函数、把返回值显示到表格或文本框」core 层完全不依赖 PyQt5可以单独在命令行里测试。我一般拿到新源码第一件事就是打开core目录把每个模块单独跑一遍确认扫描逻辑本身没问题再去调界面。2.2 信号与槽按钮点击后到底发生了什么PyQt5 的核心交互机制是信号signal和槽slot。按钮被点击是一个信号你写的处理函数就是槽。很多新手读源码时卡在这里觉得「点一下按钮怎么就跑到扫描函数去了」。看下面这段典型代码# ui/main_window.py from PyQt5.QtCore import QThread from core.port_scan import PortScanner class MainWindow(QMainWindow): def __init__(self): super().__init__() self.scan_btn.clicked.connect(self.on_scan_clicked) # 绑定信号与槽 def on_scan_clicked(self): target self.target_input.text().strip() # 取输入框内容 if not target: self.log_output.append(请先输入目标地址) return # 用独立线程跑扫描避免阻塞界面 self.worker PortScanner(target) self.worker.finished.connect(self.on_scan_finished) self.worker.start() def on_scan_finished(self, results): for row in results: self.result_table.addRow(row) # 结果写入表格逻辑说明clicked.connect把按钮点击事件和on_scan_clicked方法绑在一起这是 PyQt5 的标准写法。关键点在QThread——扫描是耗时操作如果直接在主线程里跑界面会卡死变成「无响应」这是 GUI 工具最常见的翻车点。参数方面target来自输入框记得strip()去掉首尾空格否则用户复制粘贴时带个空格就会导致扫描失败。finished信号携带扫描结果通过connect回到主线程更新界面这样线程安全。2.3 依赖安装与环境准备源码要跑起来先把依赖装齐。requirements.txt里通常包含PyQt5、requests、python-whois这类库。安装命令# 建议在虚拟环境里操作避免污染全局 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install -r requirements.txt如果pip install PyQt5卡住或报错常见原因是 Python 版本和 PyQt5 wheel 不匹配。Python 3.9 到 3.11 对 PyQt5 的支持比较稳3.12 以上有时需要换PyQt5-tools或改用PySide6。装完后用python -c from PyQt5.QtWidgets import QApplication; print(ok)验证一下能打印ok就说明环境没问题。这一步看着简单但我见过太多人卡在依赖上就放弃了其实换个 Python 版本或者用国内镜像源pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt就能解决。3. 信息收集模块逐个跑通端口、Whois、子域名界面能启动只是第一步真正要验证的是每个扫描模块能不能出结果。这一章把常见的三个模块拆开讲每个都给出可独立运行的代码和参数说明。3.1 端口扫描socket 连接与超时控制端口扫描的原理很朴素用 socket 去连目标端口连上了就是开放超时或拒绝就是关闭。源码里大概率用的是socket.connect_ex因为它不抛异常直接返回错误码处理起来干净。# core/port_scan.py import socket from concurrent.futures import ThreadPoolExecutor COMMON_PORTS [21, 22, 23, 25, 80, 110, 143, 443, 445, 3306, 3389, 8080] def scan_port(host, port, timeout1.0): 扫描单个端口返回 (port, is_open) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(timeout) # 超时设短一点否则扫 1000 个端口要等很久 result s.connect_ex((host, port)) # 返回 0 表示端口开放 return port, result 0 def scan_ports(host, portsNone, max_workers50): ports ports or COMMON_PORTS open_ports [] with ThreadPoolExecutor(max_workersmax_workers) as executor: futures [executor.submit(scan_port, host, p) for p in ports] for f in futures: port, is_open f.result() if is_open: open_ports.append(port) return sorted(open_ports)逻辑说明settimeout(1.0)是超时时间单位秒。设太长扫描慢设太短可能漏掉响应慢的端口1 秒是常见折中值。connect_ex返回 0 代表 TCP 三次握手成功端口开放。ThreadPoolExecutor用多线程并发扫描max_workers50表示同时开 50 个线程这个数字别调太大否则本机文件描述符可能不够用报Too many open files。扫描结果排序后返回方便界面展示。参数怎么改如果你要扫全端口 1-65535把ports参数传成range(1, 65536)但记得把max_workers降到 20 左右超时设 0.5 秒否则扫一轮要十几分钟。实际使用中先扫常见端口发现目标存活后再针对性扫全端口效率更高。3.2 Whois 查询域名注册信息的获取与解析Whois 查询用来拿域名的注册人、注册时间、到期时间、DNS 服务器等信息。Python 里有python-whois库可以直接用但要注意它返回的字段名在不同顶级域名下可能不一致。# core/whois_query.py import whois def query_whois(domain): 查询域名 Whois 信息返回字典 try: w whois.whois(domain) return { domain: w.domain_name, registrar: w.registrar, creation_date: str(w.creation_date), expiration_date: str(w.expiration_date), name_servers: w.name_servers, } except Exception as e: return {error: str(e)}逻辑说明whois.whois(domain)返回一个对象字段访问用属性方式。creation_date有时是列表一个域名有多个注册记录所以用str()包一层避免界面显示报错。异常处理不能省——有些域名没有 Whois 记录或者查询被限流不捕获的话整个程序会崩。参数方面传入的domain要是纯域名比如example.com不要带http://或路径否则查询会失败。3.3 子域名收集字典爆破与结果去重子域名收集常见两种方式一是查证书透明度日志crt.sh 这类二是字典爆破。源码里如果带了字典爆破核心逻辑就是拼接subdomain.domain然后做 DNS 解析。# core/subdomain.py import socket def resolve_subdomain(sub, domain): 解析子域名返回 IP 或 None full f{sub}.{domain} try: return full, socket.gethostbyname(full) except socket.gaierror: return full, None def collect_subdomains(domain, wordlist): 遍历字典收集子域名 found {} for sub in wordlist: full, ip resolve_subdomain(sub, domain) if ip: found[full] ip return found逻辑说明socket.gethostbyname做 DNS 解析解析成功说明子域名存在。socket.gaierror是解析失败的异常捕获后返回 None。found用字典存键是完整域名值是 IP天然去重。字典文件一般放在wordlist目录下常见的有subdomains-top1million-5000.txt这类行数别太多5000 条左右跑一轮几分钟10 万条就要考虑加并发和 DNS 缓存了。提示DNS 解析受本地 DNS 服务器影响很大有时候解析失败不是子域名不存在而是 DNS 超时。可以在代码里加重试或者换用dnspython库指定公共 DNS 服务器。4. 避坑与排查GUI 卡死、依赖冲突、扫描被限这份源码跑起来不难但实际用的时候有几类问题反复出现。下面按「现象 → 原因 → 解决」整理都是我自己踩过的。4.1 界面点击后卡死无响应现象点「开始扫描」按钮后窗口变白标题栏显示「无响应」等十几秒才恢复。原因扫描逻辑跑在主线程里PyQt5 的事件循环被阻塞界面无法重绘。这是 GUI 开发最经典的错误。解决把所有耗时操作放进QThread或QRunnable。源码里如果已经用了线程检查是不是在槽函数里直接调了scan_ports()而不是通过worker.start()。另外注意子线程里不能直接操作界面控件必须通过信号回传主线程更新。4.2 PyQt5 安装报错或版本不兼容现象pip install PyQt5报ERROR: Could not build wheels或者装完后import PyQt5提示 DLL 加载失败。原因Python 版本太新比如 3.12没有对应的预编译 wheel或者系统缺少 VC 运行库。解决优先用 Python 3.93.11。Windows 上装一下 VC Redistributable。如果还是不行改用PySide6API 几乎一样把from PyQt5改成from PySide6就能跑这是最省事的后悔药。4.3 端口扫描结果不稳定同一目标两次结果不同现象对同一台主机扫两次开放的端口列表不一致有时多一个有时少一个。原因超时设太短网络抖动导致某些端口没来得及响应就被判定为关闭或者目标主机有防护设备对高频连接做了限流。解决把timeout从 0.5 秒调到 1.52 秒max_workers从 50 降到 20。如果目标有防护扫描间隔加随机延迟别用固定频率猛打。扫描结果只作参考关键端口用telnet或nc手动验证一遍。4.4 Whois 查询返回空或字段缺失现象查询某些域名时registrar是 None或者直接抛异常。原因不同顶级域名的 Whois 服务器返回格式不一样python-whois的解析规则覆盖不全部分域名开启了隐私保护注册信息被隐藏。解决在代码里对每个字段做空值判断界面显示「未获取到」而不是直接崩。对于解析失败的域名可以换用whois命令行工具手动查一次确认是库的问题还是域名本身没有公开信息。5. 二次开发与验证把工具改成你自己的源码能跑通之后真正的价值在于改成适合自己工作流的版本。这一章讲两个实用的改造方向和验证方法。5.1 增加扫描结果导出功能原始工具的结果只显示在界面上关掉就没了。加一个「导出 CSV」按钮是很常见的需求。在MainWindow里加一个按钮槽函数里把表格数据写成 CSVimport csv from PyQt5.QtWidgets import QFileDialog def export_csv(self): path, _ QFileDialog.getSaveFileName(self, 保存结果, , CSV Files (*.csv)) if not path: return with open(path, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([端口, 状态, 服务]) # 表头 for row in range(self.result_table.rowCount()): writer.writerow([ self.result_table.item(row, 0).text(), self.result_table.item(row, 1).text(), self.result_table.item(row, 2).text(), ])逻辑说明QFileDialog.getSaveFileName弹出系统保存对话框返回路径和过滤器。csv.writer逐行写入encodingutf-8避免中文乱码。rowCount()遍历表格所有行item(row, col).text()取单元格内容。参数方面表头按你实际表格的列来改别照抄。5.2 用已知目标验证扫描准确性改完代码怎么确认没改坏我一般用两个目标做回归验证一是127.0.0.1本机开放端口自己清楚扫出来对不上就是代码有问题二是scanme.nmap.org这是 Nmap 官方提供的测试目标允许合法扫描用它验证外网扫描链路是否正常。验证步骤步骤操作预期结果1扫描 127.0.0.1 常见端口结果与本机netstat -tlnp一致2扫描 scanme.nmap.org 80/443两个端口均显示开放3输入不存在的域名做 Whois界面提示错误而非崩溃4导出 CSV 后用 Excel 打开中文表头正常显示无乱码这四步走完基本能确认工具的核心功能没退化。从那以后我每次改完扫描逻辑都强制走一遍这个验证流程比凭感觉靠谱得多。5.3 关于合法使用的边界这类工具的能力是双刃剑用之前务必确认目标是你自己的资产或者拿到了书面授权。扫描公网陌生 IP 可能触发对方的安全告警严重的话会惹上麻烦。源码本身是学习材料拿它练手没问题但别拿去扫不属于你的东西。希望这份源码和上面的拆解能帮你把信息收集这块的基本功练扎实需要的话按文中的结构去对应目录里找文件就行。本文还有配套的精品资源点击获取
返回列表