Natas9-->Natas11

Introduction

We're continuing our series of the Natas challenges. In the previous post, we dove into the prior 3 challenges which were focusing on the server-side programming language of PHP. Next up are two challenges that will be focused around PHP as well, but give some exposure to the concept of command injection.

Natas9--> Natas10

Website: http://natas9.natas.labs.overthewire.org/ ; Access Credentials: natas9:Sda6t0vkOPkM8YeOZkAGVhFoaplvlJFd

The website provides a text box and search button. Clicking the View sourcecode link shows some PHP code. The code comments are my own:

<?
$key = "";

# if the parameter "needle" is provided, sets its contents to the variable key
if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

# if key is not null, then run the grep command
if($key != "") {
    passthru("grep -i $key dictionary.txt");
}
?>
</pre>

The code checks to see if the form needle was submitted, and sets the value of the text provided for the needle URL parameter to the PHP variable $key. If the value is not null, it passes the $key variable into the grep command which is looking for the value inside a text file named dictionary.txt.

Just for a bit of diversity through the challenges, lets say you wanted to change up your research method. Rather than finding the PHP documentation via a google search, you ask ChatGPT, or any AI Chatbot of your preference (this will be helpful tool to leverage for more complex challenges). See the response below, I've highlighted an important takeaway in red.

That highlighted sentence is probably on the Mount Rushmore of "Sentences to be Read by a Web App Pentester"

So passthru can takes the grep command and runs it on the server's OS. For those unfamiliar, a quick bit of research would bring up the vulnerability of command injection. Remember from the introduction, that the passwords are stored in the directory /etc/natas_webpass/. After some initial testing, the grep command can be escaped with prepending and appending semicolons (;) to the command.

This is because, for example, by passing in ; id;, the full command is: grep -i ; id ; dictionary.txt. The OS, will try to execute each of those commands separately, but only return the output from STDOUT. The grep and dictonary.txt commands will error out, but the id command (or any valid command in between the semicolons - will execute and output to the webpage. See the Appendix below for more info.

We know since we are the natas9 user, we are looking for the password to natas10, coupled with the directory, we know the absolute path of the file to target is: /etc/natas_webpass/natas10. Pass in the string, ; cat /etc/natas_webpass/natas10; into the web page and click submit, and the password will return: D44EcsFkLxPIkAAKLosx8z3hxX1Z4MCE.

Natas10-->Natas11

Website: ; Access Credentials: natas10:D44EcsFkLxPIkAAKLosx8z3hxX1Z4MCE

The Natas10 web page looks identical to the Natas9 web page. However, if we attempt to run the same command as earlier, such as ; id;, an error of Input contains an illegal character! returns. By clicking View sourcecode, we find the following code:

<?
$key = "";

# same if statement as prior, setting needle URL paramter to the variable key
if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}
# if key is not null
if($key != "") {
    # new if statement checking if there are specific chars in string
    if(preg_match('/[;|&]/',$key)) {
        # if true, output an error message
        print "Input contains an illegal character!";
    } else {
        # otherwise, run the grep command
        passthru("grep -i $key dictionary.txt");
    }
}
?>

There is input validation occurring, specifically making sure the string input by the client doesn't include a semicolon, pipe, or ampersand (the three values between the square brackets). If any of those characters are identified in the string value of $key, the preg_match() function returns a 1, rendering the first condition of the if statement TRUE, and prevents the passthru command from running.

Command injection becomes slightly more challenging, but still doable! We could use a reference like GTFOBins, to see grep can be abused to read an entire file. From the introduction, we remember that the directory of all the passwords are stored in /etc/natas_webpass/. Therefore we enter '' /etc/natas_webpass/natas11 into the textbox and click Search. The password returns - 1KFqoJXi6hRaPluAmk8ESDW4fSysRoIg!

Appendix

Here's a deeper dive into how passthru works, specifically with the inner workings of the command running on Linux once it is passed to the OS. This should help you understand why only the command in between the semicolons ran.

If we remember, the passthru command is: grep -i $key dictionary.txt. We are setting the value of $key to 2>&1;id;echo, which makes the full command: grep -i 2>&1;id;echo dictionary.txt. The server run these 3 commands, and returns the output as follows:

  • grep -i 2>&1 - this is running grep -i which is an incomplete command, as it has not provided a PATTERN value, nor a FILE to look for. The 2>&1 redirects standard error to standard out. The Usage: grep [OPTION]... value that returns on the page is technically STDERR output, and passthru only returns STDOUT.
  • id - runs the id command
  • echo dictionary.txt - literally repeating the string "dictionary.txt to STDOUT.