============================================================================== -----------[ BFi numero 10, anno 4 - 30/09/2001 - file 17 di 18 ]------------- ============================================================================== -[ ViRii ]-------------------------------------------------------------------- ---[ ANALiSi ViRUS PER LiNUX -----[ vecna- NOTA BENE - io non sono Vecna dei 29a, lui e` un virii coder con le palle e penso che questa chiarificazione tolga nebbia dagli occhi dei virii coder seri che sperano di trovar un lavoro del mito invece che 4 parole del suo omonimo provincialotto :P requisiti: http://www.manuali.net cercare TrickyC http://www.big.net.au/~silvio per qualche info di vario genere sui virus... non sono la persona + indicata a dar consigli, ma tempo fa trovai parecchie informazioni su www.avpve.com (avpve = anti viral protection VIRUS ENCICLOPEDIA) con una buona descrizione su una caterva di virus, almeno puo` servire x dare idee o per far capire di cosa si parla... (ammetto che l'ultima volta che l'ho visitato e` stato nel '98) --] SISTEMI DI INFEZIONE PER BAMBINI MONGOPLETTICI BASATI SU system() [-- questo e` proprio alla base di ogni possibile virus che viene costruito, non e` altro che un codice che fa qualcosa e poi esegue il file cui ha wrapperato l'esecuzione. un esempio molto terra terra e` dato da un virus di silvio cesare all'inizio dei suoi studi; come universalmente deducibile questi virus fan solo: * sono eseguito? bene, cerco una vittima dove insediarmi. (serie di readdir()/getdents() per trovar una vittima) * e` gia` infetto? (verifica, a seconda del tipo di infezione che si vuole portare, se mettere l'eseguibile originario in append al nostro virus per poi estrapolarlo dal binario ed eseguirlo o se metterlo con un nome tipo /tmp/.hash_md5_del_nome_del_file_infetto in tmp. nel caso sia gia` infetto si cerca un'altra vittima considerando un numero massimo di tentativi; se non e` infetto si infetta e si salta al prossimo punto) * dopo essermi eseguito e aver proliferato, estrapolo dal binario con dentro me il file che ho infettato o grazie all'hash ritrovo dove l'ho messo o continuo ed essere eseguito xke` l'ho inglobato o faccio un jmp al posto giusto o [altre possibilita`, dipende dal tipo di infezione che avete implementato] e avvio il file realmente chiamato dall'utente. la cosa triste e` che se si usa system, come succedeva in alcuni virus, la system include una fork quindi se uno avvia il proprio binario e dopo un po' lancia un ps notera` che ci sono 2 processi al posto di uno e normalmente ci si insospettisce :) un'ottima variante di questo e` quella che utilizza la exec* senza fork()are prima (la system e` una fork() seguita da una exec* praticamente) per caratteristica delle funzioni della famiglia exec* il file eseguito sovrascrivera` il vecchio processo: questo impedisce quindi l'esecuzione di comandi da parte del virus una volta terminata l'esecuzione del file infetto, ma se state progettando qualcosa che si puo` accontentare dell'esecuzione prima dell'avvio allora e` una soluzione valida. attenzione che exec una volta avviata da` al processo il nome che vien passato come argomento, un errore abbastaza fixabile e notoriamente vistoso nei virus di silvio cesare (maestro su ogni fronte cmq e sempre :) era il fatto che la exec* veniva fatta su un file temporaneo che conteneva il file infettato che poi xo` doveva essere rimosso, x questo motivo spesso viene utilizzata la exec* e x questo motivo ho suggerito di usare un file nascosto in tmp: occultandolo tra i file temporanei sara` possibile avviarlo con un nome diverso senza dover eliminarlo una volta finita l'esecuzione e senza quindi dover usare una system x poterlo rimuovere. --] SISTEMI DI INFEZIONE PER GIOVANI DONNE CRESCONO CON GLI ELF [-- studiando il formato ELF e` possibile dare un significato alle varie zone di dati che stan dentro un comune binario, queste zone in seguito all'avvio del compilato verrano interpretate e lette dal kernel, ma questo non vieta a nessuno di inserire una parte di codice automodificante in una apposita sezione nel binario reale in modo da eseguire questa parte di codice in modo + trasparente e veloce, senza preoccuparsi di exec* e fork di sorta... per maggiori info vi rimando al sito di silvio cesare (o cercare su google l'archivio della mailing list unix-virus). c'e` da dire che anche questo genere di infezione altera il binario ed un eventuale md5sum o qualunque altro integrity check sui binari rivelera` l'infezione. come ottenere informazioni su *cosa viene eseguito* se l'engine di duplicazione e` cosi` trasparente? con strace! e` proprio strace(1) il semplicissimo comando che speravo di usare durante l'analisi di un virus che mi fu passato, l'analisi del suddetto e` stata pubblicata da un altro tizio prima di me ed e` reperibile su BUGTRAQ, la mail ha come subject "Remote Shell Trojan: Threat, Origin and the Solution" xke` questo virus a differenza di un semplice polimorfico se e` la prima volta che viene avviato si mette in background in listen su una porta udp attendendo che qualcuno comunichi con lui per favorire della shell gentilmente regalata :) --] L'ARRIVO DELLE TRUPPE DI PTRACE(2) E LE SUE TECNICHE DI BATTAGLIA [-- strace e` uno strumento che si appoggia alla ptrace(2) apposta x poter tracciare le system call chiamate da un programma, questo bene o male non dara` informazioni dettagliatissime sul programma che sta girando, ma perlomeno consentira` di apprendere le cose principali che fa. e` evidente che un binario infetto dovra` far qualche chiamata di sistema per poter proliferare, sicuramente la getdents o la reddir per poter scannare alla ricerca di nuovi file vittima, probabilmente leggera` se stesso x potersi copiare e aprira` la vittima... senza contare l'apertura di eventuali porte udp :) o altri attacchi sicuramente individuabili da questo mezzo. strace e ogni programma che si appoggia a ptrace xo`, puo` essere fregato proprio grazie ad una chiamata ptrace da parte del codice che vogliamo rendere *invisibile* e purtroppo x me... questo virus lo faceva... informazioni di vario genere x rendere il proprio codice invisibile agli occhi di un debugger si trovano sempre sul sito si silvio cesare, con il nome di linux-anti-debugging.txt, in cui spiega essenzialmente 5 tecniche tra cui una in cui la ptrace viene chiamata per sviare il debug... per monitorare le syscall stavo facendo un modulo che wrapperasse le principali syscall e riportasse gli argomenti, in questo caso ptrace o no io avrei visto cmq quello che ogni programma (o tramite una selezione per pid o per nome di file, solo il programma che sapevo fosse infetto) avrebbe fatto. dopo un po' di ore mi sono accorto di quanto fossi stupido a non accorgemi prima che potevo far tutto semplicemente bloccando la ptrace via lkm e usando strace normalmente... bah... ecco qui il modulo: <-| kantiptrace.c |-> /* * module for debug linux virus and other program that over ptrace(2) drop * debug system. * on this stupid release the code of fork() is bad and you needed for make * to kernel segnalation of evil code, rename this file with "evil" name, * that is detected via execve redirection. * * after loading of this module you can simple use strace with * strace ./evil * command and ptrace appears uncalled * * by vecna@s0ftpj.org - ??/09/2001 more or less */ #define MODULE #define __KERNEL__ #include #include #include #include #include #include #include #include int (*linux_execve)(struct pt_regs); /* int (*linux_fork)(); */ int (*linux_exit)(int); int (*linux_ptrace)(long request, long pid, long addr, long data); extern void *sys_call_table[]; static int virii, child; static int ktrace_execve(struct pt_regs exc) { int ret; char *filename =getname((char *)exc.ebx); ret =do_execve(filename, (char **)exc.ecx, (char **)exc.edx, &exc); if(strstr(filename, "evil")) { virii =current->pid; printk(KERN_INFO "monitoring of pid %d\n", virii); } return ret; } static int ktrace_exit(int err) { if(current->pid ==virii) { printk(KERN_INFO "pid %d program exit\n", virii); virii =0; if(child !=0) { printk(KERN_INFO "tracing child %d\n", child); virii =child; child =0; } } return linux_exit(err); } /* static int ktrace_fork() { int ret; ret =linux_fork(); if(current->pid > 1 && virii && current->pid ==virii) { printk(KERN_INFO "forking from %d child %d\n", virii, ret); child =ret; } return ret; } */ static int ktrace_ptrace(long request, long pid, long addr, long data) { printk(KERN_INFO "ptrace da %d con pid %d\n", current->pid, pid); if(current->pid && virii && (current->pid == virii || current->pid == virii +1)) return 0; return linux_ptrace(request, pid, addr, data); } int init_module(void) { printk(KERN_INFO "loading anti ptrace module by vecna@s0ftpj.org\n"); linux_execve =sys_call_table[SYS_execve]; sys_call_table[SYS_execve] =(void *)ktrace_execve; linux_exit =sys_call_table[SYS_exit]; sys_call_table[SYS_exit] =(void *)ktrace_exit; /* linux_fork =sys_call_table[SYS_fork]; sys_call_table[SYS_fork] =(void *)ktrace_fork; */ linux_ptrace =sys_call_table[SYS_ptrace]; sys_call_table[SYS_ptrace] =(void *)ktrace_ptrace; return(0); } void cleanup_module(void) { printk(KERN_INFO " unloading ktrace module\n"); sys_call_table[SYS_execve] =(void *)linux_execve; sys_call_table[SYS_exit] =(void *)linux_exit; /* sys_call_table[SYS_fork] =(void *)linux_fork; */ sys_call_table[SYS_ptrace] =(void *)linux_ptrace; } <-X-> la parte del codice che segue eventuali figli e` errata, cmq consente di usare sia strace che gdb che ogni altro debugger che altrimenti verrebbe fermato. a questo punto si potrebbe parlare di come si fa l'analisi di un virus, ma praticamente e` tutto deducibile dalla man page di strace e dal significato delle singole syscall x capire cosa fa il virus stesso. --] CONSIGLI DELLA CASA PER INFEZIONI + STEALTH [-- putroppo non ho tempo x far sta roba, ma sono convinto che semplicemente toccando il path di /bin x l'utente infetto in ~/.hidebid, facendo a poco a poco una copia di tutti i binari normalmente utilizzati tipo ls, ps, pstree, find, normalmente utilizzati x riscontare le *anomalie* che invitano a un debug + approfondito, si puo wrapperare l'output in modo da poter senza troppi problemi eseguire processi in bg, far proliferazioni o attacchi + pesanti ecc... considerando che l'output di quei programmi sarebbe alterato dal virus stesso che non consentirebbe quindi all'utente di ottenere spunti di alcun genere per sospettare dell'infezione (a meno che l'utilizzo di un ps axf da parte di un altro utente... dipende sempre cosa si sta cercando di attaccare cmq...). una volta infettati i binari o eventuali file di configurazione personali (il .fetchmailrc ? il .procmailrc sono tutti file di conf che possono consentire l'esecuzione di comandi da remoto in certi casi se adeguatamente modificati, anche questo potrebbe essere un sistema di infezione ed un sistema x assicurarsi l'accesso remoto ad una macchina virata. ed e` possibile occultare la vista di questi file facendo un wrapper a pico/vi/cat/less/more e ai comuni sistemi di visualizzazione di file, in modo che se si richieda l'apertura del file infetto si possa ripristinare l'originale e rimettere la versione infetta dopo l'uscita del programma chiamato. questo e` possibile xke` automatizzabile (quindi implementabile in un virus senza l'ausilio di AI :) e abbastanza stealth xke`, tranne nel caso di una workstation di casa, i mezzi per individuare la modifica di un file binario nella propria homedir possono essere rediretti verso propri binari infetti che non diano informazioni riguardo l'alterazione degli stessi. questo inserirebbe il problema di virus troppo grossi, ma non significa che un file wrapperato debba aver tutto il virus presso di se`, se deve essere infettato un file particolare (ls, ps, ecc...) puo` esser fatto con la parte di codice relativa a se`, senza necessitare il resto. poi la parte polimorfica che sta in questi codici potrebbe prendere il corpo principale del virus, x altre eventuali infezioni da un altro file (non necessariamente se stesso)... un altro punto abbastanza interessante dei virus e` che nulla nega a un file eseguibile di un utente di essere eseguito da un altro utente... gia` in certe distribuzioni di default le home degli utenti sono leggibili a tutti quello dello stesso gruppo, questo non puo` far altro che aumentare la proliferazione del virus, che, cosa da non dimenticare, ha come scopo quello di essere infettato prima o poi dal root e installarsi in un bel /bin/ls o binari avviati con la stessa frequenza :) o far come spiegato sul sito dei THC nel tut sui moduli x il kernel di linux in cui si trova un cenno ai virus sotto forma di LKM, cosa potenzialmente molto + dannosa *se* ben programmata (altrimenti e` dannosa si`, ma in termini di kernel panic...). --] DIFESE SPICCIOLE CONTRO L'ARRIVO DI QUESTE PICCOLE SPORE ? [-- ogni virus tocca l'md5sum, si potrebbe mettere un semplice check dei propri file di conf e dei propri binari (esclusi dal check dei file di sistema) se si e` utenti paranoici e se si e` capaci di fare uno script... in questo caso la modifica dei nostri binari saltera` subito fuori. un altro caso che non ho trattato prima e` quello che un virus infetti anche i sorgenti oltre che i binari... non i sorgenti con l'intero codice del virus xke` e` possibile, ma e` abbastanza stupido mettere in giro un virus con il suo codice completo dentro il binario... ma potrebbe semplicemente aggiungere una parte di codice dopo il main giusto x richiamare il file del virus padre, almeno anche in seguito a una ricompilazione i file rimarranno infetti e senza che il checksum sia alterato :) per difendersi da questo ci sarebbe da fare l'md5sum di TUTTI i file della home, cosa abbastanza pesante xke` anche ogni nostra modifica risulterebbe come "accesso", ma non c'e` altra via... programmi che per loro natura usano la ptrace x bloccare un debug non ne ho visti, puo essere che qualche sw commerciale lo faccia, ma visto come stan le cose si potrebbe predisporre un sistema di logging delle chiamate ptrace(2) e init_module(2) giusto x aver sotto mano l'utilizzo di queste chiamate :) il metodo migliore x individuare un virus che non va a ficcarsi nel kernel e` quello di usare sistemi di individuazione non comuni, tipo... du -abh anziche` ls -l... top o pstree anziche` ps, un virus non potra` mai wrapperare tutti i binari, visto che e` un software stupido che agisce sui sistemi comunemente utilizzati x individuare un virus... basta essere un po' + originali e fotterlo :) ============================================================================== --------------------------------[ EOF 17/18 ]--------------------------------- ==============================================================================