Writeup 4 N1BOOK 第一章 Web 入门 · 粗心的小李

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 做了什么

  1. 读 /.git/HEAD、/.git/config
  2. 解析出所有需要的对象文件路径
  3. 逐个下载
  4. 在本地组装成完整 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 泄露题,按这个顺序走:

  1. /.git/HEAD → 确认泄露
  2. .git/config、.git/index → 确认文件可读
  3. git-dumper / GitHack → 还原仓库
  4. git log --oneline --all → 看所有提交
  5. git show <hash> / git log -p → 看具体改动
  6. 没有 → git fsck --lost-found → 找悬空对象
  7. 再没有 → git show-ref、git stash list、.git/logs/HEAD → 兜底
  8. flag 可能在:最新 commit / 历史 commit / 被删的 blob / 其他分支 / stash

9. 防御建议

  1. 不要部署 .git 到线上 :部署时排除 .git、.svn、.hg 等版本控制目录
  2. Web 服务器禁止访问敏感目录 :Apache/Nginx 配置规则拦截 .git
  3. 部署前检查:CI/CD 流程里加一步,扫描并剔除敏感文件
  4. 权限最小化:Web 目录不应包含源码、密钥、配置等敏感文件

10. 最后一句复盘

这道题最值得记住的不是 payload,而是两个"看似没戏、其实有戏"的转折点:

.git/ 403,但 .git/HEAD 可读;git show 停在 (END),其实已经显示完了。

信息搜集题里,很多"卡住"只是访问方式或认知的问题,不是真的走不通。

Rambo

2026年10月08日

🎉🎉🎉

相关推荐
hengdonghui2 天前
Writeup 4 N1BOOK afr_2
ctf·目录穿越
print_Hyon3 天前
【CTF-CRYPTO-教学-RSA】第十三节:知道e、p和q的变形表达式,解密c
ctf
print_Hyon3 天前
【CTF-CRYPTO-教学-RSA】第七节:低加密指数攻击,已知n和e求c(e很小,m的e次方比n小,c可直接开方得到结果)
ctf
hengdonghui6 天前
Writeup 4 N1BOOK afr_1
ctf·伪协议·任意文件读取
hengdonghui6 天前
Writeup 4 N1BOOK 常见的搜集
ctf·信息搜集
hengdonghui7 天前
Writeup 4 N1BOOK SQL注入-1
ctf·sql注入·union·字符型注入
hengdonghui8 天前
Writeup 4 红帽杯 2021 WebsiteManger
web·ctf·ssrf·sql布尔盲注
hengdonghui10 天前
Writeup 4 2020 - 之江杯 - 异常的流量分析
wireshark·ctf·流量分析
hengdonghui10 天前
Writeup 4 津门杯 2021 Web hate_php
php·web·ctf·通配符