flawopen.com/Teardowns/CVE-2024-32002

CVE-2024-32002: Git Submodule Symlink RCE

Critical 9.8 CWE-78 / CWE-59 Git < 2.45.1
Languages: en pt-br es fr de ru zh-cn ja hi ko id
쉬운 비유 —— 사무실의 기만적인 안내판

사내 배달원이 '101호'로 중요 서류를 배달하는 상황을 상상해 보십시오. 공격자가 101호 문에 '101호는 임원 전용 금고실로 이전했습니다'라는 가짜 팻말을 붙였습니다. 배달원은 의심 없이 화살표를 따라 금고실 안에 서류를 넣었습니다. Git에서 배달원은 서브모듈 클론 프로세스였고, 가짜 팻말은 심볼릭 링크였으며, 금고실은 스크립트가 자동 실행되는 숨김 폴더 .git/hooks/ 였습니다.

Target: Git core CLI
Vector: git clone --recursive <url>
Impact: Remote Code Execution (RCE)
Platform: macOS & Windows (Case-Insensitive Filesystems)

치명적인 Git 소스 코드 패치 Diff

builtin/submodule--helper.cdir.c에서 Git은 서브모듈 클론 경로의 상위 디렉터리가 작업 트리 외부를 가리키는 심볼릭 링크인지 검증하지 않았습니다.

builtin/submodule--helper.c (Vulnerable)Vulnerable
// Git clone created submodule directory blindly
static int clone_submodule(const struct module_clone_data *clone_data)
{
    struct strbuf sb = STRBUF_INIT;

    // BUG: clone_data->path could traverse an existing symlink
    strbuf_addf(&sb, "%s", clone_data->path);
    safe_create_leading_directories(sb.buf);
    return do_clone(clone_data);
}
builtin/submodule--helper.c (Fixed)Patched
// Fixed: Refuse to clone into or through symlinked path components
static int clone_submodule(const struct module_clone_data *clone_data)
{
    struct strbuf sb = STRBUF_INIT;

    // FIX: Validate that no parent component is a symlink
    if (path_has_symlinks(clone_data->path))
        die(_("fatal: submodule path '%s' contains a symlink"),
            clone_data->path);

    strbuf_addf(&sb, "%s", clone_data->path);
    return do_clone(clone_data);
}

3단계 익스플로잇 흐름

엔지니어가 기억해야 할 핵심 원칙

Explore more vulnerability mechanisms & language matrices: Command Injection Matrix →