abcreativ/questio

GitHub: abcreativ/questio

一款离线的法医级 PDF 审计 CLI 工具,通过多维度结构特征为文档生成 0-100 信任评分以识别篡改。

Stars: 0 | Forks: 0

# questio:检测篡改文档的取证 PDF 审计工具 在 Word、LibreOffice、Acrobat、Preview、Sejda、Foxit 或其他任何软件中编辑 PDF,都会留下痕迹。不该出现的 Producer 字符串。文档中间被重置的字体标签。堆叠在一起的文件尾标记。questio 会读取所有这些信息,并对文档进行 0 到 100 的评分。 它可以在你的笔记本电脑上运行。永远不会上传任何东西。通用模式无需任何设置即可适用于任何 PDF。只需在你已有的一份真实的银行对账单、发票或合同上对其进行一次训练,questio 就会变得极其精准:它会标记出下一份伪造品中不匹配的确切对象。 没有云。没有共享注册表。没有要求你信任他们的供应商。这也包括我们。 ## 工作原理 ### 1. 编辑器和 Producer 检测 每个 PDF 都带有说明其制作工具的元数据。对于来自银行、公用事业公司、HMRC 或企业软件的官方文件来说,Microsoft Word、LibreOffice、Canva、Apple Pages 和 Google Docs 是不常见的。questio 一旦发现它们就会进行标记。Adobe Acrobat、Foxit、PDF-XChange、Sejda 和 Nitro 是编辑器,而不是生成器。如果其中一个出现在银行对账单的元数据中,说明有人打开过该文件并再次保存了。 **解读:** 如果你的房东发来一份“银行对账单”,但其 Producer 字段显示的是 LibreOffice,这就是工具注意到的线索。 ### 2. 字体会话追踪 每次保存 PDF 时,嵌入的字体会获得一个随机的 6 字符标签(例如 `ABCDEF+Helvetica`)。干净的单会话文档只有一组标签。经过编辑并重新保存的文档会有两组。三次保存过程会留下三组。这种痕迹在扁平化后依然存在,是 questio 拥有的最可靠信号。 **解读:** 如果有人在发票上加了一行伪造的内容,这行假内容通常会带有与其余部分不同的字体标签。即使肉眼无法分辨,questio 也能捕捉到这一点。 ### 3. 修订历史映射 PDF 可以增量保存,从而在文件内留下每次更改的完整堆叠历史。questio 会计算文件尾标记的数量,当发现不止一个时,它会告诉你哪个修订版修改了哪些页面和对象。 **解读:** 三个文件尾标记意味着三次保存过程。干净的原始文件只有一个。 ### 4. Acrobat 编辑签名 Adobe Acrobat 的 Edit Text 工具会留下一种特定的字体对象 (CIDFont)。Microsoft Word、Adobe InDesign、Google Chrome、LibreOffice 和大多数其他生成器从不写入这些内容。如果一个此类对象出现在声称来自不使用它们的生成器的文档中,说明 Acrobat 动过这个文件。 **解读:** 这就是精准捕获。一旦触发,伪造者几乎可以肯定使用了 Acrobat 的 Edit Text 工具。 ### 5. 内容流指纹识别 每个生成器都有自己的绘制习惯:坐标精度、运算符风格、字体引用模式。questio 将这些维度作为指纹进行学习,并将其与存储的签发者配置文件进行比较。 **解读:** 如果一个文档声称来自 InDesign,但却以 Acrobat 的方式绘制文本,说明它被编辑过。 ## questio 拒绝做的事情 - **没有云。** 没有托管版本,没有“questio 专业版”,没有 API key。你的文档永远不会离开你的机器。 - **没有共享指纹注册表。** 指纹保留在你的笔记本电脑上。公开的注册表会成为伪造者的蜜罐:上传一个糟糕的指纹,让真实文件看起来像假的,反之亦然。 - **没有法庭可采性声明。** questio 生成证据和评分。它不产生裁决。可采性是你律师的工作。 - **没有 GUI。** GUI 会吸引寻求裁决结果的用户。questio 的核心意义在于由你来思考。 - **没有遥测。** 没有任何内容被记录、上传或发送到外部。如果你不信任二进制文件,可以通过源代码进行验证。 ## 本地优先:为什么 questio 从不上传你的 PDF 大多数 PDF 检查工具要求你上传文件。这就产生了两个 questio 拒绝继承的问题: 1. **你的敏感文档会到达第三方。** 银行对账单、法律合同、工资单、医疗记录。即使服务承诺删除它们,你也无从验证。 2. **集中的指纹数据库是一种负担。** 任何贡献指纹的人都可能破坏注册表。恶意行为者可能会上传一种指纹,使伪造的文档被评分为真实,反之亦然。 questio 通过完全在你的笔记本电脑上运行来规避这两个问题。你的指纹保存在 `~/.questio/fingerprints/` 中,永远不会离开。你可以通过使用自己验证过的文件来训练该工具,从而决定哪些文档是真实的。信任链的起点和终点都在于你。 ## 安装 ``` pip install questio ``` 或者,如果你想要最新的主分支: ``` pip install git+https://github.com/abcreativ/questio.git ``` **需要**:Python 3.10+,[exiftool](https://exiftool.org/) ``` brew install exiftool # macOS apt install libimage-exiftool-perl # Debian/Ubuntu ``` ## 用法 ### 审计 PDF(默认) ``` questio invoice.pdf ``` **退出码** | 代码 | 含义 | |------|---------| | `0` | 真实:信任分数 >= 80 | | `1` | 可疑:信任分数 50 到 79 | | `2` | 可能被篡改:信任分数 < 50 | | `3` | 错误(找不到文件、缺少 exiftool 等) | **选项** ``` --json Machine-readable JSON output --verbose, -v Full structural dump (font details, content stream fingerprint) --issuer NAME Verify against a stored issuer fingerprint ``` ### 学习签发者指纹 ``` questio learn --issuer three-uk genuine-bill.pdf ``` 对来自同一签发者的几个已知良好样本运行此命令,以构建可靠的指纹。每次 `learn` 调用都会添加到现有的配置文件中,而不是替换它。 ### 针对已知签发者进行验证 ``` questio verify --issuer three-uk suspect-bill.pdf ``` 将可疑文档的结构维度与存储的指纹进行比较,并报告每个维度的置信度分数及任何偏差。 ### 直接比较两个 PDF ``` questio compare reference.pdf suspect.pdf ``` 并排的结构差异比较:字体前缀、内容流指纹、对象计数、元数据字段。当你有一份确认真实的副本可以进行比较时非常有用。 ## 输出示例 ``` $ questio invoice.pdf ================================================================ PDF AUDIT -- invoice.pdf ================================================================ Trust Score: 83/100 ████████████████████████████████░░░░░░░░ Verdict: LIKELY AUTHENTIC Creator: Adobe InDesign 19.0 Producer: Adobe PDF Library 15.0 Created: 2024-03-15T14:22:31+00:00 Modified: 2024-03-15T14:22:35+00:00 Pages: 1 Revisions: 1 (%%EOF markers) Objects: 47 Size: 84 KB Revision Map ---------------------------------------------------------------- Rev 1: 84.2 KB, 47 objects [original] Findings ---------------------------------------------------------------- v Producer Adobe PDF Library 15.0 (trusted) v Font subsets 3 subsets, consistent prefix ABCDEF v Revisions Single revision -- no incremental updates ! Timestamp gap 4s create->modify (low confidence -- sub-minute) v Content stream Matches Adobe InDesign profile v Font types TrueType only -- consistent with declared tool v Object count 47 objects -- within expected range v File structure Cross-reference table valid v Version PDF 1.6 -- consistent with producer v Coord precision 3 decimal places -- matches Adobe profile ``` ## 指纹格式 指纹以 JSON 格式存储在 `~/.questio/fingerprints/.json` 中。每个文件记录了签发者名称、训练样本数,以及观测值数组和结构维度的最小/最大范围:字体子集前缀、内容流运算符分布、坐标精度、字体引用样式、对象计数和 Producer 字符串。 使用 `QUESTIO_HOME` 环境变量覆盖存储目录: ``` QUESTIO_HOME=/team/shared/fingerprints questio verify --issuer acme suspect.pdf ``` 指纹将在首次运行时自动从旧路径 `~/.pdf-audit/fingerprints/` 迁移。 不要从不受信任的来源导入指纹。指纹告诉 questio 应该把什么视为正常。来自恶意行为者的有毒指纹可能会使篡改过的文档被评分为真实。 有关完整的字段参考和手工编写指南,请参阅 [docs/FINGERPRINT_FORMAT.md](docs/FINGERPRINT_FORMAT.md)。 ## 如何检查 PDF 是否被编辑过 1. 安装 questio:`pip install questio` 2. 安装 exiftool(唯一的外部依赖):在 macOS 上运行 `brew install exiftool`,在 Debian/Ubuntu 上运行 `apt install libimage-exiftool-perl`。 3. 运行:`questio suspect.pdf` 4. 阅读信任分数和发现列表。80 分以上通常为真实,50 到 79 分为可疑,50 分以下很可能被篡改。 5. 为了对特定签发者进行精准验证,首先使用来自该签发者的真实文档训练 questio:`questio learn --issuer three-uk real_bill.pdf`。然后根据训练好的指纹验证未来的文档:`questio verify --issuer three-uk suspect_bill.pdf`。 ## 谁在使用 questio - **记者** 检查来源泄露文件的真实性 - **欺诈调查员** 验证发票、费用收据和供应商文件 - **律师助理** 对客户提交的证据进行初步完整性审查 - **会计师** 标记可疑的银行对账单、工资单或税务表格 - **房东和物业经理** 检查收入证明文件 - **小企业主** 验证供应商发票和承包商凭证 - **KYC 和合规团队** 在文档工作流程中加入人工审核前的过滤器 ## 局限性 questio 是一种启发式工具。它根据结构证据做出有根据的猜测。它不能: - 读取 PDF 的视觉内容(它不进行 OCR 识别文本或比较图像) - 检测出在原始文件使用的同一工具中从头开始重新创建的伪造品 - 捕捉在生成 PDF 之前发生的篡改(例如,被篡改的电子表格导出为 PDF) - 证明文档是假的。它只能证明结构证据与文档声明不符。 - 取代人类的判断。在采取行动之前,请务必手动验证发现。 ## 故障排除 **找不到 exiftool** ``` brew install exiftool # macOS apt install libimage-exiftool-perl # Debian/Ubuntu ``` **合法的 PDF 出现误报** 在使用 `questio verify` 之前,对来自同一签发者的几个已知良好样本运行 `questio learn`。由单个样本构建的指纹太窄,会将生成器轻微的变动标记为可疑。实际应用中至少需要三个或以上的样本。 **指纹未加载** 检查 `~/.questio/fingerprints/.json` 是否存在。如果你使用的是旧版本,`~/.pdf-audit/fingerprints/` 中的指纹将在首次运行时自动迁移。你也可以设置 `QUESTIO_HOME` 指向现有的目录。 **安装后找不到 `questio` 命令** 确保你的 Python `bin` 目录在 `PATH` 中。使用 pipx:`pipx install git+https://github.com/abcreativ/questio.git`。 ## 常见问题 **问:如何检查 PDF 创建后是否被编辑过?** 答:运行 `questio document.pdf`。它会对 PDF 进行 0 到 100 的评分,并标记出十类篡改痕迹:不该出现的 Producer 元数据、多次编辑会话堆叠的字体标签、Acrobat 特有的字体签名、多余的文件尾标记、时间戳间隙,以及与声明的生成器不符的内容流模式。 **问:questio 能检测出伪造的银行对账单吗?** 答:能。questio 能捕捉任何常见工具的编辑痕迹:Microsoft Word、LibreOffice、Apple Pages、Canva、Google Docs、Adobe Acrobat、Foxit、PDF-XChange、Sejda。通常多个痕迹会同时触发:Producer 元数据、字体会话标签和时间戳偏移。Acrobat 的编辑工具会在其余痕迹之上触发额外的签名。 **问:questio 会将我的 PDF 发送到云服务吗?** 答:不会。questio 完全在你的机器上运行。它从不进行上传、发送外部请求,也不需要 API key。 **问:questio 能捕捉到哪些肉眼看不到的 PDF 篡改?** 答:跨编辑会话的字体标签偏移、Acrobat 特有的字体对象签名、增量保存历史、不匹配的 Producer 元数据、权限锁定滥用,以及与声明的 PDF 生成器不一致的字节级绘制指令。 **问:questio 是免费且开源的吗?** 答:是的。MIT 许可的 Python CLI。使用 pip 安装,针对任何 PDF 运行,无需账户。 ## 许可证 MIT (c) 2026 ABCreativ ## 免责声明 questio 是一种启发式的取证工具。其输出不是法律证据,不可在法庭上作为证据使用。它产生分数和结构异常列表。它不产生裁决。在做出任何指控或决定之前,请务必手动验证发现。作者对不正确的结果不承担任何责任。
标签:PDF解析, 命令行工具, 安全工具, 数字取证, 文件完整性分析, 自动化脚本, 防伪检测