PHP - Deserialization + Autoload Classes
Primeiro, você deve verificar o que são Classes de Autocarregamento.
PHP desserialização + spl_autoload_register + LFI/Gadget
Estamos em uma situação onde encontramos uma desserialização PHP em um aplicativo da web sem nenhuma biblioteca vulnerável a gadgets dentro do phpggc
. No entanto, no mesmo contêiner, havia uma outra aplicação da web do composer com bibliotecas vulneráveis. Portanto, o objetivo era carregar o carregador do composer da outra aplicação da web e abusá-lo para carregar um gadget que irá explorar aquela biblioteca com um gadget da aplicação da web vulnerável à desserialização.
Passos:
Você encontrou uma desserialização e não há nenhum gadget no código do aplicativo atual
Você pode abusar de uma função
spl_autoload_register
como a seguinte para carregar qualquer arquivo local com extensão.php
Para isso, você usa uma desserialização onde o nome da classe estará dentro de
$name
. Você não pode usar "/" ou "." em um nome de classe em um objeto serializado, mas o código está substituindo os underlines ("_") por barras ("/"). Portanto, um nome de classe comotmp_passwd
será transformado em/tmp/passwd.php
e o código tentará carregá-lo. Um exemplo de gadget será:O:10:"tmp_passwd":0:{}
Se você tiver um upload de arquivo e puder fazer o upload de um arquivo com a extensão .php
, você pode abusar dessa funcionalidade diretamente e obter RCE facilmente.
No meu caso, eu não tinha nada assim, mas havia dentro do mesmo contêiner outra página da web do composer com uma biblioteca vulnerável a um gadget phpggc
.
Para carregar essa outra biblioteca, primeiro você precisa carregar o carregador do composer da outra aplicação web (porque o da aplicação atual não terá acesso às bibliotecas da outra). Sabendo o caminho da aplicação, você pode fazer isso facilmente com:
O:28:"www_frontend_vendor_autoload":0:{}
(No meu caso, o carregador do composer estava em/www/frontend/vendor/autoload.php
)Agora, você pode carregar o carregador da outra aplicação, então é hora de
gerar o payload phpgcc
para usar. No meu caso, useiGuzzle/FW1
, o que me permitiu escrever qualquer arquivo no sistema de arquivos.NOTA: O gadget gerado não estava funcionando, para que funcionasse, eu modifiquei esse payload
chain.php
do phpggc e defini todos os atributos das classes de privado para público. Caso contrário, após desserializar a string, os atributos dos objetos criados não teriam nenhum valor.Agora temos o caminho para carregar o carregador da outra aplicação e ter um payload phpggc que funcione, mas precisamos fazer isso na MESMA REQUISIÇÃO para que o carregador seja carregado quando o gadget for usado. Para isso, enviei um array serializado com ambos os objetos como:
Você pode ver primeiro o carregador sendo carregado e depois o payload
Agora, podemos criar e escrever um arquivo, no entanto, o usuário não pôde escrever em qualquer pasta dentro do servidor web. Portanto, como você pode ver no payload, o PHP chamando
system
com algum base64 é criado em/tmp/a.php
. Em seguida, podemos reutilizar o primeiro tipo de payload que usamos como LFI para carregar o carregador do composer do outro aplicativo da web para carregar o arquivo/tmp/a.php
gerado. Basta adicioná-lo ao gadget de desserialização:
Resumo da carga útil
Carregar o autoload do composer de um aplicativo da web diferente no mesmo contêiner
Carregar um gadget phpggc para abusar de uma biblioteca do outro aplicativo da web (o aplicativo da web inicial vulnerável à desserialização não tinha nenhum gadget em suas bibliotecas)
O gadget irá criar um arquivo com uma carga útil PHP nele em /tmp/a.php com comandos maliciosos (o usuário do aplicativo da web não pode escrever em nenhuma pasta de nenhum aplicativo da web)
A parte final de nossa carga útil usará carregar o arquivo php gerado que executará comandos
Eu precisei chamar essa desserialização duas vezes. Nos meus testes, na primeira vez o arquivo /tmp/a.php
foi criado mas não carregado, e na segunda vez foi carregado corretamente.
Last updated