Write up SHX 3 (PHP Security) - Hello Photo
Este é o último Write Up sobre o SHX 3 do Shellter Labs.
Descrição do problema:
Seu amigo te pediu para verificar se o novo site que ele está desenvolvendo está seguro. Você pode ajudá-lo?
Também é oferecido o link para o site a ser explorado, que tem essa cara:
Logo ao abrir o site, é possível ver que se trata de um site de upload de imagens, então, vamos entender como está sendo feito o processo de upload, subindo uma imagem qualquer:
Após fazer o upload da imagem é exibida a seguinte página:
Conforme é exibido na Fig3, as imagens são salvas no diretório uploads, e tendo essa informação, podemos tentar subir um arquivo PHP para obter uma shell.
Ao tentar subir um arquivo em PHP com um simples “Hello World”, a aplicação retorna um erro:
Minha primeira tentativa de burlar esta validação, foi utilizando o Burp Suite para alterar o Mime Type do arquivo na requisição , mas não funcionou, o erro persistiu, e percebi que a validação verificava parte do conteúdo do arquivo para saber se era uma imagem, então a solução foi injetar no conteúdo da imagem um código PHP. Eu utilizei o GIMP para fazer isto, mas você pode fazer isso com o Photoshop ou até mesmo editando o arquivo com o VIM.
Foi feito da seguinte forma:
Após isto, basta salvar e modificar a extensão da imagem para .php e fazer o upload novamente no sistema. E dessa vez funciona:
Feito isso, temos uma shell pronta para uso, agora é só procurar a flag pelo sistema de arquivo do servidor.
Para quem tiver curiosidade, baixei o arquivo uploader.php e este é o código inseguro:
<?php
$imageinfo = getimagesize($_FILES['uploadedfile']['tmp_name']);
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') {
echo "Error: Please provide a valid image (GIF or JPEG).<br><br>Click <a href=\"./\">here</a> to go back.";
exit;
}
$uploaddir = 'uploads/';
$temp = explode(".", basename($_FILES['uploadedfile']['name']));
$newfilename = round(microtime(true)) . '.' . end($temp);
$uploadfile = $uploaddir . basename($_FILES['uploadedfile']['name']);
//if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploadfile)) {
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploaddir . $newfilename)) {
echo "File <b>" . $newfilename . "</b> is valid, and was successfully uploaded to the uploads directory.<br><br>Click <a href=\"./\">here</a> to go back.";
} else {
echo "Oops! Something went wrong.";
}
?>
Neste caso específico, uma solução possível para evitar que arquivos PHPs fossem executados na pasta de uploads seria criar um .htaccess e adicionar o código:
php_flag engine off
Lógico que isto não garante 100%, mas resolveria este caso.
Se você encontrou algum erro, tem algo a acrescentar ou alguma dúvida, comente abaixo!