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.
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.