Cosa fa#
Un processo e' un'istanza di un programma in esecuzione. Il kernel assegna a ogni processo un PID univoco, uno spazio di memoria isolato e un posto nella coda CPU. Il multitasking non e' simultaneo — il kernel switcha cosi' velocemente tra i processi da sembrare parallelo.
TL;DR#
programma su disco ──fork()──► processo figlio in memoria
│
PID univoco (crescente)
UID = utente che lo ha lanciato
stato: R / S / D / Z
padre: ogni processo ha un PPIDIl kernel non fa piu' cose insieme — assegna fette di CPU a turno. systemd (PID 1) e' sempre il primo processo, padre di tutti gli altri.
La gerarchia — albero dei processi#
Ogni processo ha un padre (PPID). La catena risale sempre a PID 1.
PID 1 — systemd
│
├── PID 234 — sshd
│ └── PID 891 — bash (sessione utente)
│ └── PID 1204 — ps (comando lanciato)
│
├── PID 312 — cron
│ └── PID 1100 — script.sh (job schedulato)
│
└── PID 445 — nginx
├── PID 446 — nginx worker
└── PID 447 — nginx workerSe un processo padre termina prima del figlio, il figlio diventa orphan e viene adottato da systemd (PID 1).
Se un processo figlio termina ma il padre non lo raccoglie con wait(), rimane come zombie — occupa una entry nella tabella processi senza usare risorse reali.
Il ciclo di vita#
fork() exec() exit()
│ │ │
processo padre carica il nuovo processo termina
crea una copia programma in manda SIGCHLD al padre
di se stesso memoria padre chiama wait()
(il figlio) (sovrascrive) entry rimossa dalla tabellaStati del processo#
RUNNABLE ◄─── I/O completato
│
scheduler CPU
│
RUNNING
│
┌───────┴──────────┐
│ │
I/O wait CTRL+Z
│ SIGSTOP
▼ │
WAITING STOPPED
(stato D) │
SIGCONT
│
RUNNABLE| Stato | Codice ps | Significato |
|---|---|---|
| Running | R | In esecuzione o in coda CPU |
| Sleeping | S | In attesa di evento — la maggior parte |
| Waiting | D | Attesa I/O disco — non interrompibile |
| Stopped | T | Sospeso da SIGSTOP o CTRL+Z |
| Zombie | Z | Terminato, non ancora raccolto dal padre |
PID e PPID#
echo $$ # PID della shell corrente
echo $PPID # PPID — PID del processo padre
# PID 1 = sempre systemd/init
# PID assegnati in ordine crescente fino a ~32768, poi ricomincia da 2
# Risalire la catena padre-figlio
pstree -p 4821 # mostra l'albero a partire dal PID 4821Segnali — come kernel e utenti comunicano con i processi#
utente kernel processo
│ │ │
│ kill -9 4821 │ │
│────────────────►│ │
│ │ SIGKILL (9) │
│ │───────────────────►│
│ │ │ non puo' ignorarlo
│ │ │ termina forzatamente| Azione utente | Segnale | Numero | Il processo puo' ignorarlo? |
|---|---|---|---|
kill PID | SIGTERM | 15 | Si — puo' fare cleanup |
kill -9 PID | SIGKILL | 9 | NO — il kernel lo esegue |
| CTRL+C | SIGINT | 2 | Si |
| CTRL+Z | SIGSTOP | 19 | NO |
| chiusura terminale | SIGHUP | 1 | Si |
Perche' e' importante per il Blue Team#
Un attaccante che ottiene esecuzione di codice su un sistema crea processi. Quei processi hanno un proprietario (UID), un padre (PPID), un tempo di vita (etime) e file aperti. Conoscere la struttura dei processi permette di rispondere alle domande chiave in incident response: chi ha lanciato questo processo? Da dove? Da quanto gira? Cosa ha aperto?
Scenario Reale#
Alle 03:14 un processo python3 /tmp/miner.py gira come root con CPU al 99%. Il Blue Team usa ps -p 4821 -o pid,ppid,user,etime,cmd per vedere da quanto gira e chi e' il padre. Con pstree -p 4821 risale la catena fino a capire come e' stato lanciato. Con lsof -p 4821 vede i file aperti e le connessioni di rete attive. Solo dopo questa documentazione procede alla terminazione.
Dove l'ho incontrato#
Collegato a#
- system — categoria
- incidents — categoria
- ps — snapshot dei processi in esecuzione
- kill — segnali ai processi
- jobs-fg-bg — gestione foreground e background
- systemctl — gestione servizi (processi gestiti da systemd)


