SecGame #1: Sauron - Resolución Nivel 7

Saludos a todos los que habéis seguido esta resolución hasta el final, y a todos los que a partir de ahora useis estas pequeños tutoriales para cualquier menester que estimeis útil.

Vaya por delante decir que os agradecemos el interés mostrado, las dudas planteadas, y en definitiva que hayáis colaborado en la materialización de este proyecto. Gracias también a todos los que usáis nuestro SecGame como material didáctico en cursos, masters y otras formaciones a profesionales. Sin más, vamos ya con el nivel 7.

Como sabemos en este punto ( y por si lo hemos olvidado siempre podemos mirar el /etc/passwd ) el sistema contiene únicamente tiene 3 usuarios: blindware, intranet y developer. De estos, developer parece estar bastante al margen, y con los otros dos ya podemos ejecutar comandos. Únicamente, nos queda, pués, intentar conseguir acceso como root a este sistema.

Y aquí hacemos un paréntesis, en muchos sistemas al llegar a una situación como esta, únicamente tendremos la opción del exploit local para el kernel. En el caso que nos ocupa, y para hacerlo más didáctico, es posible obtener root, sin explotar nada a nivel de kernel.

Vaya por delante, que la explotación de este nivel requiere de paciencia, y de unir dos conceptos un poco “dispersos”. No llegamos a calificar su explotación de “idea feliz”, puesto que hay un camino lógico que permite hacerlo, pero desde luego, no es sencillo darse cuenta del mismo. A pesar de que pueda parecer un nivel diseñado ex profeso para el juego, este fallo de seguridad puede ser extrapolado, total o parcialmente, a sistemas reales en los que usuarios sin privilegios deben desempeñar tareas administrativas. Hecho el “disclaimer”, vamos a ver los pasos a dar para explotarlo.

Hasta el momento, hay algo bastante importante, que hemos obviado hacer, quizá por no necesitarlo: obtener los paths que contiene el servidor web. Dado que el directorio “/var/www” nos impide la lectura, es cuestión de hacer uso del fichero de configuración del propio apache, y del comando grep para obtener la información: cat /etc/httpd/conf/httpd.conf | grep /var/www. De esta forma obtendremos una información parecida a la siguiente:

DocumentRoot "/var/www/html"

Alias /icons/ "/var/www/icons/"


ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased


# /var/www/error/include/ files and

Alias /error/ "/var/www/error/"


DocumentRoot /var/www/blindware/htdocs

DocumentRoot /var/www/intranet/htdocs


En definitiva tenemos el siguiente listado de directorios: html, icons, cgi-bin, error, blindware/htdocs e intranet/htdocs dentro del directorio /var/www/.

A continuación, debemos verificar los permisos que tenemos sobre cada uno de esos directorios, haciendo uso de un simple "ls -la", encontrando una "pequeña" sorpresa:

/var/www/cgi-bin:

total 16

drwxr-x--- 2 intranet apache 4096 Jun 22 20:06 .

d--x--x--x 8 root root 4096 May 12 13:52 ..

El directorio /var/www/cgi-bin es propiedad del usuario intranet. Este error, que rara vez se da en entornos altamente estructurados, como puede ser un proveedor de hosting, donde los usuarios tienen unos permisos predefinidos, es más frecuente de lo que parece en otros entornos de producción, por ejemplo grandes empresas u organismos públicos de gran tamaño, donde se dan cambios relativamente frecuentes, donde se necesita compartir información entre usuarios, y donde el nivel de seguridad local, con el paso del tiempo, de las necesidades, y de las distintas modificaciones, queda mermado.

Este fallo, concretamente, nos permite ganar la ejecución de comandos otro usuario: apache. ¿Cómo? Si recordamos, al principio de estas resoluciones, dijimos que al menos 3 hosts, estaban siendo servidos por apache, uno era www.blindware.inc, otro intranet.blindware.inc, y un tercero, el servido mediante https. Pues bien, el servicio HTTPS tiene su directorio CGI en /var/www/cgi-bin/.

Por tanto, únicamente deberemos realizar una copia de la shell en PHP que tengamos en el sistema para ejecutar comandos a ese directorio, para empezar a ejecutar comandos con nuestras nuevas credenciales: uid=48(apache) gid=48(apache) groups=48(apache)

A partir de aquí es cuestión de paciencia, y de ser capaces de revisar los servicios activos en el sistema, buscando una vulnerabilidad de configuración, para ello podemos hacer uso del comando "ps", de listar los servicios con "chkconfig", o de pasearnos por el "init.d". El hecho es que si paulatinamente vamos revisando (versiones y ficheros de configuración) de todos los servicios activos: syslog, mysql, cron, anacron, sendmail, etc ( algo que es bastante tedioso, todo sea dicho )
encontraremos lo siguiente dentro de la configuración del demonio cron, en el fichero crontab:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
* * * * * root run-parts /etc/cron.every
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

Hay una entrada “cron.every”, que no es natural en estos sistemas, no obstante, aunque no la hubiese, lo normal sería revisar cada uno de los directorios y ver qué se ejecuta en ellos.

/etc/cron.every:

total 4

lrwxrwxrwx 1 root root 22 May 16 20:10 www.do -> /var/www/html/doit.txt


En negrita hemos resaltado la vulnerabilidad. Si no fijamos, cron.every, ejecuta cada minuto el script localizado en /var/www/html/doit.txt cuyos permisos son los siguientes:

total 12
-rwxr-xr-x 1 apache apache 124 May 16 20:12 doit.txt
-rw-r--r-- 1 apache apache 0 May 12 21:15 index.html

El fallo, contrario a cualquier criterio de buenas prácticas, radica en haber enlazado un proceso administrativo con privilegios de root a un script que bajo determinadas circunstancias, por muy remotas que estas sean, puede ser controlado por un usuario ajeno a root.

A partir de aquí, vamos a ver el proceso para obtener la cuenta de root, vaya por delante que es únicamente una demostración de concepto, y desde luego, no es precisamente la forma más sutil de obtenerlo.

Primero, añadiremos una línea al fichero doit.txt y tendremos cambiada la contraseña de root del sistema, a r00t3d. Para eso ejecutamos el siguiente comando (urlencodeado):

echo+%22echo+root%3Ar00t3d+%7C+%2Fusr%2Fsbin%2Fchpasswd%22+%3E+%2Fvar
%2Fwww%2Fhtml%2Fdoit.txt


Por último y para concluir, deshabilitamos el firewall del sistema y habilitamos ssh, con lo que conseguiremos un acceso remoto:

Deshabilitar FW:
echo+%22%2Fetc%2Finit.d%2Fiptables+stop%22+%3E+%2F
var%2Fwww%2Fhtml%2Fdoit.txt


Habilitar SSHD:
echo+%22%2Fetc%2Finit.d%2Fsshd+start%22+%3E+%2F
var%2Fwww%2Fhtml%2Fdoit.txt

Conectamos y aquí tenemos el resultado:

[root@sauron ~]# id
uid=0(root) gid=0(root) grupos=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)

Poco más, enhorabuena a todos los que hayáis conseguido superar el reto planteado con Sauron, y enhorabuena también a todos los que aunque no lo hayáis superado hayáis mejorado vuestros conocimientos y habilidades. Hasta el siguiente SecGame y hasta nuevos proyectos que lanzaremos en breve y esperamos sean de vuestro interés.