Log Poisoning

Hemos visto en secciones anteriores que si incluimos cualquier archivo que contenga código PHP, este se ejecutará siempre que la función vulnerable tenga los Executeprivilegios necesarios. Los ataques que analizaremos en esta sección se basan en el mismo concepto: escribir código PHP en un campo que controlamos y que se registra en un archivo de registro (es decir poison, contaminateel archivo de registro), y luego incluir dicho archivo para ejecutar el código PHP. Para que este ataque funcione, la aplicación web PHP debe tener privilegios de lectura sobre los archivos de registro, que varían según el servidor.

Como fue el caso en la sección anterior, cualquiera de las siguientes funciones con Executeprivilegios debería ser vulnerable a estos ataques:

Función

Leer contenido

Ejecutar

URL remota

PHP

include()/include_once()

require()/require_once()

NodeJS

res.render()

Java

import

.NETO

include

PHP Session Poisoning

La mayoría de las aplicaciones web PHP utilizan PHPSESSIDcookies, que almacenan datos específicos del usuario en el backend, lo que permite a la aplicación web rastrear la información del usuario mediante sus cookies. Esta información se almacena en sessionarchivos en el backend y se guarda en /var/lib/php/sessions/Linux y C:\Windows\Temp\Windows. El nombre del archivo que contiene los datos del usuario coincide con el nombre de la PHPSESSIDcookie con el sess_prefijo. Por ejemplo, si la PHPSESSIDcookie se configura como el4ukv0kqbvoirg7nkp4dncpk3, su ubicación en el disco sería /var/lib/php/sessions/sess_el4ukv0kqbvoirg7nkp4dncpk3.

Lo primero que debemos hacer ante un ataque de envenenamiento de sesión PHP es examinar nuestro archivo de sesión PHPSESSID y ver si contiene algún dato que podamos controlar y envenenar. Por lo tanto, primero verifiquemos si tenemos una PHPSESSIDcookie configurada en nuestra sesión:

Como podemos ver, PHPSESSIDel valor de nuestra cookie es nhhv8i0o6ua4g88bkdl9u1fdsd, por lo que debería almacenarse en /var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsd. Intentemos incluir este archivo de sesión a través de la vulnerabilidad LFI y veamos su contenido:

Podemos ver que el archivo de sesión contiene dos valores: page, que muestra la página del idioma seleccionado, y preference, que muestra el idioma seleccionado. Este preferencevalor no está bajo nuestro control, ya que no lo especificamos en ningún lugar y debe especificarse automáticamente. Sin embargo, pagesí lo está, ya que podemos controlarlo mediante el ?language=parámetro.

Intentemos configurar pageun valor personalizado (por ejemplo, language parameter) y ver si cambia en el archivo de sesión. Podemos hacerlo simplemente visitando la página ?language=session_poisoningespecificada, como se muestra a continuación:

http://<SERVER_IP>:<PORT>/index.php?language=session_poisoning

Ahora, incluyamos nuevamente el archivo de sesión para ver el contenido:

Nota: Como puede imaginar fácilmente, el valor de la cookie diferirá de una sesión a otra, por lo que deberá utilizar el valor de la cookie que encuentre en su propia sesión para realizar el mismo ataque.

Podemos observar que el archivo de sesión contiene dos valores: pageuno que muestra la página en el idioma seleccionado y preferenceotro que muestra el idioma seleccionado. El preferencevalor de este último no está bajo nuestro control, ya que no lo hemos especificado y debe generarse automáticamente. Sin embargo, el pagevalor del segundo sí está bajo nuestro control, ya que podemos modificarlo mediante el ?language=parámetro correspondiente.

Intentemos establecer el valor de pageun valor personalizado (por ejemplo, language parameter) y veamos si cambia en el archivo de sesión. Podemos hacerlo simplemente visitando la página con ?language=session_poisoningel valor especificado, como se muestra a continuación:

http://<SERVER_IP>:<PORT>/index.php?language=session_poisoning

Ahora, incluyamos nuevamente el archivo de sesión para analizar su contenido:

Esta vez, el archivo de sesión contiene session_poisoningen lugar de es.php, lo que confirma nuestra capacidad para controlar el valor de pageen el archivo de sesión. Nuestro siguiente paso es realizar el poisoningpaso escribiendo código PHP en el archivo de sesión. Podemos escribir una web shell PHP básica cambiando el ?language=parámetro a una web shell codificada en URL, de la siguiente manera:

http://<SERVER_IP>:<PORT>/index.php?language=%3C%3Fphp%20system%28%24_GET%5B%22cmd%22%5D%29%3B%3F%3E

Finalmente, podemos incluir el archivo de sesión y usarlo &cmd=idpara ejecutar comandos:

Nota: Para ejecutar otro comando, es necesario volver a envenenar el archivo de sesión con la web shell, ya que se sobrescribe /var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsdtras la última inclusión. Idealmente, usaríamos la web shell envenenada para escribir una web shell permanente en el directorio web o enviar una shell inversa para facilitar la interacción.

Envenenamiento de registros del servidor

