samedi 22 mars 2014

CTF Writeup: Insomni'hack 2014: encoding

On fait face à un serveur web, disons http://insomni.hack/. Sur la page d'accueil, on trouve un lien vers la "Page d'administration", http://insomni.hack/control.php/admin, qui nous gratifie d'un beau "Please authenticate.".

On tape dans le robots.txt, on y découvre:

User-Agent: *
Disallow: /backup
Disallow: /

Aha. Le répertoire backup nous offre un listing, on y découvre le fichier suivant, qu'on sauvegarde dans encoded.php:
gzuncompress(str_rot13(base64_decode('a5yVkVhCwzAMgM/1rzDVDq00sQc7rYxdKBIXBt3jgtCUtd5NEZIqWoQQ6n8n3bRUVCfEMY4/+7N9O87THKCVsw3hCAuzKrTyTct2GC3C6NWNwpdsOJ0t59Gj+9butns3fgAtlnxx4myH/MXgDiGlpLLpwmMeAEC2U8+zXCY2/na90Qjd7dP1v8E5YL0AVyReQ43bTV9MohNYoZXk12maQZ3s71a00Qtdeol91CieQywT8o7/fkjQqVrdmBaAZnlIM2NXKGoz/7PrqWNw0vnGHIpGia5BCdecejArYza5n7iVw1K135t6vgienwSg+MxnnNq5tuHKIHO2i9fzhweZL3ZDECWoJTJw1YTOb6apkmVJith7sMf6J9igO8AnqfFOGpHUZRNNM8P18Bgqbnz3A8Wt1kk=')));
On utilise php pour évaluer cette expression facilement:
$ php -r 'echo(gzuncompress(str_rot13(base64_decode('a5yVkVhCwzAMgM/1rzDVDq00sQc7rYxdKBIXBt3jgtCUtd5NEZIqWoQQ6n8n3bRUVCfEMY4/+7N9O87THKCVsw3hCAuzKrTyTct2GC3C6NWNwpdsOJ0t59Gj+9butns3fgAtlnxx4myH/MXgDiGlpLLpwmMeAEC2U8+zXCY2/na90Qjd7dP1v8E5YL0AVyReQ43bTV9MohNYoZXk12maQZ3s71a00Qtdeol91CieQywT8o7/fkjQqVrdmBaAZnlIM2NXKGoz/7PrqWNw0vnGHIpGia5BCdecejArYza5n7iVw1K135t6vgienwSg+MxnnNq5tuHKIHO2i9fzhweZL3ZDECWoJTJw1YTOb6apkmVJith7sMf6J9igO8AnqfFOGpHUZRNNM8P18Bgqbnz3A8Wt1kk='))));'

$page = substr($_SERVER["REQUEST_URI"],0,13);
$adminPage =  substr($_SERVER["REQUEST_URI"], 13);
$error = null;


if ((string)$adminPage === "admin"){
        $error = 1;
} elseif ((string)$page != "/control.php/"){
        $error = 2;
} else {
        if ((string)$adminPage != (string)urldecode($adminPage)){
                $adminPage = urldecode($adminPage);
        } else {
                $error = 2;
        }
}

if ($adminPage != (string)urldecode($adminPage)){
        if ((string)urldecode($adminPage) === "admin"){
                echo "the flag is TODO";
        }else {
                $error = 2;
        }
} elseif ((string)$adminPage === "admin") {
        $error = 1;
}

switch ($error){
        case (1):
                echo "you need to authenticate";
                break;
        case (2):
                echo "404 Not Found";
                break;
        default:
                break;
}


Pour déclencher la branche de code qui révèle le flag, les conditions suivants doivent être remplies:
(string)adminPage === "admin" => FALSE
(string)adminPage != (string)urldecode(adminPage)  => TRUE

adminPage = urldecode(adminPage);

$adminPage != (string)urldecode($adminPage)) => TRUE
(string)urldecode($adminPage) === "admin" => TRUE
Par la première condition, on doit donc remplacer le chemin d'accès, "admin", par autre chose. La deuxième condition impose que la nouvelle chaine contienne au moins une séquence d'échappement interprétée par urldecode.
Après décodage, la 3e condition impose que la chaine contienne encore une fois une séquence d'échappement, et que cette séquence, une fois décodée une deuxième fois, soit égale à "admin".
On choisit donc un caractère au hasard, ici le "i". La séquence après le premier décodage sera donc "adm%69n". On passe ensuite cette chaine dans urlencode une deuxième fois, pour obtenir "adm%3069n".
Il suffit donc de visiter http://insomni.hack/control.php/adm%3069n, et hop !

Aucun commentaire: