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:
- Queue up both of the original requests from
natas21-experimenter
andnatas21
. - Send each to the Repeater.
- Modify the
natas21-experimenter
one (as shown above) to include&admin=1
in thePOST
data. - Send that request.
- 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).