ADS è la funzionalità NTFS che continua a sorprendere gli analisti junior. Un file può avere più di un attributo $DATA. Quello senza nome è quello di cui dir mostra la dimensione. Tutto il resto, qualsiasi cosa con i due punti nell'identificatore, è invisibile agli strumenti che la maggior parte usa. Gli attaccanti lo sanno. Microsoft lo sa. L'auditor che esamina il tuo report IR dovrebbe saperlo.
Il meccanismo, in breve
Nel record MFT, l'attributo di tipo 0x80 è $DATA. L'header porta un nome opzionale. Un singolo record può portare molti attributi $DATA: uno senza nome (lo stream primario) e qualsiasi numero di stream nominati. Dallo user space li indirizzi con filename:streamname.
echo payload > readme.txt:nope
type readme.txt:nope
readme.txt ha zero byte secondo ogni misura che Explorer mostra. Lo stream nominato nope contiene il payload. Stesso record MFT. Stessa voce dell'indice della directory padre. Due attributi di dati indipendenti.
Non è un bug. È una decisione di design del 1993 che NTFS ha ereditato da HPFS per permettere a Services for Macintosh di allegare resource fork. Quasi nessuno usa ADS per questo ormai. Tutti gli altri, Microsoft inclusa, lo usano per metadati ad hoc.
Dove Windows stesso lascia degli ADS
Zone.Identifier è il famoso. Edge, Chrome, Firefox e Outlook lo aggiungono a qualsiasi cosa che abbia attraversato un confine di sicurezza. Il contenuto è un frammento INI con l'URL di origine, il referrer e una riga ZoneId=3 che attiva le protezioni Mark-of-the-Web in Office e SmartScreen. Se stai leggendo una MFT e un binario in Downloads\ non ha Zone.Identifier, chiediti perché. Qualcuno potrebbe aver eseguito Unblock-File o aver copiato il file attraverso un archivio che scarta gli stream.
Altri stream benedetti da Microsoft che incontrerai:
$KSPsui file di layout della tastiera per lingue asiatiche.OECustomPropertye affini sugli allegati Outlook salvati su disco.- Dati reparse
Wofsui file compressi sotto WIMBoot e CompactOS. SmartScreensugli eseguibili che Defender ha fingerprintato.encryptablesulle directory di cache di ConfigMgr.
Questi compaiono di continuo. Impara come appare la tua baseline prima di marcare gli stream come sospetti.
Cosa fanno davvero gli attaccanti con ADS
Tre pattern ricorrenti:
- Nascondiglio del payload, launcher separato. Il file visibile è benigno (un documento Word, un PDF, un file di licenza). Lo stream nominato porta il vero PE. WMI,
wmic process call createorundll32avvialegit.docx:payload.exedirettamente. Defender oggi scansiona gli stream nominati, ma molti EDR non lo fanno quando uno stream è creato da un processo fidato. - Nascondiglio living-off-the-land. Payload PowerShell scritti in
ads:script.ps1e poi eseguiti conGet-Content -Stream. Sorprendentemente comune nei retainer red team perché sopravvive a una ricerca di IOC basata solo sul percorso. - Persistenza in stream alternativi di file di sistema.
C:\Windows\System32\drivers\etc\hosts:backdoorè l'esempio da manuale. Il file hosts appare intatto, il timestamp può anche essere quello originale, e la maggior parte degli strumenti di monitoraggio dell'integrità non guarda oltre lo stream senza nome.
La proprietà condivisa: non puoi vederli con dir, non puoi vederli in Explorer e non puoi vederli facendo l'hash del file visibile. Puoi vederli leggendo il record MFT.
Rilevarli su un host attivo
dir /R enumera gli stream in cmd. Get-Item -Stream * di PowerShell fa lo stesso con output più pulito. streams.exe di Sysinternals percorre un albero. Tutti e tre funzionano sul volume su cui sei. Nessuno aiuta se il volume è offline o se non sai quali file controllare.
dir /R C:\Users\bob\Documents\
Get-ChildItem -Recurse | ForEach-Object { Get-Item $_.FullName -Stream * } |
Where-Object Stream -ne ':$DATA'
Quella seconda one-liner enumera ogni stream non predefinito in un albero. Eseguila su un'installazione Windows fresca e avrai già centinaia di risultati, perlopiù Zone.Identifier. Filtra agli stream più grandi di qualche centinaio di byte e il rumore cala rapidamente.
Perché la MFT è la lente migliore
I comandi sull'host enumerano file per file. Si perdono quello che non hai pensato di controllare. La MFT no. Ogni attributo $DATA, nominato o meno, è scritto nel record all'attributo di tipo 0x80. Percorri la tabella, elenca gli attributi $DATA di ogni record con nomi e dimensioni, e hai un inventario esaustivo di tutti gli stream del volume in un solo passaggio.
Alcune cose che questo ti dà rispetto all'enumerazione per file:
- Stream su file in directory in cui non avresti mai guardato, inclusa
C:\Windows\Temp\eC:\$Recycle.Bin\. - Stream su file eliminati. Il record MFT sopravvive all'eliminazione; l'ADS è ancora elencato nello stream di attributi.
flseistatdel Sleuth Kit li mostreranno; lo faranno anche MFTECmd e la CLIomerbenamram/mft. - Stream residenti il cui contenuto sta inline nel record MFT. Piccoli payload (loader PowerShell, blob base64, config codificate) entrano spesso nello slack di un record da 1.024 byte. Puoi leggerli direttamente dall'estratto MFT senza mai toccare l'area dati. Vedi dati residenti per la soglia di dimensione.
- Nomi degli stream. La MFT conserva il nome che l'attaccante ha scelto.
:payload.exesembra innocuo in una lista di dimensioni di file; è rumoroso quando fai grep di un dump di attributi cercandoexe.
Il filtro di triage che uso davvero
Dopo aver parsato la MFT con MFTECmd o mft_dump, esporto ogni record con più di un attributo $DATA. Poi scarto:
- Qualsiasi cosa il cui nome stream extra sia
Zone.Identifiere sotto 1 KB. - Qualsiasi cosa in
\Windows\WinSxS\(il manifest store, pieno di stream legittimi). - Qualsiasi cosa sotto una directory di applicazione firmata dal vendor il cui stream sia una miniatura o chiave di metadati nota.
Ciò che resta è il set di lavoro. Su una workstation pulita di solito sono meno di cento record. Su un host dove è successo qualcosa di interessante, i delta saltano fuori subito.
Incrocia i superstiti con il journal USN per vedere quando ogni stream è stato creato o modificato per l'ultima volta. Un attributo $DATA nominato apparso alle 02:14 e non più toccato vale uno sguardo più attento. Affianca a Sysmon e log eventi di sicurezza se li hai: Sysmon Event ID 15 (FileCreateStreamHash) è l'unico event ID che cattura la creazione di ADS con l'hash del contenuto dello stream.
Una nota su Defender
Defender moderno scansiona gli ADS di default. È davvero bravo col pattern brute-force "lascia un PE notoriamente cattivo in uno stream". È meno bravo con piccoli PowerShell offuscati nascosti negli stream, e non sempre tocca gli stream nei percorsi esclusi. Non dare per scontato che il silenzio di Defender sia prova di assenza.
Letture aggiuntive
- Microsoft, File Streams. La meccanica ufficiale, inclusa l'API
BackupRead/BackupWriteche copia tutti gli stream. istateflsdel Sleuth Kit per l'enumerazione offline che porta a galla gli ADS.- La documentazione Mark of the Web di Microsoft su cosa fa davvero
Zone.Identifiere come lo usa Office.