Normalmente, se un attacco è stato portato "bene" le tracce lasciate sono poche. Però spesso i sistemi non si comportano esattamente come ci si aspetterebbe. Se l'amministratore del sistema analizza con una certa frequenza i log si può accorgere di qualcosa di strano. Nel nostro caso si vedono comparire nei messages una serie di segnalazioni del tipo:
sandbox:/var/tmp# tail -f /var/log/messages
Aug 17 13:47:17 sandbox kernel: [249600.574872] netstat[8292]: segfault at 0 ip b7e8fe90 sp bfd9403c error 4 in libc-2.7.so[b7e1a000+155000]
Aug 17 13:47:25 sandbox kernel: [249608.839057] netstat[8648]: segfault at 0 ip b7e1ce90 sp bfc216cc error 4 in libc-2.7.so[b7da7000+155000]
Aug 17 13:47:25 sandbox kernel: [249608.922034] netstat[8651]: segfault at 0 ip b7e95e90 sp bfc9c73c error 4 in libc-2.7.so[b7e20000+155000]
Aug 17 13:47:25 sandbox kernel: [249608.983258] netstat[8654]: segfault at 0 ip b7e6be90 sp bf97041c error 4 in libc-2.7.so[b7df6000+155000]
tutte queste segnalazioni di segmentation fault di netstat sono tutt'altro che normali. Infatti:
sandbox:/tmp/shv6/conf# netstat -an
Segmentation fault
Questa cosa decisamente dovrebbe mettere in guardia qualsiasi amministratore.
Come è possibile che un binario che fino a ora ha sempre funzionato ora, invece, senza alcun motivo apparente va in errore (...non stiamo parlando di winzozz :D ).
Verifichiamo i processi che stanno girando sul sistema:
altro fatto strano: risulta avviato inetd che normalmente rimane non attivo sui sistemi critici:
root 7884 1 0 13:45 ? 00:00:00 /usr/sbin/inetd
root 8809 3381 0 13:54 pts/0 00:00:00 ps -ef
sandbox:/proc# date
lun ago 17 13:54:53 CEST 2009
una rapida occhiata al file di configurazione di inetd non rivela niente di rilevante.
Provando ad utilizzare lsof per verificare quali processi siano attivi si verifica un altro comportamento anomalo, cioè lsof non restituisce alcun output:
sandbox:# lsof -i:22
sandbox:# lsof
sandbox:#
In condizioni normali questi eventi sono sufficienti per convincere un amministratore a mettere offline il nodo e a tenerlo in quarantena.
Una rapida occhiata ai processi di sistema toglie ogni dubbio:
sandbox:/var/log# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Aug14 ? 00:00:15 init [2]
root 2 0 0 Aug14 ? 00:00:00 [kthreadd]
root 3 2 0 Aug14 ? 00:00:00 [migration/0]
root 4 2 0 Aug14 ? 00:00:05 [ksoftirqd/0]
root 5 2 0 Aug14 ? 00:00:00 [watchdog/0]
root 6 2 0 Aug14 ? 00:01:09 [events/0]
root 7 2 0 Aug14 ? 00:00:00 [khelper]
root 39 2 0 Aug14 ? 00:00:03 [kblockd/0]
root 41 2 0 Aug14 ? 00:00:00 [kacpid]
root 42 2 0 Aug14 ? 00:00:00 [kacpi_notify]
root 85 2 0 Aug14 ? 00:00:00 [kseriod]
root 118 2 0 Aug14 ? 00:00:00 [pdflush]
root 119 2 0 Aug14 ? 00:00:13 [pdflush]
root 120 2 0 Aug14 ? 00:00:00 [kswapd0]
root 121 2 0 Aug14 ? 00:00:00 [aio/0]
root 560 2 0 Aug14 ? 00:00:00 [ksuspend_usbd]
root 561 2 0 Aug14 ? 00:00:00 [khubd]
root 605 2 0 Aug14 ? 00:00:00 [ata/0]
root 606 2 0 Aug14 ? 00:00:00 [ata_aux]
root 706 2 0 Aug14 ? 00:00:04 [kjournald]
root 782 1 0 Aug14 ? 00:00:02 udevd --daemon
root 1117 2 0 Aug14 ? 00:00:00 [kpsmoused]
root 1395 2 0 Aug14 ? 00:00:00 [kjournald]
root 1398 2 0 Aug14 ? 00:00:00 [kjournald]
root 1400 2 0 Aug14 ? 00:00:02 [kjournald]
root 1401 2 0 Aug14 ? 00:00:05 [kjournald]
daemon 1453 1 0 Aug14 ? 00:00:00 /sbin/portmap
statd 1469 1 0 Aug14 ? 00:00:00 /sbin/rpc.statd
root 1665 1 0 Aug14 ? 00:00:03 /usr/sbin/rsyslogd -c3
root 1676 1 0 Aug14 ? 00:00:00 /usr/sbin/acpid
Debian-e 1943 1 0 Aug14 ? 00:00:01 /usr/sbin/exim4 -bd -q30m
daemon 1961 1 0 Aug14 ? 00:00:00 /usr/sbin/atd
root 1981 1 0 Aug14 ? 00:00:12 /usr/sbin/cron
root 2002 1 0 Aug14 tty2 00:00:00 /sbin/getty 38400 tty2
root 2004 1 0 Aug14 tty3 00:00:00 /sbin/getty 38400 tty3
root 2005 1 0 Aug14 tty4 00:00:00 /sbin/getty 38400 tty4
root 2008 1 0 Aug14 tty5 00:00:00 /sbin/getty 38400 tty5
root 2009 1 0 Aug14 tty6 00:00:00 /sbin/getty 38400 tty6
root 3364 1 0 Aug14 ? 00:00:00 /usr/sbin/sshd
root 7706 1 0 Aug17 tty1 00:00:00 /sbin/getty 38400 tty1
root 7884 1 0 Aug17 ? 00:00:00 /usr/sbin/inetd
root 9074 3364 0 13:31 ? 00:00:10 sshd: root@pts/0
root 9077 9074 0 13:31 pts/0 00:00:01 -bash
root 9136 9077 0 15:09 pts/0 00:00:00 ps -ef
Il comando ps restituisce 44 processi. Però andando a vedere il contenuto di /proc
sandbox:~# ls /proc/ |grep '[0-9]'|wc -l
46
I processi sono 46. Quindi ps non restituisce info almeno su due processi, le probabilità che il sistema sia compromesso sono molto elevate.
Un ultimo test taglia la testa al toro. Verifichiamo la tabella degli hash md5 che avevamo in precedenza creato:
sandbox:~# debsums -c -m /mnt/sda1/md5_hash_table
/var/lib/aspell/it.compat
/bin/ls
/usr/bin/md5sum
/usr/bin/find
/bin/login
/bin/netstat
/sbin/ifconfig
/bin/ps
/usr/bin/top
/usr/bin/pstree
Come si vede sono cambiati gli hash di alcuni file fondamentali, come netstat che, abbiamo visto, non si riesce ad eseguire.... giustamente è cambiato anche md5sum, il che fa supporre che il rootkit cerchi di bypassare questo genere di controllo, alterando gli hash del sistema operativo.
Prima di isolare il sistema, da un'altra macchina, verifichiamo se qualcosa è cambiato nel networking dato che netstat non funziona:
root@slax:~# nmap -sS -sV -p1-65535 10.41.113.99
Starting Nmap 4.60 ( http://nmap.org ) at 2009-08-18 14:30 GMT
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns_servers
Stats: 0:00:45 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 66.67% done; ETC: 14:31 (0:00:05 remaining)
Interesting ports on 10.41.113.99:
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh (protocol 2.0)
111/tcp open rpcbind 2 (rpc #100000)
37599/tcp open status 1 (rpc #100024)
37998/tcp open ssh SCS sshd 2.0.13 (protocol 1.5)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
SF-Port22-TCP:V=4.60%I=7%D=8/18%Time=4A8ABB42%P=i486-Slackware-linux-gnu%r
SF:(NULL,20,"SSH-2\.0-OpenSSH_5\.1p1\x20Debian-5\r\n");
MAC Address: 08:00:27:B3:D3:4E (Cadmus Computer Systems)
Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 46.056 seconds
Sorpresa sorpresa :) una seconda istanza di un ssh su 37998. Vediamo un po':
root@slax:~# nc 10.41.113.99 37998
SSH-1.5-2.0.13
Quindi il rootkit ha installato anche una backdoor. A questo punto ogni ulteriore analisi compiuta col sistema attivo e online è inutile e potenzialmente dannosa. Inutile perchè il rootkit è fatto apposta per nascondere le proprie tracce (infatti ad una prima analisi non è possibile determinare nè dove risieda questo secondo demone ssh, nè dove sia la corrispondente configurazione), dannosa perchè l'attaccante, se il sistema è online, può ancora connettersi e rimuovere eventuali tracce.
Supponiamo, quindi, di mettere offline il sistema. Se dobbiamo raccogliere informazioni utili per una analisi forense ci sono alcune attenzioni da avere. Prima di tutto bisogna effettuare una copia del o dei dischi del sistema impattato. Conviene prendere un hd nuovo da collegare al sistema della stessa dimensione del disco presente. Il boot va effettuato in modo "pulito", cioè o da un cdrom o da una chiave usb. L'importante è non far riavviare il sistema dal proprio disco "contaminato". Questo per evitare ulteriori eventuali modifiche dei file che impediscano di stabilire una linea temporale precisa.
Effettuiamo, quindi, il boot da una live.
Prima di tutto una copia fisica. Supponiamo che il disco incriminato sia /dev/hda e il nuovo disco sia /dev/hdb:
sandbox:~# dd if=/dev/zero of=/dev/hdb
sandbox:~# dd if=/dev/hda of=/dev/hdb
Il primo dd serve a "ricoprire" di zero tutto il disco in modo da evitare che qualche informazione spuria presente su hdb vada ad inficiare la validità della copia.
Verifichiamo che le copie siano consistenti:
sandbox:~# md5sum /dev/hda
b335358b2054cb9d68325d3fa4687531 /dev/hda
sandbox:~# md5sum /dev/hdb
b335358b2054cb9d68325d3fa4687531 /dev/hdb
sandbox:~# openssl sha1 /dev/hda
SHA1(/dev/hda)= 159ef7f052e1579b527a582cfb8ad4e62cdbc94c
sandbox:~# openssl sha1 /dev/hdb
SHA1(/dev/hdb)= 159ef7f052e1579b527a582cfb8ad4e62cdbc94c
Perchè usare due algoritmi di hash? Se si stanno compiendo analisi per l'utilizzo forense è necessario tutelarsi dalla possibilità che, nel frattempo, si scopra una possibile collisione nei protocolli di hashing. Così facendo se anche uno dei protocolli dovesse venir bucato, esiste sempre l'altro che fa fede. Se non ricordo male qualcuno ha dimostrato la possibilità di generare due hash uguali per file diversi sfruttando una collisione della routine di compressione dell'MD5.
L'uguaglianza degli hash implica che i due dischi sono uguali, per quanto riguarda i contenuti, al byte.
Infine facciamo una terza copia in modo del tutto analogo al precedente, utilizzando però un file e non un supporto fisico:
sandbox:~# dd if=/dev/zero of=/tmp/dump_hd
...
sandbox:~# md5sum /tmp/dump_hd
...
In questo modo i due hd fisici rimarranno come reperti, mentre l'analisi verrà effettuata sul dump appena creato. Chiaramente se non ci sono necessità legali non c'è bisogno di questo... anche se magari avere una immagine può aiutare nel caso si corrompa l'hd.
A questo punto, per eseguire una vera e propria analisi forense ci sarebbero altre cose da fare, a noi interessa capire solo cosa sia successo al sistema.
Come dicevo in precedenza io stesso mi sono auto attaccato, però l'ho fatto alla maniera "lamer" cioè ho banalmente applicato un rootkit, senza curarmi troppo di cosa facesse. Per cui lo scopro ora in diretta :D
Lavoriamo sull'immagine precedentemente raccolta. Supponiamo di montarla su /tmp/dump
Attenzione a montare l'immagine. Bisogna assicurarsi che il fs non venga modificato, non venga modificata l'ora di accesso agli inode dei vari file, chiaramente bisogna evitare che si eseguano file infetti. In sostanza l'immagine va montata cone le opzioni ro,noatime,noexec,nodev
Importante: da ora in poi assumiamo che il boot sia stato effettuato da un sistema pulito.
Prima di tutto un controllo anti rootkit:
box:~# chkrootkit -q -r /tmp/dump
Checking `ifconfig'... INFECTED
Checking `netstat'... INFECTED
Checking `pstree'... INFECTED
Checking `top'... INFECTED
/etc/ld.so.hash
Possible t0rn v8 (or variation) rootkit installed
The following suspicious files and directories were found:
/lib/init/rw/.ramfs
Warning: Possible Showtee Rootkit installed
/usr/include/file.h /usr/include/proc.h
Possible ShKit rootkit installed
You have 3 process hidden for readdir command
You have 5 process hidden for ps command
Mi pare che sia abbastanza significativo l'output :)
Vengono segnalati 5 processi nascosti. In effetti 5 nascosti al ps, 3 al readdir, risulta la differenza di 2 che avevamo visto prima facendo il confronto tra ps e il contenuto di /proc.
Ora con l'immagine montata su un altro sistema si riesce ad accedere a quei punti del fs che erano stati "oscurati" dal rootkit. Troviamo lo script per rimuovere l'utente dai log, i tools per bypassare i normali ids... si può, quindi, avere una idea generale del funzionamento:
1) vengono installate versioni trojanized dei principali comandi di sistema.
2) si determina, mediante il check di un paricolare file (penso /lib/init/rw/.ramfs) se il rootkit è installato, in modo da evitare sovrainstallazioni
3) viene creata una backdoor utilizzando un demone ssh dedicato
4) vengono installati tutti i tools necessari a nascondere le proprie tracce
Generalmente, ma non è stato questo il caso, il trojan tende a mantenere delle copie "sane" dei file che infetta, in modo che l'attaccante possa controllare effettivamente il sistema. Per esempio il comando ls non restituisce nulla nella directory nella quale si trova il trojan, così come ps maschera i processi relativi al rootkit. Le versioni non compromesse, invece, funzionano correttamente.
Come dicevo si tratta di un caso semplice (anche perchè l'ho fatto io :D ) e sicuramente ci sarebbero molte più analisi da effettuare. Però questo articolo voleva solo fornire degli spunti e, soprattutto, far considerare che un malfunzionamento di un comando (così come un ouptup strano e non consueto) dovrebbero mettere subito in allarme qualsiasi sysadm e indurlo ad approfondire la cosa. Poi c'è un secondo aspetto: il logging. Spesso i log vengono trascurati e alle volte, come in questo caso, possono venir manomessi privando quindi il sysadm di una preziosissima fonte di informazioni. Si può rimediare mediante logging su un sistema terzo, che introduce una complessità maggiore all'attaccante.
Magari, in un futuro, proverò ad inserire un articolo più completo sulla fase di analisi di un sistema compromesso.
Come al solito, se ci sono questioni o commenti postate pure :)


0 commenti:
Posta un commento