# 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`: ```php
``` 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 ``` 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 ``` ## 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!