You MUST sanitize PHP mail() inputs — or else RCE!

A walkthrough of Letter Dispair (Hack the Box Web Challenge)

Roberto
InfoSec Write-ups

--

AI-generated image of “thief mail illustration” at craiyon.com

mail() function

In this write up, I will be detailing my thought process and solution to the new Hack the Box (HTB) web challenge: Letter Dispair.

The vulnerability that this challenge exposes is the PHP mail() function and how it can be used to gain Remote Code Execution (RCE) privileges. For a more detailed explanation of this particular vulnerability, this linked white-paper is extremely thorough (and where I got my information on how to build the exploit).

Essentially, in the mail(), by adding the additional parameters,

-OQueueDirectory=/tmp/ -X/var/html/poc.php

you can control where temporary outputs are stored. These temporary outputs can contain unfiltered or other non-sanitized inputs such as

<?php system($_GET["CMD"]) ?>

where you can set the ?cmd= query to be whatever you’d like, resulting in RCE. The full white-paper sheds much more light into the intricacies of this exploit.

Letter Dispair: How to Get Started

Go to https://app.hackthebox.com/challenges . Under “Active Challenges,” click on “Web”. Look for “Letter Dispair” and then start the instance (if you don’t see it, it might be under “Retired Challenges” at the time of reading). When you start the instance, you should be able to see a host:port (i.e something like 157.245.46.136:30055). Copy the host into a new browser tab/window. Good to go!

Starting the challenge

Reconnaissance

Looking at the web page, if you click on mailer.php , you get taken to the following page, and you can download this by clicking on mailer.zip.

mailer.php

This is where we can input elements for our exploit.

Downloaded mailer.php file

Looking at the downloaded source code, we see that a function called send is used on the submit button. This send function eventually calls the previously discussed PHP mail() function. We can see that the additional parameter, which is the 5th argument, is passed in as “-f$from_addr” , where $from_addr is not sanitized.

The Exploit

Now, knowing that the argument is not sanitized, we can use the additional options to create an output log that has a PHP injection. This PHP injection will allow us to perform RCE since we control it. In the mailer website, we can type in the following:

Exploit

This will create a file called exploit.php that will contain the PHP code injection of <?php system($_GET[“cmd”]) ?> once we submit the delivery. Then, we will be able to retrieve this file by going to IP:PORT/exploit.php .

The created output file

Then, by adding ?cmd=ls / , the PHP code we injected grabs the parameter of the GET request, allowing us to see that our flag is located in the file /flag.txt . Note: %20 is the URL encoding for space.

“ls” of the root directory /

Now, by changing the our GET param to be ?cmd=cat /flag.txt , we can output the value of the flag! Woohoo!

Thanks for reading through and please leave any constructive feedback, suggestions, or questions below! If you enjoyed, please consider following me on Medium. Contact me at roberto.cyberkid@gmail.com, follow me on twitter, and connect with me on LinkedIn!

From Infosec Writeups: A lot is coming up in the Infosec every day that it’s hard to keep up with. Join our weekly newsletter to get all the latest Infosec trends in the form of 5 articles, 4 Threads, 3 videos, 2 Github Repos and tools, and 1 job alert for FREE! https://weekly.infosecwriteups.com/

--

--

Stanford alum, Software Engineer with a passion for CyberSec, Biotech, and Sustainability. Work with me at https://www.tidallabs.io/.