Introduction
This blog post contains the writeup for the natas wargame levels 21 to 25. If you haven’t already, I recommend reading the previous articles on the introduction and the writeups on Levels 0-10 and Levels 11-20.
Level 21
URL: http://natas21.natas.labs.overthewire.org
Credentials: natas21:89OWrTkGmiLZLv12JY4tLj2c4FW0xn56
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<html>
<body>
<h1>natas21</h1>
<div id="content">
<p>
<b>Note: this website is colocated with <a href="http://natas21-experimenter.natas.labs.overthewire.org">http://natas21-experimenter.natas.labs.overthewire.org</a></b>
</p>
<?php
function print_credentials() {
if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) {
print "You are an admin. The credentials for the next level are:<br>";
print "<pre>Username: natas22\n";
print "Password: <censored></pre>";
} else {
print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas22.";
}
}
session_start();
print_credentials();
?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Solution
Level 21 had two pages that were colocated - this meant they would share the same cookie data. By intercepting the second vulnerable proxy with Burp suite, I came across the form where it would take in data. After adding the string ‘&admin=1’ to the end of the form, I forwarded the request, saved the cookie and replaced the cookie on the original page with the saved cookie containing the ‘admin=1’. This returned the password and I moved on.
Fix
The solution for this would be to ensure that both webpages colocated with each other have tightened security to prevent the exploit of a vulnerability in one site leading to the other site also being exposed to attacks.
Click Me to see the Password!
91awVM9oDiUGm33JdzM7RVLBS8bz9n0sLevel 22
URL: http://natas22.natas.labs.overthewire.org
Credentials: natas22:91awVM9oDiUGm33JdzM7RVLBS8bz9n0s
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
session_start();
if(array_key_exists("revelio", $_GET)) {
// only admins can reveal the password
if(!($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1)) {
header("Location: /");
}
}
?>
<html>
<body>
<h1>natas22</h1>
<div id="content">
<?php
if(array_key_exists("revelio", $_GET)) {
print "You are an admin. The credentials for the next level are:<br>";
print "<pre>Username: natas23\n";
print "Password: <censored></pre>";
}
?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Solution
Level 22 was a blank page and only had a hyperlink showing the source code. Upon looking at the code, I found the the header of the page had to contain the string ‘revelio’ in order to return the password. Following this, I opened BurpSuite and changed the URL to ‘http://natas22.natas.labs.overthewire.org/?revelio’ which returned the password.
Fix
The fix for this vulnerability would be to deny all access to the sensitive file from the .httaccess file. This would prevent the attacker from directly viewing the sensitive information.
Password: qjA8cOoKFTzJhtV0Fzvt92fgvxVnVRBj
Level 23
URL: http://natas23.natas.labs.overthewire.org
Credentials: natas23:qjA8cOoKFTzJhtV0Fzvt92fgvxVnVRBj
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html>
<head>
<body>
<h1>natas23</h1>
<div id="content">
Password:
<form name="input" method="get">
<input type="text" name="passwd" size=20>
<input type="submit" value="Login">
</form>
<?php
if(array_key_exists("passwd",$_REQUEST)){
if(strstr($_REQUEST["passwd"],"iloveyou") && ($_REQUEST["passwd"] > 10 )){
echo "<br>The credentials for the next level are:<br>";
echo "<pre>Username: natas24 Password: <censored></pre>";
}
else{
echo "<br>Wrong!<br>";
}
}
?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Solution
Level 23 consisted of a password box and a submit button. Upon looking at the code, I found that the password, or var passwd, had to contain ‘iloveyou’ and have a numerical value greater than 20. Following this, I entered the string ‘iloveyou100’ as the password which returned false. Changing it to ‘100iloveyou’, I was given the password. Turns out that this was because the wargame ran on php 7, therefore it took in the first numerical value and ignored the second.
Fix
The fix for this would be to have a much more secure password that is hidden elsewhere so that the attacker cannot easily identify under what conditions a password is correct.
Password: 0xzF30T9Av8lgXhW7slhFCIsVKAPyl2r
Level 24
URL: http://natas24.natas.labs.overthewire.org
Credentials: natas24:0xzF30T9Av8lgXhW7slhFCIsVKAPyl2r
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html>
<head>
<body>
<h1>natas24</h1>
<div id="content">
Password:
<form name="input" method="get">
<input type="text" name="passwd" size=20>
<input type="submit" value="Login">
</form>
<?php
if(array_key_exists("passwd",$_REQUEST)){
if(!strcmp($_REQUEST["passwd"],"<censored>")){
echo "<br>The credentials for the next level are:<br>";
echo "<pre>Username: natas25 Password: <censored></pre>";
}
else{
echo "<br>Wrong!<br>";
}
}
?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Solution
Level 24 also looked extremely simple. It had one condition where the password and the censored value had to be identical for next level’s credentials to be returned, this was done using the strcmp or string compare function. Upon returning true, the strcmp() would give a value of 0, and the ‘!’ Inverted it to a 1 (as it returns a true if the previous condition ie ‘not false’). This meant that in boolean, it would return a true so the program returned the password. Knowing this, I entered passwd[]= , resulting in an array being compared to the string, returning a null, which was represented as 0 so it returned the password.
Fix
The solution for this would be to update php to the latest version, as the latest version no longer returns a null value, it only has an error. Alternatively, the function ’strncmp’ may be used which is not subject to this vulnerability, providing a quick fix.
Password: O9QD9DZBDq1YpswiTM5oqMDaOtuZtAcx
Level 25
URL: http://natas25.natas.labs.overthewire.org
Credentials: natas25:O9QD9DZBDq1YpswiTM5oqMDaOtuZtAcx
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<html>
<head>
<body>
<?php
function setLanguage(){
if(array_key_exists("lang",$_REQUEST))
if(safeinclude("language/" . $_REQUEST["lang"] ))
return 1;
safeinclude("language/en");
}
function safeinclude($filename){
// check for directory traversal
if(strstr($filename,"../")){
logRequest("Directory traversal attempt! fixing request.");
$filename=str_replace("../","",$filename);
}
// dont let ppl steal our passwords
if(strstr($filename,"natas_webpass")){
logRequest("Illegal file access detected! Aborting!");
exit(-1);
}
// add more checks...
if (file_exists($filename)) {
include($filename);
return 1;
}
return 0;
}
function listFiles($path){
$listoffiles=array();
if ($handle = opendir($path))
while (false !== ($file = readdir($handle)))
if ($file != "." && $file != "..")
$listoffiles[]=$file;
closedir($handle);
return $listoffiles;
}
function logRequest($message){
$log="[". date("d.m.Y H::i:s",time()) ."]";
$log=$log . " " . $_SERVER['HTTP_USER_AGENT'];
$log=$log . " \"" . $message ."\"\n";
$fd=fopen("/var/www/natas/natas25/logs/natas25_" . session_id() .".log","a");
fwrite($fd,$log);
fclose($fd);
}
?>
<h1>natas25</h1>
<div id="content">
<div align="right">
<form>
<select name='lang' onchange='this.form.submit()'>
<option>language</option>
<?php foreach(listFiles("language/") as $f) echo "<option>$f</option>"; ?>
</select>
</form>
</div>
<?php
session_start();
setLanguage();
echo "<h2>$__GREETING</h2>";
echo "<p align=\"justify\">$__MSG";
echo "<div align=\"right\"><h6>$__FOOTER</h6><div>";
?>
<p>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Solution
Level 25 consisted of a quote and a dropdown menu. The source code hinted towards the usage of a directory traversal attack to retrieve information. The program had a filter that removed ‘../‘ from a string, however since this wasn’t recursive and failed to account for url encoded bypasses, it was easy to bypass and I was able to retrieve the session logs by adding /?lang=….//….//logs/natas25[cookie].log. {Note: the program saved the logs as natas25[cookie].log in /var/www/natas/natas25/logs/}. After inspecting the response in burp, I noticed that the log would print anything in the user-agent header, therefore I decided to manipulate it to run php code which would return the contents of /etc/natas_webpass/natas26 to retrieve the password. This was done with the file_get_contents function, which returned the contents of the file. With (replace %3F with ?), I was able to find the password to level 25.
Fix
The solution to directory traversal would be to account for all url encoding methods and have a recursive loop that removes all of the illegal content within the url request until it is clean, which prevents directory traversal. Additionally, the developer may completely disable user input to the filesystem API which would completely prevent all vulnerabilities.
Password: 8A506rfIAXbKKk68yJeuTuRq4UfcK70k
Comments powered by Disqus.