Home OverTheWire: NATAS 0 – 10

OverTheWire: NATAS 0 – 10


The password for the next level is embedded in the HTML source code as a comment.

<!–The password for natas1 is gtVrDuiDfck831PqWsLEZy5gyDz1clto –>



You can find the password for the next level on this page, but rightclicking has been blocked!

Press “ALT” button to get to the menu if it isn’t visible, then go to “Tools -> Web Developer Menu” and view the Page Source.

<!–The password for natas2 is ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi –>



There is nothing on this page

Looking into the page source, you can see an image “files/pixel.png”.

If you browse to the “files” directory, it is open for viewing and there’s another file called “users.txt” where you’ll find the next password.

# username:password



There is nothing on this page

Looking in the page source, you’ll see <!– No more information leaks!! Not even Google will find it this time… –> . That makes me think they’re trying to block Google’s web crawler’s from picking up something. It’s a well known flaw to have secret things listed in the “robots.txt” file that web crawlers look for, so take a look there.


User-agent: *
Disallow: /s3cr3t/

In the “s3cr3t” directory, there’s a “users.txt” file with the next credentials.




Access disallowed. You are visiting from “” while authorized users should come only from “http://natas5.natas.labs.overthewire.org/”

This makes me think it’s checking the referrer to see what page we’re coming from.

To edit HTTP headers and other changes, I like to use Burp Suite, which is purpose built for testing websites.

Using Burp, view the headers on the request and see what the referrer is. Mine didn’t have a referrer, so that explains the blank quotes on the page.

I added a referrer like so:

GET / HTTP/1.1
Host: natas4.natas.labs.overthewire.org
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: __cfduid=d36afe6edde0ea62a428daa5ba6f1cc781568143940
Authorization: Basic bmF0YXM0Olo5dGtSa1dtcHQ5UXI3WHJSNWpXUmtnT1U5MDFzd0Va
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Referer: http://natas4.natas.labs.overthewire.org

and it showed up on the page as:

Access disallowed. You are visiting from “http://natas4.natas.labs.overthewire.org” while authorized users should come only from “http://natas5.natas.labs.overthewire.org/”

So I changed the referrer address to http://natas5.natas.labs.overthewire.org/ and it worked!

Access granted. The password for natas5 is iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq



Access disallowed. You are not logged in

The page source on this one shows nothing. However, the response HTTP headers do show something interesting:

HTTP/1.1 200 OK
Date: Tue, 10 Sep 2019 20:18:26 GMT
Server: Apache/2.4.10 (Debian)
Set-Cookie: loggedin=0
Vary: Accept-Encoding
Content-Length: 855
Connection: close
Content-Type: text/html; charset=UTF-8

It sets a cookie “loggedin” to “0”. If we change that cookie value to “1” it will probably trick the site into thinking we are logged in and can access the content.

I used the Web Developer Tools in the browser to change the cookie and then refreshed the page to get the next password.

Access granted. The password for natas6 is aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1



When viewing the sourcecode using the link provided, you’ll notice some PHP code:

include "includes/secret.inc";

    if(array_key_exists("submit", $_POST)) {
        if($secret == $_POST['secret']) {
        print "Access granted. The password for natas7 is &lt;censored&gt;";
    } else {
        print "Wrong secret";

The PHP code is looking at an included file called “secret.inc” and checking it against what we’re entering in the input form. Browsing to the included file at “/includes/secret.inc” gives us the secret.


When you put that secret string into the Input box, it gives you the password for the next level.

Access granted. The password for natas7 is 7z3hEENjQtflzgnT29q7wAvMNfZdh0i9



This level gives us two pages we can browse to, “Home” and “About”. They’re equally boring and probably not worth clicking on. What is worth investigating is the page source however. There you’ll see:

<!– hint: password for webuser natas8 is in /etc/natas_webpass/natas8 –>

That suggests to solve this level, we will need to pull a file from the server. Local File Include vulnerability maybe? In the page source, the links to “Home” and “About” show a PHP script is being called to serve them, by passing “page=” to “index.php”. Putting in the path to the webpass file into the “page” variable will probably give us the password.

Sure enough, it does!



This is another secret sauce input box. Glad they have that sourcecode button or these might really be hard.

There is PHP code in the source on this one as well:


$encodedSecret = "3d3d516343746d4d6d6c315669563362";

function encodeSecret($secret) {
    return bin2hex(strrev(base64_encode($secret)));

if(array_key_exists("submit", $_POST)) {
    if(encodeSecret($_POST['secret']) == $encodedSecret) {
    print "Access granted. The password for natas9 is &lt;censored&gt;";
    } else {
    print "Wrong secret";

Notice this part:

return bin2hex(strrev(base64_encode($secret)));

It is taking the secret string, base64 encoding it, then reversing the letters, then hex encoding the characters. So to get the original string, we only have to do the exact opposite!

To decode the Secret from hex back to ASCII, use the “XXD” command like so:

echo -n "3d3d516343746d4d6d6c315669563362" | xxd -r -ps

The “rev” command will reverse the string.

And lastly, the “base64” command will decode it to it’s original form. Putting all of this together looks like this:

echo -n “3d3d516343746d4d6d6c315669563362” | xxd -r -ps | rev | base64 -d

Take the result and submit it in the form to get the next password!



The PHP code in this page is:

$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];

if($key != "") {
    passthru("grep -i $key dictionary.txt");

So this code is taking our input variable “needle” and passing it’s value to “grep”, which looks up the value in a dictionary file, then returns the result.

We can exploit an injection here, with command substitution. Using a “$()” string will execute whatever is inside the parentheses. Since the rules of the NATAS say that all passwords are stored in “/etc/natas_webpass/”, we can use the injection to read out the file we need.

If we read out the file by using “cat”, like ?needle=$(cat /etc/natas_webpass/natas10) it won’t return anything since that isn’t in the dictionary file. We could make a script that looks up each character in the password with an “if” statement, showing dictionary results only when we get a match, one character at a time. Pretty sure that’s the way this level was intended to be solved…

But there is a better way. What if I told you we could use the bash command substitution to forcefully inject the password into the PHP script’s output? I tried a bunch of things, and eventually found that we can inject straight into the output file descriptor for the PHP script. We have to get the Process ID of the PHP script, and bash makes it easy for us by designating a variable for the current PID, “$$”.

So the command become something like cat /etc/natas_webpass/natas10 1> /proc/$$/fd/1 where “1>” is redirecting output and “/proc/\(/fd/1&#8221; is the output file descriptor for the current process. To send it to the PHP script, type this into the address bar: `?needle=$(cat+/etc/natas_webpass/natas10+1>+/proc/\)/fd/1)`

This is the coolest solution I came up with for the whole NATAS site!



Oh great, a character filter! Looking into the sourcecode we can see which characters are bad:

$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];

if($key != "") {
    if(preg_match('/[;|&]/',$key)) {
        print "Input contains an illegal character!";
    } else {
        passthru("grep -i $key dictionary.txt");

The characters “; | &” can’t be used now. No problem, our last solution doesn’t use any of those! Lol, just send the same request as the last level, modified to get the correct password file of course.

Boom! Gotcha.

This post is licensed under CC BY 4.0 by the author.