4、凭据扫描工具实战:使用 TruffleHog、GitLeaks 扫描 Git 仓库中的泄露凭据

凭据泄露,说白了就是你的密码、Token、密钥被不小心写进了代码里。我见过太多工厂因为一个硬编码的数据库密码,导致整个生产网络被渗透。今天我们就来聊聊怎么用 TruffleHog 和 GitLeaks 这两个工具,把藏在 Git 历史里的“定时炸弹”挖出来。

4.1 为什么 Git 仓库是凭据泄露的重灾区?

你想想看,一个工厂的 IT/OT 融合项目,代码仓库里可能有什么?PLC 的通信密钥、SCADA 系统的数据库连接串、MES 系统的 API Token……这些东西一旦被提交到 Git,哪怕后来删掉了,历史记录里还留着。攻击者只要拿到仓库的访问权限,就能翻出这些凭据。

我在一家汽车零部件工厂做审计时,就遇到过这种情况。工程师为了方便,把 OPC UA 服务器的用户名密码直接写在了配置文件的注释里,还提交到了 GitLab。幸好我们及时发现,否则后果不堪设想。

⚠️ 核心风险点:
  • Git 历史记录不可篡改(除非强制 rebase 或 filter-branch)
  • 凭据可能存在于多个分支、标签、提交中
  • 即使删除了文件,二进制对象仍保留在 .git 目录中

4.2 TruffleHog:深度扫描 Git 历史的“猎犬”

TruffleHog 是我个人最常用的工具之一。它的原理很简单——扫描 Git 仓库的每一次提交,检查是否有高熵值字符串(比如 Base64 编码的密钥)或者已知模式的凭据(比如 AWS Key、GitHub Token)。

4.2.1 安装与基础使用

# 使用 pip 安装
pip install trufflehog

# 扫描本地仓库
trufflehog git file:///path/to/your/repo --json

# 扫描远程仓库
trufflehog git https://github.com/your/repo.git --only-verified

这里有个关键参数 --only-verified。我建议你在生产环境中一定要加上它。为什么?因为 TruffleHog 会调用对应的 API 去验证扫描到的凭据是否真的有效,能大幅降低误报率。

💡 我的习惯: 扫描结果输出为 JSON 格式,方便后续导入 SIEM 或自动化处理。比如用 jq 工具过滤出高严重性的结果。

4.2.2 实战案例:扫描工厂 MES 系统仓库

假设我们有一个工厂 MES 系统的 Git 仓库,里面可能包含数据库连接信息。我们这样操作:

trufflehog git https://gitlab.plant.local/mes/production.git \
  --only-verified \
  --json \
  --since-commit HEAD~100 \
  > trufflehog_report.json

扫描完成后,用 jq 提取关键信息:

cat trufflehog_report.json | jq 'select(.severity == "high") | {source, detector, raw}'

我曾经用这个命令,在一个工厂的仓库里找到了 3 个有效的 AWS Secret Key。那个工程师把密钥写在了 Dockerfile 的环境变量里,还提交了 20 多个版本。要不是 TruffleHog 扫出来,这些密钥可能到现在还在泄露。

4.3 GitLeaks:轻量级、规则驱动的扫描器

GitLeaks 和 TruffleHog 的思路不太一样。它更像一个规则引擎,通过预定义的正则表达式和路径模式来匹配凭据。优点是速度快、规则可定制,适合集成到 CI/CD 流水线中。

4.3.1 安装与基础使用

# macOS
brew install gitleaks

# Linux
wget https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks-linux-amd64
chmod +x gitleaks-linux-amd64
sudo mv gitleaks-linux-amd64 /usr/local/bin/gitleaks

# 扫描本地仓库
gitleaks detect --source /path/to/repo -v

# 扫描远程仓库
gitleaks detect --source https://github.com/your/repo.git --no-git

4.3.2 自定义规则:适配工厂场景

