Memoria e dati volatili · Lezione 1 di 4
Perché la memoria è importante e come acquisirla
13 min di lettura
Un'immagine del disco mostra ciò che un sistema ha memorizzato; un'immagine della memoria mostra ciò che stava facendo: quali programmi erano in esecuzione e con quali argomenti, chi aveva effettuato l'accesso, dove era connessa la macchina e quali segreti erano sbloccati. La maggior parte di queste informazioni scompare allo spegnimento. Questa lezione illustra quali dati risiedono soltanto nella RAM, quali raccogliere per primi e come acquisire la memoria da Windows, Linux e macchine virtuali affinché l'acquisizione possa essere analizzata e la sua validità possa essere sostenuta. Le attività pratiche di CFX sulla memoria utilizzano un'acquisizione Linux, pertanto il problema della tabella dei simboli Linux riceve particolare attenzione.
Che cosa risiede soltanto nella RAM
La memoria ad accesso casuale (RAM) contiene lo stato operativo del sistema operativo e di ogni programma in esecuzione. Una parte di questi dati viene scritta successivamente su disco, nel file di paging, nel file di ibernazione o in un dump di arresto anomalo (lezione 5.4), ma molti non lo sono mai:
- Processi e relative righe di comando. La riga di comando completa, ad esempio
powershell.exe -enc <Base64>, spesso esiste soltanto nella memoria del processo. - Connessioni di rete. Socket aperti, porte in ascolto e indirizzi remoti, oltre alla cache ARP e alla tabella di instradamento.
- Sessioni con accesso effettuato. Sessioni interattive, di desktop remoto e di servizio, con i relativi token di accesso. In Windows, il processo Local Security Authority (
lsass.exe) contiene materiale relativo alle credenziali degli utenti che hanno effettuato l'accesso. - Dati decrittografati e chiavi di crittografia. Mentre un volume BitLocker è sbloccato o un contenitore VeraCrypt è montato, la chiave principale che lo decrittografa si trova nella RAM. Recuperarla può essere l'unico modo per leggere successivamente il disco crittografato (il modulo 7 tratta i volumi crittografati).
- Contenuto degli appunti, compreso il testo copiato ma mai salvato.
- Codice iniettato o senza file. Il malware caricato direttamente in un altro processo o eseguito come script in memoria potrebbe non lasciare alcun eseguibile sul disco (lezione 5.3).
- Documenti non salvati e buffer degli editor.
- Residui della navigazione privata. Le modalità private evitano di scrivere la cronologia sul disco, ma URL, testo delle pagine e dati dei moduli rimangono nella memoria del processo del browser.
La memoria corrobora anche le evidenze presenti sul disco: Prefetch dimostra che un programma è stato eseguito in un determinato momento, mentre un processo presente in un'immagine della memoria dimostra che era in esecuzione al momento dell'acquisizione, con un'ora di avvio, un processo padre e un utente.
L'ordine di volatilità
RFC 3227, Linee guida per la raccolta e l'archiviazione delle evidenze (2002), indica a chi effettua la raccolta di procedere dalle evidenze più volatili a quelle meno volatili. L'elenco è il seguente:
- Registri e cache
- Tabella di instradamento, cache ARP, tabella dei processi, statistiche del kernel, memoria
- File system temporanei
- Disco
- Dati remoti di registrazione e monitoraggio pertinenti al sistema
- Configurazione fisica e topologia di rete
- Supporti di archiviazione
Registri e cache cambiano nell'arco di nanosecondi e non vengono quasi mai raccolti, quindi nella pratica l'immagine della memoria viene acquisita per prima. La tabella di instradamento, la cache ARP e la tabella dei processi risiedono tutte nella RAM: un'immagine completa della memoria le preserva, mentre eseguire prima comandi sul sistema attivo, come netstat o ps, modifica la memoria. I file system temporanei, come tmpfs di Linux (/dev/shm e, in alcune distribuzioni, /tmp), sono basati sulla RAM e scompaiono allo spegnimento. I log remoti sopravvivono all'incidente, ma sono soggetti a rotazione secondo la politica di conservazione, quindi è opportuno richiederli tempestivamente.
Decidere se acquisire e documentare l'impronta lasciata
Se un sistema viene trovato acceso, la prassi predefinita è acquisire la memoria prima di arrestarlo o scollegare l'alimentazione. Arrestarlo prima distrugge le evidenze nella RAM e può bloccare definitivamente un volume crittografato montato. Le ragioni per agire diversamente, come un malware che sta cancellando attivamente i dati, devono essere valutate e annotate.
Ogni acquisizione su un sistema attivo modifica il sistema. Lo strumento viene eseguito come processo, carica un driver o un modulo oppure apre file di dispositivo e sovrascrive pagine di memoria che potrebbero aver contenuto dati liberati ma ancora recuperabili. Non è possibile evitare questa impronta, quindi occorre ridurla al minimo e documentarla. ISO/IEC 27037 tratta l'acquisizione su sistemi attivi e richiede che ogni azione sia giustificata e documentata, mentre NIST SP 800-86 raccomanda di raccogliere i dati volatili in ordine di volatilità con strumenti affidabili e nella consapevolezza dei loro effetti. Registrare il nome, la versione e l'hash dello strumento, il comando esatto, l'account utilizzato, gli orari di inizio e fine in UTC con la relativa fonte oraria e ogni azione eseguita nella console.
Acquisizione in Windows
Gli strumenti di acquisizione della memoria per Windows richiedono privilegi di amministratore perché caricano un driver del kernel per leggere la memoria fisica. Eseguire lo strumento da un supporto esterno e scrivere l'output su un'unità esterna predisposta o su una condivisione di rete. Non scrivere mai un'acquisizione sul disco del sistema oggetto di esame: si sovrascriverebbero cluster non allocati che potrebbero contenere file eliminati. Calcolare l'hash dell'output non appena è completo.
I formati di output comuni sono raw (una copia lineare della memoria fisica, con estensione .raw, .mem o .img), il formato dump di arresto anomalo Microsoft (.dmp, un'intestazione seguita dalle pagine di memoria) e AFF4 (Advanced Forensic Format 4, un contenitore con compressione e metadati). Volatility 3 legge direttamente i file raw e i dump di arresto anomalo, ma non AFF4, quindi occorre prima esportare un'acquisizione AFF4 in formato raw.
Due funzionalità di Windows complicano l'analisi. Dati trasferiti nel file di paging: le pagine spostate in pagefile.sys non sono presenti nell'immagine della RAM, lasciando delle lacune; ove possibile, raccogliere anche il file di paging (lezione 5.4). Compressione della memoria: a partire da Windows 10, il gestore della memoria comprime nella RAM le pagine utilizzate raramente anziché trasferirle nel file di paging; nelle versioni attuali di Windows 10 e 11, l'archivio di compressione appartiene a un processo denominato Memory Compression. Questi dati sono presenti nell'immagine, ma sono compressi e soltanto gli strumenti che supportano l'archivio di compressione possono leggerli.
Macchine virtuali
Un hypervisor può salvare la memoria del sistema ospite senza eseguire alcunché al suo interno, quindi lo strumento non lascia alcuna impronta; inoltre, una VM sospesa è ferma, perciò la memoria salvata è coerente.
- VMware: la memoria del sistema ospite viene scritta in un file
.vmemquando la VM viene sospesa (con un file di stato.vmss) o quando uno snapshot include la memoria (con un file di snapshot.vmsn). Raccogliere il file.vmeminsieme al relativo.vmsso.vmsn: il file di stato descrive come è organizzata la memoria del sistema ospite nel file.vmeme viene utilizzato da Volatility 3. - Hyper-V: a partire da Windows Server 2016 e Windows 10, lo stato salvato e i checkpoint vengono memorizzati in file di stato di esecuzione
.vmrs; le versioni precedenti utilizzavano file.bin(memoria) e.vsv(stato salvato). Nessuno di questi è un'immagine raw: occorre convertirlo con uno strumento che ne interpreti il formato, ad esempio gli strumenti Microsoft per il dump dello stato salvato, e verificare il risultato.
Acquisizione in Linux
LiME (Linux Memory Extractor) è un modulo del kernel caricabile. Un kernel accetta un modulo soltanto se è stato compilato per quella specifica versione e configurazione del kernel, quindi LiME deve essere compilato utilizzando gli header del kernel in esecuzione, su un sistema separato e pulito con la stessa distribuzione e lo stesso kernel, non sul sistema oggetto di esame. La compilazione produce lime-<release>.ko, che viene caricato, ad esempio, con insmod lime-6.1.0-18-amd64.ko "path=/mnt/usb/mem.lime format=lime". Il parametro format accetta raw, padded o lime. Il formato lime scrive un'intestazione di 32 byte prima di ogni intervallo di memoria fisica, iniziando con il valore distintivo 0x4C694D45, che nel file appare come i byte ASCII EMiL. LiME può anche trasmettere l'acquisizione sulla rete con path=tcp:<port>, evitando qualsiasi scrittura locale. Con Secure Boot e l'obbligo di firma dei moduli, un modulo LiME non firmato viene rifiutato.
AVML (Acquire Volatile Memory for Linux) è l'alternativa di Microsoft: un programma statico in spazio utente che non richiede una compilazione specifica per ogni kernel. Legge tramite /dev/crash, /proc/kcore o /dev/mem, a seconda di quale sia disponibile, e scrive in formato LiME, facoltativamente compresso (Volatility 3 legge il file compresso se è installata la libreria snappy; in caso contrario, convertirlo con avml-convert).
/proc/kcore presenta la memoria virtuale del kernel come un file core ELF. Non è un'immagine fisica pronta all'uso: la sua dimensione apparente riflette lo spazio degli indirizzi del kernel (circa 128 TiB sui sistemi x86-64 tipici), la modalità lockdown del kernel può limitarne l'accesso e copiarlo con dd non produce un file nel formato previsto dagli strumenti di analisi. Neppure /dev/mem è una fonte pratica: con l'opzione del kernel STRICT_DEVMEM, abilitata nella maggior parte delle distribuzioni, non può leggere la RAM ordinaria (gli attuali kernel x86 restituiscono zeri anche per la RAM nel primo 1 MiB).
La tabella riepiloga le opzioni di acquisizione presentate in questa lezione.
| Strumento | Sistema operativo | Formato di output | Note |
|---|---|---|---|
| WinPmem | Windows | Raw; AFF4 nelle versioni precedenti | Open source; privilegi di amministratore; carica un driver |
| Magnet RAM Capture | Windows | Raw (.raw) | Gratuito; privilegi di amministratore |
| DumpIt | Windows | Raw o dump di arresto anomalo (.dmp) | Gratuito; singolo eseguibile; privilegi di amministratore |
| FTK Imager | Windows | Raw (.mem) | Gratuito; opzione per raccogliere anche pagefile.sys |
| LiME | Linux | lime, raw o padded | Modulo del kernel compilato per lo specifico kernel in esecuzione |
| AVML | Linux | LiME, facoltativamente compresso | Binario statico in spazio utente; nessuna compilazione specifica per ogni kernel |
| Hypervisor (VMware) | Sistema ospite con qualsiasi sistema operativo | .vmem con .vmss o .vmsn | Nessuna impronta nel sistema ospite; conservare entrambi i file |
Il problema della tabella dei simboli
Per analizzare un'immagine Linux, Volatility 3 richiede una tabella dei simboli per la specifica compilazione del kernel: un file JSON ISF (Intermediate Symbol Format) che descrive le strutture del kernel e gli indirizzi dei simboli. Viene generato con dwarf2json a partire da un file vmlinux contenente informazioni di debug DWARF e dal corrispondente System.map, ad esempio dwarf2json linux --elf vmlinux-6.1.0-18-amd64 --system-map System.map-6.1.0-18-amd64 > debian12-6.1.0-18.json. In Debian, il file vmlinux di debug proviene dal pacchetto linux-image-<release>-dbg. Volatility 3 associa il file dei simboli all'immagine tramite la stringa del banner del kernel e il suo plugin banners mostra quale banner è contenuto in un'immagine. Un'acquisizione priva di simboli corrispondenti potrebbe essere inutilizzabile, quindi registrare uname -a al momento dell'acquisizione: indica all'analista esattamente per quale kernel ottenere i simboli.
Integrità, incoerenza temporale e tempistiche
Calcolare immediatamente l'hash dell'acquisizione, in genere con SHA-256. L'hash dimostra che il file non è cambiato dall'acquisizione, ma non può essere verificato rispetto alla fonte: la memoria cambia continuamente, quindi due acquisizioni dello stesso sistema in esecuzione non producono mai lo stesso hash.
La memoria cambia anche mentre viene letta: le pagine copiate alla fine di un'acquisizione riflettono uno stato successivo rispetto alle pagine copiate all'inizio. Questa incoerenza temporale (smear) può produrre strutture incoerenti, ad esempio una voce di elenco che punta a un processo già terminato. Un'acquisizione non è uno snapshot perfetto, quindi occorre corroborare i risultati anomali.
Esempio svolto: acquisizione di un server Linux
Occorre preservare un server web Debian 12 in esecuzione. Un modulo LiME è stato compilato in anticipo su un sistema di laboratorio con un kernel identico. Il registro di acquisizione riporta:
| Campo | Valore |
|---|---|
| Host | web01 (Debian 12), 8 GiB di RAM |
Kernel (uname -r) | 6.1.0-18-amd64; riga completa di uname -a copiata testualmente nelle note |
| Strumento | LiME, lime-6.1.0-18-amd64.ko, SHA-256 del modulo registrato |
| Comando | insmod lime-6.1.0-18-amd64.ko "path=/mnt/usb/mem.lime format=lime" |
| Destinazione | Unità esterna USB 3 montata in /mnt/usb |
| Inizio / fine | 2026-03-14T09:12:05Z / 2026-03-14T09:12:51Z (fonte oraria: portatile dell'esaminatore sincronizzato tramite NTP) |
SHA-256 di mem.lime | a7326e3c793d494752ca0a09896ee1d81feeb30476fc9048415c3edf2bb27bea |
| Nota per l'analisi | Il file dei simboli di Volatility 3 deve essere generato per 6.1.0-18-amd64 dal pacchetto -dbg corrispondente |
Dimensionamento. Le dimensioni della RAM sono binarie: 8 GiB = 8 × 1.073.741.824 = 8.589.934.592 byte. Le velocità delle unità sono decimali: 200 MB/s = 200.000.000 byte al secondo. Tempo = 8.589.934.592 ÷ 200.000.000 ≈ 42,9 s, circa 43 secondi. Considerare 8 GiB come 8.000.000.000 byte dà 40 s, una sottostima del 7%. I 46 secondi registrati corrispondono alla stima più il caricamento del modulo. Un server con 64 GiB, alla stessa velocità, richiede 68.719.476.736 ÷ 200.000.000 ≈ 344 s, quasi sei minuti di incoerenza temporale. Neppure il file lime misura esattamente 8 GiB: LiME copia soltanto gli intervalli che il kernel elenca come System RAM in /proc/iomem e aggiunge 32 byte per intervallo.
Autorizzazione e riservatezza
La memoria contiene password, messaggi privati e dati di persone estranee all'indagine. Verificare che la propria autorizzazione (un mandato, il consenso del proprietario o un incarico di risposta agli incidenti) comprenda l'acquisizione su sistemi attivi, rispettarne l'ambito e proteggere l'acquisizione come dato sensibile.
Focus sull'esame: Sono previste domande che applicano l'ordine di volatilità a uno scenario, chiedono quali informazioni siano contenute in un'immagine della memoria ma non in un'immagine del disco e verificano perché l'hash di un'acquisizione della memoria non possa essere nuovamente verificato rispetto al sistema attivo. Per la parte pratica, occorre sapere che l'analisi Linux con Volatility 3 dipende da un file dei simboli ISF corrispondente all'esatto banner del kernel e riportare esattamente valori quali la versione del kernel.
Punti chiave
- La RAM contiene processi in esecuzione, righe di comando, connessioni, sessioni, chiavi di crittografia e codice senza file che non vengono mai scritti sul disco.
- Raccogliere dalle evidenze più volatili a quelle meno volatili (RFC 3227): acquisire la memoria prima dell'arresto e documentare l'inevitabile impronta dello strumento.
- Eseguire gli strumenti Windows come amministratore da supporti esterni, scrivere su supporti esterni e calcolare immediatamente l'hash dell'output.
- LiME deve essere compilato per lo specifico kernel in esecuzione; AVML è un'alternativa in spazio utente;
/proc/kcorenon è un'immagine fisica pronta all'uso. - Registrare
uname -a: senza una tabella dei simboli ISF per quello specifico kernel, Volatility 3 potrebbe non essere in grado di analizzare l'acquisizione. - L'incoerenza temporale, le pagine trasferite nel file di paging e la compressione della memoria di Windows fanno sì che un'acquisizione non sia mai uno snapshot completo e coerente.