410 likes | 588 Views
advances in attacking linux kernel. 17 Ottobre 2006 Net & System Security Pisa, Italia. Pierre Falda darkangel@antifork.org. // introduzione.
E N D
advances in attacking linux kernel 17 Ottobre 2006 Net & System Security Pisa, Italia Pierre Falda darkangel@antifork.org
//introduzione _In questo intervento vedremo come sia possibile manomettere un sistema linux in modalità completamente nascosta sfruttando l’hardware sottostante come complice. _I concetti di base sono validi per qualsiasi sistema operativo _Come prerequisiti sono richieste unicamentemte un minimo di dimestichezza col linguaggio C ed Assembly oltre ad alcune nozioni base di sistemi operativi Pierre Falda darkangel@antifork.org
//sommario 01// Panoramica 02// Terminologia 03// Uso ed abuso di sys call table e kmem 04// Cenni sul rilevamento 05// Caratteristiche abusabili dell’hardware 06// Abuso dei meccanismi di linux 07// conclusioni Pierre Falda darkangel@antifork.org
01// Panoramica Pierre Falda darkangel@antifork.org
01//panoramica Partiremo dall’analisi generale di alcune tecniche di manomissione già note fino ad arrivare a vedere, piu o meno approfonditamente, come sia possibile fonderle per ottenere un potente nuovo motore di occultamento delle informazioni. L’esposizione avrà lo scopo di fornire principalmente gli strumenti concettuali per comprendere la struttura, il funzionamento nonché la pericolosità di software di questo tipo. Pierre Falda darkangel@antifork.org
02// Terminologia Pierre Falda darkangel@antifork.org
02//terminologia Syscalls: funzioni che ci offre il kernel per interfacciarci con le sue funzionalità Sys call table: è una tabella residente a kspace contenente gli indirizzi delle syscall Kmem: /dev/kmem è un character device che fornisce un'immagine della memoria virtuale del kernel. Interrupt: è un evento sincrono od asincrono che altera la sequenza di istruzioni eseguite dal processore Exception: segnale lanciato dalla CPU per segnalare un evento eccezionale Interrupt Handler: funzione che si fa carico della gestione di un determinato interrupt Pierre Falda darkangel@antifork.org
02//terminologia Interrupt Descriptor Table: tabella che associa ciascun interrupt col suo interrupt handler e le relative informazioni di supporto Breakpoint: è una qualsiasi locazione all’interno del programma scelta dallo sviluppatore dove l’esecuzione del programma stesso viene fermata Virtual File System: Il virtual file system e' un layer del kernel che si occupa di gestire tutte le syscall legate ad un filesystem IA-32: Architettura dei processori intel a 32 bit Pierre Falda darkangel@antifork.org
03// Uso ed abuso di sys call table e kmem Pierre Falda darkangel@antifork.org
03//come viene utilizzata la sct? Pierre Falda darkangel@antifork.org
03//come viene utilizzata la sct? Pierre Falda darkangel@antifork.org
03//abuso della sys call table La prima generazione di LKM maligni modificava la s.c.t. ... Sys_exit 0xc0123456 0xc0123456: int sys_exit(int) … .. 0xc0789101: int sys_fork(void) … .. 0xc0112131: int sys_read(int,void*,int) … .. 0xc0415161: int sys_write(int,void*,int) … .. Sys_fork 0xc0789101 Sys_read 0xc0112131 Hacked Write 0xbadc0ded Sys_write 0xc0415161 ... 0xbadc0ded: int hacked_write(int,void*,void) Pierre Falda darkangel@antifork.org
03//abuso della sys call table PRO: _Estremamente semplice da realizzare _Permette un’altissima portabilità CONTRO: _Semplice da rilevare _Semplice rilevare quanto nascosto tramite questa tecnica in quanto non si opera sulle informazioni vere e proprie ma solo sulla loro visualizzazione. PROGRAMMA: _Adore Pierre Falda darkangel@antifork.org
03//abuso DI KMEM _Una generazione piu recente di kernel malware ha riadottato l’utilizzo parziale di questa tecnica per questioni implementative e di portabilità _/dev/kmem , come precedentemente detto, fornisce un'immagine della memoria virtuale del kernel. Normalmente utilizzato da X (ovvero il server grafico) puo essere sfruttato anche per inserire dati a piacere, tramite opportune tecniche _L’attacco non viene piu portato a termine tramite l’ausilio di lkm ma iniettando direttamente del codice a kernel space Pierre Falda darkangel@antifork.org
03//abuso DI KMEM PRO: _L’attacco non viene piu portato a termine tramite l’ausilio di lkm ma iniettando direttamente del codice a kernel space CONTRO: _Lo sviluppo del relativo software è piu complesso e laborioso PROGRAMMA: _Suckit Pierre Falda darkangel@antifork.org
03//SUCKIT _Crea una propria sys call table contenente puntatori alle proprie syscall maligne _Non modifica la sys call table del sistema ma sostituisce il suo indirizzo nello handler dell’interrupt 0x80 _Si inietta in memoria tramite kmem Pierre Falda darkangel@antifork.org
03//SUCKIT ed 0d dc ba badc0ded Pierre Falda darkangel@antifork.org
04// Cenni sul rilevamento Pierre Falda darkangel@antifork.org
04//cenni sul rilevamento _Alcuni tool permettevano un’analisi del sistema per cercare modifiche note a zone sensibili del kernel, ma una modifica ‘anomala’ o ben congegnata poteva facilmente ingannarli _Anche una modifica simile però puo essere facilmente rilevata tramite un hash del segmento testo del kernel effettuato da software operante a kspace _Dobbiamo perciò riuscire a modificare il comportamento del kernel senza modificare lo stesso PROGRAMMA: _Kstat Pierre Falda darkangel@antifork.org
04//kstat bypass int check_sct() { int kd; char sch_code[100], *buf; kd=open(KMEM, O_RDONLY); printf(”\nLegal sys_call_table should be at 0x%x ...", SYS_CALL_TABLE); kread(kd, sc_addr, sch_code, 100); buf = (char *) memmem(sch_code, 100, ”\xff\x14\x85", 3); sct = *(unsigned *)(buf+3); if(sct == SYS_CALL_TABLE) { printf(" OK!\n"); close(kd); return0; } else { printf(" WARNING! sys_call_table hijacked!\n\n"); printf("Checking sys_call_table array now at 0x%lx …\n\n\n", sct); close(kd); return1; } return0; } Pierre Falda darkangel@antifork.org
04//kstat bypass int kread(int des, unsignedlong addr, void *buf, int len) { int rlen; if(lseek(des, (off_t)addr, SEEK_SET) == -1) return-1; if((rlen = read(des, buf, len)) != len) return-1; return rlen; } Pierre Falda darkangel@antifork.org
04//kstat bypass staticunsignedchar buffer (100)={0}; longlong my_lseek(struct file *target, longlong offset,unsignedint origin) { if((unsignedlong)offset==FORBIDD) offset=(longlong)&buffer; return o_lseek(target,offset,origin); } Pierre Falda darkangel@antifork.org
05// Caratteristiche abusabili Dell'hardware Pierre Falda darkangel@antifork.org
05//abuso dell’hardware _IA-32 fornisce meccanismi per il debug del codice che sono un valido aiuto per il debugging di: - applicativi - software di sistema - sistemi operativi multiprogrammati _Si accede al supporto per il debugging tramite l’utilizzo di 8 Debug Registers (dbr0-dbr7) , dei registri specifici modello (MSRs) e dell’istruzione di breakpoint (int 3 #BP ) DBRs 0-3: contengono l’indirizzo lineare di un breakpoint. Una debug exception (#DB )viene generata quando avviene in tentativo di accesso all’indirizzo del breakpoint DBR 6: riporta le condizioni che erano presenti quando la debug o breakpoint exception è stata generata DBR 7: Specifica le forme di accesso che causeranno la debug exception al raggiungimento del breakpoint Pierre Falda darkangel@antifork.org
05//debug registers Pierre Falda darkangel@antifork.org
05//debug registers _La modalità di accesso puo indicare: - Break alla sola esecuzione - Break alla sola scrittura - Break alla lettura/scrittura di I/O - Break alla lettura o scrittura di dati _In base a quanto detto fin’ora questo ci permette di far generare una #DB quando la cpu tenta di eseguire del codice posto in una qualsiasi locazione di memoria a nostra scelta, anche a kernel space Pierre Falda darkangel@antifork.org
05//gestione delle #DB _La #DB verrà gestita anch’essa tramite il meccanismo dell’idt _In linux la funzione principale atta alla gestione delle #DB, come possiamo vedere dalla trap_init in poi all’interno dei file traps.c ed entry.S, è la fastcall void do_debug(struct *pt_regs, int errorcode) _Allo stato attuale delle cose noi possiamo quindi dirottare qualsiasi flusso di esecuzione del kernel verso la do_debug, senza modificare un singolo bit del segmento testo! Pierre Falda darkangel@antifork.org
05//do_debug fun! Per capire bene con cosa abbiamo a che fare diamo uno sguardo al suo argomento principale, la struct pt_regs: struct pt_regs { long ebx; long ecx; long edx; long esi; long edi; long ebp; long eax; int xds; int xes; long orig_eax; long eip; int xcs; long eflags; long esp; int xss; }; Pierre Falda darkangel@antifork.org
05//do_debug fun! _Dalla do_debug possiamo quindi avere accesso al valore di eip rappresentante l’indirizzo di ritorno relativo a chi ha fatto scattare il breakpoint, ovvero il kernel nel nostro caso, così da poterne modificare a piacimento il flusso di esecuzione una volta terminata la procedura! _Modificando eip possiamo mandare in esecuzione una nostra routine che una volta fatto il ‘lavoro sporco’ si occupi di ripristinare il flusso di esecuzione originario Pierre Falda darkangel@antifork.org
05//do_debug fun! evil routine do_debug eip overwriting jump to regular flow debug exception breakpoint execution flow execution flow Pierre Falda darkangel@antifork.org
05//do_debug fun! _Tutto questo necessita però del nostro controllo sulla do_debug, il che ci porta a due possibili soluzioni: - dirottamento della stessa - abuso della flessibilità di linux _Dirottarla implicherebbe modificare parte del segmento testo, vediamo perciò come sia possibile ottenere lo stesso risultato senza modificare nulla di rilevabile dalle consuete tecniche Pierre Falda darkangel@antifork.org
06// Abuso dei meccanismi di linux Pierre Falda darkangel@antifork.org
06//abuso dei meccanismi di Linux Diamo un’occhiata alla do_debug: fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code) { unsignedint condition; struct task_struct *tsk = current; get_debugreg(condition, 6); if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,, SIGTRAP) == NOTIFY_STOP) return; Pierre Falda darkangel@antifork.org
06//abuso dei meccanismi di linux staticinlineint notify_die(enum die_val val, constchar *str, struct pt_regs *regs, long err, int trap, int sig) { struct die_args args = { .regs = regs, .str = str, .err = err, .trapnr = trap, .signr = sig }; return notifier_call_chain(&i386die_chain, val, &args); } Pierre Falda darkangel@antifork.org
06//abuso dei meccanismi di linux int __kprobes notifier_call_chain(struct notifier_block **n, unsignedlong val, void *v) { int ret=NOTIFY_DONE; struct notifier_block *nb = *n; while(nb) { ret=nb->notifier_call(nb,val,v); if(ret&NOTIFY_STOP_MASK) { return ret; } nb=nb->next; } return ret; } Pierre Falda darkangel@antifork.org
06//abuso dei meccanismi di linux struct notifier_block { Int (*notifier_call)(struct notifier_block *self, unsignedlong, void *); struct notifier_block *next; int priority; }; int register_die_notifier(struct notifier_block *nb) { int err = 0; unsignedlong flags; spin_lock_irqsave(&die_notifier_lock, flags); err = notifier_chain_register(&i386die_chain, nb); spin_unlock_irqrestore(&die_notifier_lock, flags); return err; } EXPORT_SYMBOL(register_die_notifier); Pierre Falda darkangel@antifork.org
06//abuso dei meccanismi di linux _Iniettare il nostro codice in kmem _Creare una nostra sys call table maligna _Creare un handler maligno per la gestione delle #DB _Registrare il nostro handler tramite la register_die_notifier _Inserire l’indirizzo della syscall_call come breakpoint Pierre Falda darkangel@antifork.org
07// conclusioni Pierre Falda darkangel@antifork.org
07//conclusioni _Possiamo modificare il comportamento di porzioni di codice senza modificarlo _Possiamo iniettare codice nella memoria del kernel senza utilizzare moduli e talvolta senza utilizzare punti di accesso standard come kmem _Questa tecnica si presta molto alla creazione sia di malware sofisticati sia di anti-malware altrettanto potenti PROGRAMMA: _Mood-NT Pierre Falda darkangel@antifork.org
//riferimenti _http://www.antifork.org _http://www.s0ftpj.org _http://www.phrack.org _http://www.invisiblethings.org _http://darkangel.antifork.org/codes.htm Pierre Falda darkangel@antifork.org
…grazie per l’attenzione… domande sui concetti esposti? advances in attacking linux kernel Pierre Falda darkangel@antifork.org