PID Namespace
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Informazioni di base
Il PID (Process IDentifier) namespace è una funzionalitĂ del kernel Linux che fornisce isolamento dei processi permettendo a un gruppo di processi di avere il proprio insieme di PIDs unici, separati dai PIDs in altri namespace. Questo è particolarmente utile nella containerizzazione, dove lâisolamento dei processi è essenziale per la sicurezza e la gestione delle risorse.
Quando viene creato un nuovo PID namespace, al primo processo in quel namespace viene assegnato il PID 1. Questo processo diventa il processo âinitâ del nuovo namespace ed è responsabile della gestione degli altri processi allâinterno del namespace. Ogni processo successivo creato nel namespace avrĂ un PID unico allâinterno dello stesso, e questi PIDs saranno indipendenti dai PIDs in altri namespace.
Dal punto di vista di un processo allâinterno di un PID namespace, può vedere solo gli altri processi nello stesso namespace. Non è a conoscenza dei processi in altri namespace e non può interagire con essi usando i tradizionali strumenti di gestione dei processi (es. kill, wait, ecc.). Questo fornisce un livello di isolamento che aiuta a prevenire che i processi interferiscano tra loro.
Come funziona:
- Quando viene creato un nuovo processo (es. usando la system call
clone()), il processo può essere assegnato a un PID namespace nuovo o esistente. Se viene creato un nuovo namespace, il processo diventa il processo âinitâ di quel namespace. - Il kernel mantiene una mappatura tra i PIDs nel nuovo namespace e i corrispondenti PIDs nel namespace parent (cioè il namespace dal quale è stato creato il nuovo namespace). Questa mappatura permette al kernel di tradurre i PIDs quando necessario, ad esempio quando vengono inviati segnali tra processi in namespace diversi.
- I processi allâinterno di un PID namespace possono vedere ed interagire solo con altri processi nello stesso namespace. Non sono a conoscenza dei processi in altri namespace e i loro PIDs sono unici allâinterno del loro namespace.
- Quando un PID namespace viene distrutto (es. quando il processo âinitâ del namespace termina), tutti i processi allâinterno di quel namespace vengono terminati. Questo garantisce che tutte le risorse associate al namespace vengano correttamente liberate.
Laboratorio:
Creare diversi namespace
CLI
sudo unshare -pf --mount-proc /bin/bash
Errore: bash: fork: Impossibile allocare memoria
Quando unshare viene eseguito senza lâopzione -f, si verifica un errore dovuto al modo in cui Linux gestisce i nuovi PID (Process ID) namespaces. I dettagli principali e la soluzione sono riportati di seguito:
- Spiegazione del problema:
- Il kernel Linux permette a un processo di creare nuovi namespace usando la system call
unshare. Tuttavia, il processo che avvia la creazione di un nuovo PID namespace (denominato processo âunshareâ) non entra nel nuovo namespace; solo i suoi processi figli vi entrano. - Lanciare %unshare -p /bin/bash% avvia
/bin/bashnello stesso processo diunshare. Di conseguenza,/bin/bashe i suoi processi figli rimangono nel namespace PID originale. - Il primo processo figlio di
/bin/bashnel nuovo namespace diventa PID 1. Quando questo processo termina, innesca la pulizia del namespace se non ci sono altri processi, poichĂŠ PID 1 ha il ruolo speciale di adottare i processi orfani. Il kernel Linux disabiliterĂ quindi lâallocazione di PID in quel namespace.
- Conseguenza:
- Lâuscita di PID 1 in un nuovo namespace porta alla rimozione del flag
PIDNS_HASH_ADDING. Questo fa sĂŹ che la funzionealloc_pidnon riesca ad allocare un nuovo PID quando viene creato un nuovo processo, producendo lâerrore âImpossibile allocare memoriaâ.
- Soluzione:
- Il problema può essere risolto usando lâopzione
-fconunshare. Questa opzione fa sĂŹ cheunshareesegua un fork di un nuovo processo dopo aver creato il nuovo PID namespace. - Eseguire %unshare -fp /bin/bash% garantisce che il comando
unsharestesso diventi PID 1 nel nuovo namespace./bin/bashe i suoi processi figli saranno cosĂŹ contenuti in modo sicuro allâinterno di questo nuovo namespace, evitando lâuscita prematura di PID 1 e permettendo la normale allocazione dei PID.
Assicurandosi che unshare venga eseguito con il flag -f, il nuovo PID namespace viene mantenuto correttamente, permettendo a /bin/bash e ai suoi sotto-processi di operare senza incontrare lâerrore di allocazione della memoria.
Montando una nuova istanza del filesystem /proc usando il parametro --mount-proc, si garantisce che il nuovo mount namespace abbia una visione accurata e isolata delle informazioni di processo specifiche di quel namespace.
Docker
docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash
Controlla in quale namespace si trova il tuo processo
ls -l /proc/self/ns/pid
lrwxrwxrwx 1 root root 0 Apr 3 18:45 /proc/self/ns/pid -> 'pid:[4026532412]'
Individuare tutti i PID namespaces
sudo find /proc -maxdepth 3 -type l -name pid -exec readlink {} \; 2>/dev/null | sort -u
Nota che lâutente root del PID namespace iniziale (predefinito) può vedere tutti i processi, anche quelli nei nuovi PID namespaces; per questo possiamo vedere tutti i PID namespaces.
Entrare in un PID namespace
nsenter -t TARGET_PID --pid /bin/bash
Quando entri allâinterno di un PID namespace dal namespace predefinito, sarai comunque in grado di vedere tutti i processi. E il processo di quel PID ns sarĂ in grado di vedere la nuova bash nel PID ns.
Inoltre, puoi solo entrare in un altro PID namespace di processo se sei root. E non puoi entrare in un altro namespace senza un descrittore che punti ad esso (come /proc/self/ns/pid)
Note recenti di sfruttamento
CVE-2025-31133: abuso di maskedPaths per raggiungere i PID dellâhost
runc â¤1.2.7 consentiva ad attaccanti che controllano immagini container o workload runc exec di sostituire /dev/null lato container appena prima che il runtime mascherasse voci sensibili di procfs. Quando la race ha successo, /dev/null può diventare un symlink che punta a qualsiasi percorso dellâhost (per esempio /proc/sys/kernel/core_pattern), quindi il nuovo PID namespace del container eredita improvvisamente accesso in lettura/scrittura alle impostazioni globali di procfs dellâhost anche se non ha mai lasciato il proprio namespace. Una volta che core_pattern o /proc/sysrq-trigger sono scrivibili, generare un coredump o triggerare SysRq permette lâesecuzione di codice o denial of service nel PID namespace dellâhost.
Flusso di lavoro pratico:
- Costruisci un OCI bundle il cui rootfs sostituisce
/dev/nullcon un link al percorso dellâhost che vuoi (ln -sf /proc/sys/kernel/core_pattern rootfs/dev/null). - Avvia il container prima della patch in modo che runc effettui un bind-mount del target procfs dellâhost sopra il link.
- Allâinterno del namespace del container, scrivi nel file procfs ora esposto (es., punta
core_patterna un reverse shell helper) e fai crashare qualsiasi processo per costringere il kernel dellâhost a eseguire il tuo helper nel contesto PID 1.
Puoi rapidamente verificare se un bundle sta mascherando i file corretti prima di avviarlo:
jq '.linux.maskedPaths' config.json | tr -d '"'
Se il runtime manca di una voce di mascheramento che ti aspetti (o la salta perchĂŠ /dev/null è scomparso), considera il container come potenzialmente in grado di vedere i PID dellâhost.
Iniezione di namespace con insject
NCC Groupâs insject viene caricato come payload LD_PRELOAD che aggancia una fase tardiva del programma target (predefinito main) ed esegue una sequenza di chiamate setns() dopo execve(). Questo permette di attaccarsi dallâhost (o da un altro container) al PID namespace della vittima dopo lâinizializzazione del suo runtime, preservandone la vista di /proc/<pid> senza dover copiare binari nel filesystem del container. PoichĂŠ insject può differire lâentrata nel PID namespace fino al fork, puoi mantenere un thread nel namespace host (con CAP_SYS_PTRACE) mentre un altro thread esegue nel PID namespace target, creando potenti primitive di debugging o offensive.
Esempio di utilizzo:
sudo insject -S -p $(pidof containerd-shim) -- bash -lc 'readlink /proc/self/ns/pid && ps -ef'
Punti chiave quando si sfrutta o si difende contro namespace injection:
- Usa
-S/--strictper forzareinsjectad abortire se threads esistono giĂ o se namespace joins falliscono; altrimenti potresti lasciare threads parzialmente migrati che si estendono attraverso gli spazi PID dellâhost e del container. - Non collegare mai strumenti che mantengono ancora writable host file descriptors a meno che non ti unisca anche al mount namespace â altrimenti qualsiasi processo allâinterno del PID namespace può ptrace il tuo helper e riutilizzare quei file descriptor per manomettere le risorse dellâhost.
Riferimenti
- https://stackoverflow.com/questions/44666700/unshare-pid-bin-bash-fork-cannot-allocate-memory
- container escape via âmasked pathâ abuse due to mount race conditions (GitHub Security Advisory)
- Tool Release â insject: A Linux Namespace Injector (NCC Group)
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
HackTricks

