Essa semana, o SidHawks falou que conseguiu virar admin no nosso site sem a nossa permissão... Você consegue descobrir como?

a flag fica em /flag.txt
BOITA{0nly_4dm1nCan_R34d_f1l3z}

O código começa nos apresentando um código simples em PHP, sendo ele:

<html>  
    <head>       
    <title>pwnme</title>  
    </head>
<?php  
  
define('SECRET', random_bytes(128));  
  
function is_user_admin(){  
    if (isset($_GET['data'])){  
        return (hash_hmac('sha256', $_GET['data'], SECRET) === $_GET['hash']);  
    }  
}  
  
if (is_user_admin()){  
    var_dump(1);  
    echo sha1_file($_GET['file']);  
}  
?>  
  
</body>  
</html>

Em uma linguagem de alto nível, a aplicação primeiro checa se o parâmetro data, passado através de uma requisição GET é igual a criptografia gerada do valor SECRET, que é gerada aleatoriamente a cada vez que a aplicação é chamada. Assim, para conseguirmos obter a flag, primeiramente temos que realizar um bypass na função is_user_admin().

Analisando a função mais a fundo, podemos observar que o parâmetro data é passado de forma livre ao parâmetro da função hash_hmac, que está esperando um valor do tipo string. Portanto, se forçarmos uma requisição do tipo ?data[]=foo, podemos fazer com que hash_hmac nos retorne FALSE. Assim, continuando o nosso procedimento, as funções $_GET[] do PHP, caso não recebam nenhum valor, são consideradas também como FALSE. Finalizando, podemos conseguir realizar um bypass na função is_user_admin ao forçar ela comparar FALSE === FALSE, o que nos retorna um TRUE.

Dito isso, passando o parâmetro ?file=/flag.txt na requisição, podemos obter o hash da flag. Entretanto, isso não nos importa muito, pois precisamos de uma maneira de conseguir o valor dela.

center

Após uma investigação profunda, de acordo com o artigo PHP FILTER CHAINS: FILE READ FROM ERROR-BASED ORACLE, escrito por Rémi Matasse em 21/03/2023, a função sha1_file (junta com 14 outras funções do PHP) está sujeita a ataques com PHP Wrappers. Utilizando o PHP filter chains: file read from error-based oracle e adaptando algumas de suas variáveis para se adaptar ao nosso caso, podemos obter a flag em questão.