GitLeaks 默认的规则集主要针对互联网常见的凭据类型。但工厂环境有很多特有的凭据格式,比如西门子 PLC 的通信密钥、罗克韦尔的 Tag 密码等。这时候就需要自定义规则了。

创建一个 .gitleaks.toml 文件:

title = "工厂凭据扫描规则"

[[rules]]
id = "siemens-plc-key"
description = "西门子 PLC 通信密钥"
regex = '''(S7-1200|S7-1500)_KEY_[A-Za-z0-9]{32}'''
tags = ["plc", "siemens"]

[[rules]]
id = "opc-ua-password"
description = "OPC UA 连接密码"
regex = '''(Password|Pwd)\s*[:=]\s*['"][A-Za-z0-9!@#$%^&*]{8,}['"]'''
tags = ["opcua", "scada"]

[allowlist]
paths = [
  '''(vendor|third_party|node_modules)''',
  '''\.git'''
]

然后运行:

gitleaks detect --source /path/to/repo --config .gitleaks.toml
🔑 关键点: 自定义规则是 GitLeaks 的核心优势。我建议每个工厂团队都维护一套自己的规则库,覆盖 PLC、SCADA、MES、数据库等常见凭据类型。

4.4 两种工具的对比与选型建议

特性 TruffleHog GitLeaks
扫描方式 基于熵值 + 模式匹配 基于正则规则
验证能力 支持(--only-verified) 不支持(需配合其他工具)
速度 较慢(深度扫描历史) 较快(规则匹配)
自定义规则 较复杂 简单(TOML 配置)
CI/CD 集成 支持 原生支持(pre-commit hook)
误报率 中等(验证后降低) 低(规则精准)

我个人建议:日常开发用 GitLeaks 做 pre-commit 检查,定期用 TruffleHog 做全量历史扫描。两者互补,效果最好。

4.5 扫描结果处理与修复流程

扫描出凭据只是第一步,怎么处理才是关键。我曾经见过一个团队,扫出凭据后直接删文件重新提交,结果历史记录里还留着。正确的做法是:

  1. 立即撤销/轮换凭据:通知相关系统管理员,生成新凭据并更新配置。
  2. 从 Git 历史中彻底清除:使用 git filter-branch 或 BFG Repo-Cleaner 重写历史。
  3. 强制推送并通知所有协作者:rebase 或重新 clone 仓库。
  4. 更新 CI/CD 流水线:加入凭据扫描步骤,防止再次发生。
⚠️ 注意: 重写 Git 历史会影响所有协作者。操作前一定要通知团队,并做好备份。我曾经因为没通知到位,导致一个同事本地分支全部失效,加班到凌晨才恢复。

4.6 知识体系:凭据扫描的核心逻辑

下面这张图展示了凭据扫描的整体流程和工具定位,你可以对照着理解:

凭据扫描工具实战知识体系 凭据扫描工具实战知识体系 Git 仓库输入 TruffleHog GitLeaks 熵值检测 + 模式匹配 支持 API 验证(--only-verified) 正则规则匹配 支持自定义 TOML 规则 扫描报告(JSON / 控制台输出) 凭据轮换 + Git 历史重写 建议:GitLeaks 用于 pre-commit TruffleHog 用于定期全量扫描

4.7 避坑指南:我踩过的几个坑

  • 不要只扫当前分支:凭据可能藏在旧分支或标签里。记得加 --all 参数。
  • 别忽略二进制文件:有些凭据藏在图片、PDF 或压缩包里。TruffleHog 默认会扫描二进制文件,但 GitLeaks 需要额外配置。
  • 扫描结果要人工复核:自动工具难免有误报。我见过把随机生成的 UUID 当成 AWS Key 的情况。
  • 定期扫描 vs 实时扫描:两者都要做。实时扫描靠 pre-commit hook,定期扫描靠定时任务。
📌 我的建议: 在工厂的 GitLab/GitHub 企业版中,可以配置 Webhook 自动触发扫描。每次 push 都跑一次 GitLeaks,发现凭据直接阻止合并请求。这样能把风险扼杀在摇篮里。