Domanda:
Esiste un modo semplice per rilevare se l'SSDT è stato corretto da un dump della memoria?
Polynomial
2013-04-02 02:56:28 UTC
view on stackexchange narkive permalink

SSDT è una tabella di invio all'interno del kernel di Windows NT e viene utilizzata per gestire le chiamate a varie API interne del kernel. Spesso il malware cambia gli indirizzi nell'SSDT per agganciare determinate funzioni del kernel. Individuare questo genere di cose in un dump della memoria sarebbe fantastico, perché mi consentirebbe di identificare potenziali rootkit. C'è un modo per rilevarli in modo affidabile? Che tipo di dump della memoria è richiesto?

Due risposte:
#1
+8
0xC0000022L
2013-04-02 05:39:33 UTC
view on stackexchange narkive permalink

Nessun modo assolutamente affidabile , no.

In ogni caso avrai bisogno di un dump completo, ma il problema è che il malware potrebbe persino agganciare le funzioni responsabili all'interno del kernel e modificare cosa viene scaricato. Ci sono molte cose che devono essere considerate qui.

Puoi rilevarlo se il malware ha utilizzato un metodo banale per l'hook in primo luogo. Supponiamo che l'indirizzo sia stato sostituito da uno a un trampolino o all'interno di un'altra immagine caricata (o anche all'esterno di una solo in una piscina non di paging), quindi puoi rilevarlo facilmente . Puoi semplicemente enumerare tutti i moduli e provare a trovare quello all'interno del quale punta l'indirizzo dall'interno dell'SSDT. In caso di un trampolino dovrai smontare le istruzioni lì per vedere dove salta / chiama. Esistono molte librerie disponibili allo scopo, come udis86 .

Tuttavia, se un malware è subdolo, potrebbe utilizzare le lacune naturali all'interno di un eseguibile (come il kernel) quando viene caricato in memoria. Come probabilmente saprai, il modo in cui un file PE (come ntoskrnl.exe e amici) viene rappresentato in modo diverso su disco e in memoria. Il formato del file su disco è più conciso. Caricate in memoria, le sezioni sono allineate in un modo particolare descritto nell'intestazione PE. In questo modo probabilmente esisteranno degli spazi tra la dimensione reale di una sezione (estremità) e la dimensione della sezione correttamente allineata ("imbottitura"). Questo lascia il posto a nascondere qualcosa come un trampolino o anche più codice di shell di un semplice trampolino. Quindi un controllo ingenuo come quello sopra, ovvero enumerare i moduli e verificare se le funzioni SSDT puntano all'interno dell'immagine del kernel, non funzionerà. Verrebbe aggirato da malware abbastanza sofisticato da fare ciò che ho appena descritto.

Come puoi immaginare, questo significa che le cose, come tutte le cose malware / anti-malware, diventano rapidamente una corsa agli armamenti. Quello che suggerisco vivamente è di allegare un debugger del kernel (mi viene in mente WinDbg tramite Firewire) e di mantenere la macchina infetta (o presumibilmente infetta) nel limbo mentre indaghi. Mentre sei connesso e sei entrato nel debugger, il debuggee non può fare nulla. Questo può essere usato per eseguire il debug di un sistema live e, supponendo che il malware non fosse abbastanza subdolo da manipolare anche kdcom - per ottenere metriche preziose - può anche essere usato per creare direttamente un crashdump (vedi la guida di WinDbg ). Se hai prove conclusive che una macchina è infetta, a causa dei sintomi che mostra, è probabile che il malware non sia troppo sofisticato e non dovrai preoccuparti del caso speciale che ho descritto. Tuttavia, tieni presente che questo caso speciale può essere considerato solo uno tra i tanti possibili casi usati per nascondersi. Per farla breve: non esiste un modo assolutamente affidabile per fare ciò che vuoi.

A volte è stato detto - ed è vero - che l'attaccante deve solo trovarne uno di un numero infinito di vettori di attacco, mentre il difensore può difendere solo un numero finito di vettori di attacco noti . La lezione da questo dovrebbe essere che noi, come settore anti-malware (in cui lavoro), possiamo sempre affermare che noi non abbiamo trovato nulla nel sistema, ma che è sbagliato affermarlo il sistema è pulito.


Come causare deliberatamente un BSOD

Si può dire ai driver della tastiera di causare un BSOD:

  HKLM \ CurrentControlSet \ Services \ kbdhid \ Parameters  

o (per tastiere PS / 2 meno recenti)

  HKLM \ SYSTEM \ CurrentControlSet \ Services \ i8042prt \ Parameters  

E lì imposta un REG_DWORD denominato CrashOnCtrlScroll su 1 .

Dopo il prossimo riavvio puoi forzare la schermata blu con Ctrl + ScrollLk + ScrollLk . Il codice di controllo dei bug in questo caso sarà 0xE2 ( MANUALLY_INITIATED_CRASH ).


Nota a margine: ho anche letto, ma mai visto in una sessione di debug del kernel io stesso o in qualsiasi tipo di implementazione FLOSS, che qualche metodo cerchi di ricaricare il kernel dall'immagine sul disco e di eseguirlo attraverso i primi passaggi di inizializzazione, creando così un SSDT "ombra". Questo sarebbe quindi incontaminato e potrebbe essere utilizzato per "sganciare" tutto in un colpo solo dall'unità SSDT originale. Ancora una volta, non l'ho visto implementato, ma dalla mia conoscenza degli interni sembra una possibilità. Ovviamente questo gioca più con l'idea di rilevare / sganciare le funzioni di un rootkit che con la tua intenzione originale di ottenere un dump della memoria di un sistema infetto.

#2
+6
Brendan Dolan-Gavitt
2013-04-02 05:37:25 UTC
view on stackexchange narkive permalink

Volatility può rilevare tali hook in base a un'immagine di memoria in uno qualsiasi dei suoi formati supportati.

In particolare, i thread contrassegnerà qualsiasi thread con hook SSDT come HookedSSDT e il plug-in ssdt scaricherà tutte le funzioni nell'SSDT e fornirà il nome del modulo del kernel che contiene ogni funzione.

Un altro metodo, che potrebbe rilevare tipi più sottili di danneggiamento, sarebbe usare WinDbg (su un sistema live o su un crash dump) e usare il codice chkimg > comando per controllare ogni modulo del kernel, ad esempio:

  chkimg -d nt  

Questo scarica una copia incontaminata del kernel dal server MS Symbol e riporta eventuali differenze rispetto alla versione in memoria. Nota che questo probabilmente non rileverebbe alcun hook inserito in un SSDT per thread.

Ops, grazie per la cattura @0xC0000022L. Fisso.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...