L'azienda Qualys ha individuato due vulnerabilità negli strumenti apport (CVE-2025-5054) e systemd-coredump (CVE-2025-4598), utilizzati per gestire i core dump generati dopo il crash dei processi. Le vulnerabilità consentono di accedere ai core dump salvati dopo il crash di applicazioni suid o di alcuni processi di sistema in background, la cui memoria potrebbe contenere credenziali memorizzate o chiavi di crittografia. Lo strumento apport viene automaticamente attivato per salvare i core dump in Ubuntu, mentre systemd-coredump è utilizzato in Red Hat Enterprise Linux 9+, Fedora e in molte altre distribuzioni Linux.
È stata dimostrata una tecnica di attacco in cui sono state create condizioni per il crash dell'applicazione suid unix_chkpwd e per accedere al core dump dello stato durante il crash. Nel core dump salvato erano presenti gli hash delle password degli utenti del sistema, rimasti in memoria dopo che il processo era andato in crash, a seguito del caricamento del contenuto di /etc/shadow. La possibilità di sfruttare queste vulnerabilità è stata dimostrata in Ubuntu 24.04 e Fedora 40/41, ma si presume che altre distribuzioni siano vulnerabili a simili attacchi.
Entrambe le vulnerabilità sono causate da una condizione di competizione che consente di sostituire il processo suid andato in crash con un altro processo nel momento immediatamente dopo l'inizio della gestione del crash da parte del kernel, ma prima che il gestore controlli i parametri del processo nello spazio utente tramite /proc/pid/files. La chiamata a apport e systemd-coredump si effettua come segue: il kernel, dopo aver ricevuto l'informazione sul crash del processo, invoca il gestore specificato nel file /proc/sys/kernel/core_pattern, trasferendo quindi il contenuto del core dump attraverso il flusso di input.
La generazione del core dump e l'avvio del gestore non avvengono istantaneamente e questo tempo è sufficiente per sostituire il processo suid andato in crash con un normale processo utente. In caso di sostituzione, il gestore dei core dump avviato penserà che il crash sia avvenuto non in un processo suid, ma in un'applicazione utente normale e, di conseguenza, salverà il core file con accessibilità per un utente normale, e non solo per l'amministratore.
L'attacco a apport si articola nei seguenti passaggi:
- Viene ramificato un nuovo processo e viene chiamata la funzione execve() per avviare un programma suid, come unix_chkpwd.
- Viene trascurato il tempo necessario per caricare dalla programma suid i dati riservati in memoria (nel caso di unix_chkpwd ci si aspetta di caricare gli hash delle password di tutti gli utenti di sistema dal file /etc/shadow).
- Prima della fine dell'esecuzione del comando, al processo viene inviato un segnale SIGSEGV o SIGSYS per il termine anomalo.
- In risposta al termine anomalo, il kernel genera un core dump e avvia il processo apport per elaborare il core dump nello spazio utente.
- Dopo l'avvio di apport, ma prima che inizi l'analisi, al processo terminato anomalo viene inviato un segnale SIGKILL e il processo stesso viene sostituito da un altro senza il flag suid. Per aggirare i controlli in apport, il nuovo processo viene creato all'interno di spazi dei nomi separati (user, pid e mount namespace).
- Apport si connette al socket unix /run/apport.socket nello spazio dei nomi di punti di montaggio creato per il nuovo processo e invia un descrittore di file per accedere al core dump.
Per ottenere per il nuovo processo il necessario identificatore che corrisponde all'identificatore del processo suid, prima di inviare il segnale SIGSEGV, il processo suid viene fermato con il segnale SIGSTOP e durante la pausa vengono avviati ciclicamente nuovi processi fino a ottenere un PID con un numero precedente, vicino a quello del processo suid da sostituire. Dopo lo spostamento della numerazione PID, ai segnali SIGSEGV e SIGCONT viene inviato il processo suid, dopo di che viene inviato SIGKILL e ciclicamente vengono avviati nuovi processi per raggiungere lo stesso PID del processo suid.
Per quanto riguarda systemd-coredump, da un lato è più semplice condurre un attacco contro di esso, poiché non è necessario sostituire il processo suid con un processo in uno spazio utente separato e basta ottenere una corrispondenza tra AT_UID e AT_EUID. D'altra parte, systemd-coredump è scritto in C e viene eseguito piuttosto rapidamente, il che fornisce meno tempo per la sostituzione, a differenza di apport, che è scritto in Python e nel processo di inizializzazione carica vari file pyc. Questo problema viene risolto rallentando artificialmente systemd-coredump: quando si invoca un file suid viene passato un numero molto elevato di argomenti della riga di comando, creando la necessaria latenza durante l'analisi di /proc/pid/cmdline.
Durante l'analisi delle vulnerabilità, i ricercatori hanno anche scoperto che systemd-coredump, durante la configurazione della chiamata, non specifica nel /proc/sys/kernel/core_pattern il flag "%d", il che consente a un attaccante di forzare il crash di processi in background eseguiti con diritti di root, che generano altri processi cambiando l'identificatore utente in un utente non privilegiato sotto cui viene effettuato l'attacco. Tale possibilità consente di eseguire attacchi non solo su applicazioni setuid, ma anche su processi come sshd-session (OpenSSH), sd-pam (systemd) e cron, per ottenere dati riservati memorizzati nella loro memoria, come chiavi private, hash delle password da /etc/shadow, etichette di canarini dallo stack e dati per eludere la randomizzazione dello spazio degli indirizzi (ASLR).
Si possono seguire gli aggiornamenti dei pacchetti nelle distribuzioni alle seguenti pagine: Debian, Ubuntu, RHEL, openSUSE, Fedora, Gentoo, Arch. Come soluzione per bloccare le vulnerabilità, si consiglia di disabilitare il salvataggio dei core dump per i programmi suid e per i processi che azzerano i privilegi, impostando il parametro /proc/sys/fs/suid_dumpable a 0. Per risolvere completamente il problema è necessaria una modifica al kernel Linux, che implementa la possibilità di passare informazioni su un processo terminato in modo anomalo tramite il meccanismo pidfd (pidfd è associato a processi specifici e, a differenza di pid, non viene ripetutamente riassegnato).
Fonte: opennet.ru
