Diversas aplicações modernas são desenvolvidas PHP, juntamente com diversas outras aplicações web em diferentes frameworks PHP, como Laravel e Symfony. Nesse cenário, nós podemos utilizar PHP Wrappers para nos ajudar a explorar vulnerabilidades encontradas ou até mesmo conseguir um Remote Code Execution.
Os PHP Wrapper permitem o acesso a diferentes fluxos de entrada/saída (I/O) no nível da aplicação, como entrada/saída padrão, descritores de arquivos e fluxos de memória. Isso pode ser extremamente útil para desenvolvedores PHP. Entretanto, como um atacante, nós podemos utilizar esses wrappers para auxiliar na exploração e conseguir revelar o código fonte PHP, arquivos ou até mesmo executar códigos no sistema. Isso pode ser utilizado em diversas vulnerabilidades, tais como em XXE e LFI.
Filter Wrapper
Filtros PHP são um tipo de PHP Wrappers, eles podem ser utilizados quando nós queremos passar diferentes tipos de input e filtrar utilizando algum filtro que nós especificarmos. Para utilizar PHP Wrappers, nós podemos utilizar php://
na nossa string, e nós podemos acessar o filtro PHP através de php://filter/
.
O filter
wrapper tem diversos parâmetros, mas os mais utilizados em ataques são os parâmetros resources
e read
. O parâmetro resource
é necessário para o wrapper filter
, e com isso nós podemos especificar qual fluxo nós gostaríamos de aplicar o filtro (exemplo, um arquivo local), enquanto o parâmetro read
especifica qual filtro iremos aplicar na entrada.
Existem quatro tipos de filtros disponíveis para uso, que são String Filters, Conversion Filters, Compresion Filters e Encryption Filters. Você pode ler mais a respeito de cada um deles nos links disponibilizados, mas o filtro mais útil e que mais vamos utilizar é o convert.base64-encode
.
Uma maneira de tentar encontrar arquivos de código fonte no servidor, é utilizando a ferramenta Ffuf
Exemplo
Um exemplo de Input Filter para conseguirmos ler o código fonte, pode ser construído como:
$payload = "php://filter/read=convert.base64-encode/resource=config.php"
Data Wrapper
O wrapper data permite incluir texto externo, incluindo código PHP. Entretanto, isso só é possível se a configuração allow_url_include
está definida como verdadeira nas configurações do PHP. Então, para confirmar se essa configuração está ativada, nós podemos ler o arquivo através de um LFI.
Verificando os arquivos de configuração do PHP
Para fazer isso, nós podemos usar uma vulnerabilidade (como o LFI) para ler o conteúdo de configurações, localizado em /etc/php/X.Y/apache2/php.ini
para Apache ou /etc/php/X.Y/fpm/php.ini
para Ngix, onde X.Y
é a versão do PHP. Nós podemos começar com a versão mais recente do PHP e ir decrementando até encontrar o arquivo de configurações.
curl "http://0x6a70.com/index.php?language=php://filter/read=convert.base64-encode/resource=../../../../../../etc/php/7.4/apache2/php.ini"
Se nós tivermos um
echo '<BASE64>' | base64 -d | grep allow_url_include
allow_url_include = On
Então podemos conseguir um Remote Code Execution no servidor.
Remote Code Execution
Com o allow_url_include
estiver ativado, nós podemos utilizar o data wrapper
para realizar um Remote Code Execution. Para isso, podemos utilizar uma Web Shell, como por exemplo:
echo '<?php system($_GET["cmd"]) ?>' | base64
Para então, enviar o payload malicioso para o servidor.
curl http://0x6a70.com/index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8+&cmd=id
Expect Wrapper
O wrapper expect
pode ser utilizado também para executar comandos e fluxos diretamente na máquina do servidor. O funcionamento do expect
é muito parecido com as Web Shell que anteriormente descritas, mas não é necessário upar uma Web Shell, visto que é designado para executar comandos.
Contudo, expect
é um PHP Wrapper externo e precisa ser instalado e ativado manualmente no backend do servidor.
Nós podemos ver se a extensão expect
está instalada no sistema da mesma maneira que verificamos as configurações.
curl http://0x6a70.com/index.php?language=expect://id
Com essa extensão, ainda é possível explorar XXE