OverTheWire Natas Level 21 Walkthrough

Level 21 of Natas is covered in this blog post, including source code analysis and using Burp Suite to get the flag. This is a continuation of several levels that point out various flaws in PHP session management.

What is Natas?

Natas is an online hacking game meant to help you learn and practice security concepts.

OverTheWire is a website with a number of “war games”, which are online hacking games that allow you to practice security concepts. If you are looking for a beginner introduction to web security (albeit an older tech stack), then Natas is a great place to start.

Natas is hosted on different subdomains following the pattern of http://natas<level#>.natas.labs.overthewire.org. As you progress through the levels, you’ll need to increment the level number in the URL in order to view the correct level.

Each level requires the levels below it to be solved, so you will need the level 21 flag found in level 20 to begin this walkthrough. As before, make sure you keep notes and write down the passwords as you find them!

Level 21 ➔ 22

If we visit http://natas21.natas.labs.overthewire.org/ with previously-found credentials natas21 and IFekPyrQXftziDEsUr3x21sYuahypdgJ, we see:

The source code for this website is pretty lacking, and mainly informs us that we are trying to get a $_SESSION key/value pair of “admin=1” in order to view the flag.

The page tells us that the website is co-located with another website at http://natas21-experimenter.natas.labs.overthewire.org. If we navigate there, we see a form that lets us inject different CSS values and display a simple Hello World! styled div:

We’re provided source code for this website, too.

It has a concept of “valid keys”, which include align, fontsize, and bgcolor, all CSS properties.

Rendering the form

The form reads each of the valid keys and creates a form input for them with either the default value, or the value taken out of the $_SESSION variable.

Then it concatenates all of the CSS styles into a $style variable and adds that into a HTML div:

$style = "background-color: ".$_SESSION["bgcolor"]."; text-align: ".$_SESSION["align"]."; font-size: ".$_SESSION["fontsize"].";";

This means that the app is vulnerable to cross site scripting (XSS), although XSS didn’t end up being useful for solving this level.

Reading in requests

The last part of the source code is the most interesting part for us:

This is the logic that handles a POST request with data to update the variables. Before, the form creation only read valid keys. Here, there is no such restriction, which means we can append our own keys and have them read into the $_SESSION variable.

There’s one issue though. These are two separate websites, so how will a $_SESSION variable on one website affect the other website?

Our hint is that the two sites are co-located. PHP session information is stored in files on the server, and if the web apps both process session data in a similar way, we might be able to inject the admin=1 data into the $_SESSION variable on one site, then immediately request a page from the other site using the same PHPSESSID, since the session data for both websites have to be on the same server.

Natas Level 21 Solution

To solve this level, set up Burp Suite to proxy traffic from your web browser.

Then, click “Update” on the form at http://natas21-experimenter.natas.labs.overthewire.org/index.php. You should see a POST request in your Burp Suite history (Proxy > HTTP History).

Right click the request and select Send to Repeater:

From here, you can add &admin=1 near the end of the POST data. The reasoning behind this is the source code we saw earlier that indiscriminately reads key/value pairs into the $_SESSION variable.

Add ?debug on the end of /index.php:

Click “Go” and then look at the response. You’ll see that admin=>1 was read into the $_SESSION variable.

Now, we need to make a GET request to http://natas21.natas.labs.overthewire.org/index.php?debug using the same PHPSESSID. You can either modify the existing request (changing POST to GET, changing the host, removing the referer and origin, POST data, etc.) or you can make a new request in your browser, and send that to the Repeater.

For whatever reason, I had timeouts using the first method (maybe a copy/paste error), so instead, I went this route:

  1. Queue up both of the original requests from natas21-experimenter and natas21.
  2. Send each to the Repeater.
  3. Modify the natas21-experimenter one (as shown above) to include &admin=1 in the POST data.
  4. Send that request.
  5. Immediately copy the PHPSESSID over to the second request, and send that.

6.  Get the flag 🙂

Takeaway: test out cross-subdomain session cookies (and if you’re a dev, pay extra attention to managing this correctly).