Ambos Apacheservidores Nginxmantienen varios archivos de registro, como `/etc/register` access.logy `/etc/ error.logregister`. El access.logarchivo `/etc/register` contiene información sobre todas las solicitudes realizadas al servidor, incluyendo User-Agentla cabecera de cada solicitud. Dado que podemos controlar la User-Agentcabecera en nuestras solicitudes, podemos usarla para manipular los registros del servidor, como hicimos anteriormente.

Una vez infectados, debemos incluir los registros mediante la vulnerabilidad LFI, para lo cual necesitamos acceso de lectura a los mismos. NginxPor defecto, los registros son legibles por usuarios con pocos privilegios (por ejemplo, usuarios con privilegios limitados www-data), mientras que los Apacheregistros de seguridad solo son legibles por usuarios con altos privilegios (por ejemplo, rootusuarios con privilegios elevados adm). Sin embargo, en servidores antiguos o mal configurados Apache, estos registros podrían ser legibles por usuarios con pocos privilegios.

Por defecto, Apachelos registros se encuentran en `/usr/localhost` /var/log/apache2/en Linux y en C:\xampp\apache\logs\`/usr/localhost` en Windows, mientras que Nginxlos registros se encuentran en `/usr/localhost` /var/log/nginx/en Linux y en C:\nginx\log\`/usr/localhost` en Windows. Sin embargo, en algunos casos, los registros pueden estar en una ubicación diferente, por lo que podríamos usar una lista de palabras LFI para realizar pruebas de fuzzing y determinar su ubicación, como se explicará en la siguiente sección.

Intentemos entonces incluir el registro de acceso de Apache desde /var/log/apache2/access.log, y veamos qué obtenemos:

Como podemos ver, podemos leer el registro. El registro contiene el encabezado remote IP address, el encabezado de solicitud request pageHTTP , el encabezado de solicitud HTTP response codey el User-Agentencabezado de solicitud HTTP. Como se mencionó anteriormente, User-Agentcontrolamos el encabezado de solicitud HTTP mediante los encabezados de solicitud HTTP, por lo que deberíamos poder modificar este valor.

Consejo: Los registros suelen ser enormes y cargarlos en una vulnerabilidad LFI puede tardar bastante o incluso provocar la caída del servidor en el peor de los casos. Por lo tanto, tenga cuidado y sea eficiente con ellos en un entorno de producción, y evite enviar solicitudes innecesarias.

Para ello, interceptaremos Burp Suitenuestra solicitud LFI anterior y modificaremos la User-Agentcabecera a Apache Log Poisoning:

Nota: Dado que todas las solicitudes al servidor se registran, podemos envenenar cualquier solicitud a la aplicación web, y no necesariamente la de LFI como hicimos anteriormente.

Como era de esperar, nuestro valor personalizado de User-Agent es visible en el archivo de registro incluido. Ahora, podemos envenenar la User-Agentcabecera configurándola con una web shell PHP básica:

También podemos envenenar el registro enviando una solicitud a través de cURL, como se muestra a continuación:

echo -n "User-Agent: <?php system(\$_GET['cmd']); ?>" > Poison

curl -s "http://<SERVER_IP>:<PORT>/index.php" -H @Poison

Dado que el registro ahora debería contener código PHP, la vulnerabilidad LFI debería ejecutar este código y deberíamos poder obtener ejecución remota de código. Podemos especificar un comando para ejecutar con ( &cmd=id):

Vemos que el comando se ejecutó correctamente. El mismo ataque se puede realizar Nginxtambién en los registros.

Consejo: La User-Agentcabecera también se muestra en los archivos de proceso del /proc/directorio Linux. Por lo tanto, podemos intentar incluir los archivos /proc/self/environ`.bashrc` o /proc/self/fd/N`.bashrc` (donde N es un PID, generalmente entre 0 y 50) y es posible que podamos realizar el mismo ataque en estos archivos. Esto puede resultar útil si no tenemos acceso de lectura a los registros del servidor; sin embargo, estos archivos también podrían ser legibles únicamente por usuarios con privilegios.

Finalmente, existen otras técnicas similares de manipulación de registros que podemos utilizar en diversos registros del sistema, dependiendo de a qué registros tengamos acceso de lectura. A continuación, se muestran algunos de los registros de servicio que podríamos leer:

  • /var/log/sshd.log

  • /var/log/mail

  • /var/log/vsftpd.log

Primero deberíamos intentar leer estos registros mediante LFI y, si logramos acceder a ellos, podemos intentar manipularlos como hicimos anteriormente. Por ejemplo, si los sshservicios ftpestán expuestos y podemos leer sus registros mediante LFI, podemos intentar iniciar sesión en ellos y configurar el nombre de usuario con código PHP. Al incluir sus registros, el código PHP se ejecutaría. Lo mismo se aplica a los mailservicios: podemos enviar un correo electrónico con código PHP y, al incluirlo en el registro, el código PHP se ejecutaría. Podemos generalizar esta técnica a cualquier registro que contenga un parámetro que controlemos y que podamos leer mediante la vulnerabilidad LFI.

Last updated