labgeek/HashHarvest

GitHub: labgeek/HashHarvest

一款基于 PyQt5 的桌面应用,能从多种文档格式中递归提取加密哈希值并导出为 CSV 或 JSON,同时提供 SQLite 扫描历史管理。

Stars: 2 | Forks: 0

# HashHarvest 作者:labgeek@gmail.com `HashHarvest` 是一个 PyQt5 桌面应用程序,用于从文件文件夹中提取加密哈希值。它会递归扫描 PDF、文本、日志、CSV、JSON、XML、Markdown 和 Microsoft Office 文件(Word `.docx`、Excel `.xlsx`、PowerPoint `.pptx`)——使用精确的十六进制长度匹配结合负向零宽断言来检测 MD5、SHA1、SHA256 和 SHA512 值,确保较短的模式永远不会与较长的模式发生冲突。结果会在扫描运行时实时显示,可导出为 CSV 或 JSON,并自动持久化保存到本地 SQLite 数据库中。内置的“扫描历史记录”对话框允许您按日期范围筛选过去的扫描,并将任何以前的结果集重新加载到主 UI 中,以便重新检查或重新导出。 image ## 支持的文件类型 | 扩展名 | 文本提取方式 | |-----------|----------------------| | `.pdf` | 通过 `pypdf` 提取页面文本 | | `.txt` | 纯文本,UTF-8 编码,回退至 latin-1 | | `.log` | 纯文本,UTF-8 编码,回退至 latin-1 | | `.md` | 纯文本,UTF-8 编码,回退至 latin-1 | | `.csv` | 将所有单元格的值连接为可搜索的文本 | | `.json` | 递归遍历——所有的键和标量值 | | `.xml` | 所有元素文本及其尾部文本 | | `.docx` | Word 文档正文——提取自 `word/document.xml` 的段落文本 | | `.xlsx` | Excel 单元格文本——包含共享字符串表和内联工作表字符串 | | `.pptx` | PowerPoint 幻灯片文本——提取自每个 `ppt/slides/slideN.xml` 的段落运行内容 | 扩展名匹配不区分大小写。具有其他扩展名的文件将被忽略。 Office 格式(`.docx`、`.xlsx`、`.pptx`)使用 Python 标准库直接从其底层的 OpenXML zip 包中读取——在运行时不需要第三方 Office 库。在段落或单元格中跨越多个运行拆分的文本会被重新组合,因此被创作工具拆分成多段的哈希值仍然能够被匹配到。范围说明:`.docx` 读取主文档正文(不包括页眉、页脚或脚注);`.xlsx` 读取所有工作表中的字符串单元格(数字单元格永远不会包含哈希字符串);`.pptx` 读取幻灯片正文(不包括演讲者备注或母版)。 ## 支持的哈希类型 | 算法 | 十六进制长度 | |-----------|-----------| | MD5 | 32 | | SHA1 | 40 | | SHA256 | 64 | | SHA512 | 128 | ## 功能特性 - 在一次扫描中检测所有支持文件类型中的 MD5、SHA1、SHA256 和 SHA512 哈希值。 - 递归目录搜索——包含所选文件夹下的所有受支持文件。 - 多线程提取确保 GUI 在长时间扫描期间保持响应。 - 结果表包含四列:**源文件**、**文件类型**、**哈希类型** 和 **哈希值**。 - 隔行变色,并且每一列都可以通过拖动其标题边框由用户调整大小。 - 较长的源路径会在中间显示省略号(保持驱动器号和文件名可见),并且在悬停时会以工具提示的形式显示完整路径。 - 进度条会根据处理的文件进行更新。 - 扫描摘要面板显示已扫描的文件、找到的哈希数以及跳过的文件。 - **导出 CSV** 按钮可在扫描完成后将结果保存到您选择的 CSV 文件中。 - **导出 JSON** 按钮可在扫描完成后将结果保存到您选择的 JSON 文件中。 - 在扫描成功完成之前,导出按钮处于禁用状态;加载历史扫描记录后会重新启用它们。 - **扫描历史记录** 按钮可打开存储在本地数据库中的、可筛选的过去扫描列表。 - 每次完成的扫描都会自动持久化到本地 SQLite 数据库(`hashharvest.db`)中。 - 历史扫描结果可以重新加载到主 UI 中,并像最新扫描一样进行导出。 - 清除表单按钮可重置所有输入、结果、进度、摘要字段和导出按钮。 - 同一文件内的重复哈希值只会写入一次。 - 被跳过的文件(不可读或格式错误)会被计数,但不会中断扫描。 ## 要求 - Python 3 - `pypdf` - `PyQt5` Office(`.docx`/`.xlsx`/`.pptx`)解析仅使用 Python 标准库,因此不会增加任何运行时依赖。 从项目根目录安装依赖项: ``` python -m pip install -r requirements.txt ``` ## 运行应用程序 ``` cd C:\path\to\HashHarvest python -m hashharvest.main ``` ### GUI 控件 | 控件 | 描述 | |---------|-------------| | **输入目录** 字段 | 输入或浏览至包含要扫描文件的文件夹。 | | **选择输入文件夹** | 为输入目录打开一个文件夹选择器。 | | **哈希类型** 复选框 | 选择要扫描的算法(MD5、SHA1、SHA256、SHA512)。默认全部勾选。 | | **开始扫描** | 验证输入目录并开始多线程扫描。 | | **清除表单** | 重置所有字段、结果表、进度条和摘要计数。 | | **扫描历史记录** | 打开“扫描历史记录”对话框以浏览和重新加载过去的扫描记录。 | | **导出 CSV** | 打开保存对话框并将当前结果写入 CSV 文件。在扫描成功或加载历史记录后启用。 | | **导出 JSON** | 打开保存对话框并将当前结果写入 JSON 文件。在扫描成功或加载历史记录后启用。 | 您可以直接在输入目录字段中输入路径,而无需使用文件夹选择器。 ## 扫描历史记录 每次扫描完成后,结果都会自动保存到 `hashharvest.db`(位于可执行文件或脚本旁写入的 SQLite 文件)中。点击 **扫描历史记录** 以打开历史记录对话框。 ### 历史记录对话框 | 列名 | 描述 | |--------|-------------| | 日期 / 时间 | 运行扫描时的时间戳(截断到分钟)。 | | 目录 | 被扫描的输入目录。 | | 文件 | 已处理的文件数量。 | | 找到的哈希数 | 提取的哈希总数。 | 使用 **显示** 下拉菜单按时间范围筛选: | 选项 | 显示的扫描记录范围 | |--------|-----------------| | 今天 | 当天午夜起 | | 过去 7 天 | 滚动的 7 天时间窗口 | | 过去 30 天 | 滚动的 30 天时间窗口(默认) | | 过去 90 天 | 滚动的 90 天时间窗口 | | 所有时间 | 整个数据库 | 选择一行并点击 **加载选中项** 即可将这些结果恢复到主窗口中。结果表、摘要计数和导出按钮将像实时扫描后一样被完全填充。 ## 导出结果 不会自动写入任何文件。在扫描完成后(或加载历史扫描记录后),使用导出按钮以您首选的格式保存结果。 ### CSV 列名:`Absolute_Path`、`Hash_Type`、`Hash_Value`。 ``` Absolute_Path,Hash_Type,Hash_Value C:\path\to\report.pdf,MD5,44d88612fea8a8f36de82e1278abb02f C:\path\to\alerts.log,SHA1,da39a3ee5e6b4b0d3255bfef95601890afd80709 C:\path\to\iocs.json,SHA256,e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ``` ### JSON 一个扁平的对象数组,每找到一个哈希值对应一条记录。 ``` [ { "absolute_path": "C:\\path\\to\\report.pdf", "hash_type": "MD5", "hash_value": "44d88612fea8a8f36de82e1278abb02f" }, { "absolute_path": "C:\\path\\to\\alerts.log", "hash_type": "SHA1", "hash_value": "da39a3ee5e6b4b0d3255bfef95601890afd80709" } ] ``` | 字段 | 描述 | |-------|-------------| | `absolute_path` / `Absolute_Path` | 包含哈希值的源文件在文件系统中的完整路径。 | | `hash_type` / `Hash_Type` | 匹配的算法:`MD5`、`SHA1`、`SHA256` 或 `SHA512`。 | | `hash_value` / `Hash_Value` | 小写十六进制哈希字符串。 | ## 实现说明 [extractor.py](hashharvest/extractor.py) 中的 `HashHarvest` 没有 GUI 依赖,可以独立使用。 ``` from hashharvest.extractor import HashHarvest extractor = HashHarvest(directory="/path/to/files") results = extractor.extract() # 结果: {file_path: (hash_type, hash_value) tuples 的集合} extractor.export_csv("/path/to/output.csv") extractor.export_json("/path/to/output.json") ``` 文件读取由 [readers.py](hashharvest/readers.py) 处理,该模块也可以直接使用: ``` from hashharvest.readers import read_file, SUPPORTED_EXTENSIONS text = read_file("/path/to/report.json") # returns extracted text as a string print(SUPPORTED_EXTENSIONS) # {'.pdf', '.txt', '.log', '.md', '.csv', '.json', '.xml', '.docx', '.xlsx', '.pptx'} ``` 数据库持久化由 [persistence/db.py](hashharvest/persistence/db.py) 处理: ``` from hashharvest.persistence.db import HashDatabase db = HashDatabase("hashharvest.db") # 检索过去 30 天内的所有扫描 scans = db.get_scans(since="2026-05-01T00:00:00") # 检索给定 scan id 的每个文件的 hash 行 rows = db.get_results(scan_id=1) ``` ### 核心方法 —— HashHarvest | 方法 | 描述 | |--------|-------------| | `dir_exists()` | 如果配置的输入目录存在,则返回 `True`。 | | `read_dir()` | 递归查找输入目录下所有受支持的文件,并已排序。 | | `extract(...)` | 运行完整扫描,触发可选的回调,并返回结果。 | | `export_csv(path)` | 将当前结果写入指定路径的 CSV 文件中。 | | `export_json(path)` | 将当前结果写入指定路径的 JSON 文件中。 | `extract()` 接受三个可选的回调: | 回调 | 签名 | 触发时机 | |----------|-----------|------------| | `progress_callback` | `(int)` | 在每个文件处理完毕后触发(0–100)。 | | `status_callback` | `(str)` | 当文件由于错误被跳过时触发。 | | `result_callback` | `(file_path, file_type, hash_type, hash_value)` | 每次找到哈希值时触发。 | ### 核心方法 —— HashDatabase | 方法 | 描述 | |--------|-------------| | `save_scan(...)` | 将扫描元数据和所有按文件划分的哈希结果持久化到数据库中。 | | `get_scans(since=None)` | 返回扫描记录列表,可选择按 ISO 格式的时间戳进行筛选。 | | `get_results(scan_id)` | 返回给定扫描 ID 对应的按文件划分的所有哈希行。 | [main.py](hashharvest/main.py) 中的 GUI 将这些回调与运行在 `QThread` 中的 `ScanWorker` 发出的 PyQt5 信号连接在一起。 ## 构建独立可执行文件 ``` python -m PyInstaller --clean --onefile --windowed --name HashHarvest --hidden-import PyQt5.sip hashharvest/main.py ``` 数据库文件(`hashharvest.db`)会在运行时写入到编译后的可执行文件旁边。
标签:PyQt5, SQLite, 哈希识别, 恶意活动检测, 数据提取, 文件扫描, 桌面应用, 漏洞挖掘, 逆向工具