Guía Básica de Log Poisoning: Qué Es y Cómo Protegerte
8/31/2024
Que es el Log Poisoning?
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
Vamos e empezar creando una imagen con la ultima versión de Ubuntu:
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
<?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
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...
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
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!




0 comentarios