NATAS20:
Link do zalogowania: http://natas20.natas.labs.overthewire.org/index.php
Login: natas20, password: eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF

Poniżej kod strony:
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas20", "pass": "<censored>" };</script></head>
<body>
<h1>natas20</h1>
<div id="content">
<?
function debug($msg) { /* {{{ */
if(array_key_exists("debug", $_GET)) {
print "DEBUG: $msg<br>";
}
}
/* }}} */
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: natas21\n";
print "Password: <censored></pre>";
} else {
print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas21.";
}
}
/* }}} */
/* we don't need this */
function myopen($path, $name) {
//debug("MYOPEN $path $name");
return true;
}
/* we don't need this */
function myclose() {
//debug("MYCLOSE");
return true;
}
function myread($sid) {
debug("MYREAD $sid");
if(strspn($sid, "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-") != strlen($sid)) {
debug("Invalid SID");
return "";
}
$filename = session_save_path() . "/" . "mysess_" . $sid;
if(!file_exists($filename)) {
debug("Session file doesn't exist");
return "";
}
debug("Reading from ". $filename);
$data = file_get_contents($filename);
$_SESSION = array();
foreach(explode("\n", $data) as $line) {
debug("Read [$line]");
$parts = explode(" ", $line, 2);
if($parts[0] != "") $_SESSION[$parts[0]] = $parts[1];
}
return session_encode();
}
function mywrite($sid, $data) {
// $data contains the serialized version of $_SESSION
// but our encoding is better
debug("MYWRITE $sid $data");
// make sure the sid is alnum only!!
if(strspn($sid, "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-") != strlen($sid)) {
debug("Invalid SID");
return;
}
$filename = session_save_path() . "/" . "mysess_" . $sid;
$data = "";
debug("Saving in ". $filename);
ksort($_SESSION);
foreach($_SESSION as $key => $value) {
debug("$key => $value");
$data .= "$key $value\n";
}
file_put_contents($filename, $data);
chmod($filename, 0600);
}
/* we don't need this */
function mydestroy($sid) {
//debug("MYDESTROY $sid");
return true;
}
/* we don't need this */
function mygarbage($t) {
//debug("MYGARBAGE $t");
return true;
}
session_set_save_handler(
"myopen",
"myclose",
"myread",
"mywrite",
"mydestroy",
"mygarbage");
session_start();
if(array_key_exists("name", $_REQUEST)) {
$_SESSION["name"] = $_REQUEST["name"];
debug("Name set to " . $_REQUEST["name"]);
}
print_credentials();
$name = "";
if(array_key_exists("name", $_SESSION)) {
$name = $_SESSION["name"];
}
?>
<form action="index.php" method="POST">
Your name: <input name="name" value="<?=$name?>"><br>
<input type="submit" value="Change name" />
</form>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Analiza kodu źródłowego pokazuje, że możemy wykorzystać funkcję debug,
http://natas20.natas.labs.overthewire.org/index.php?debug

Następnie sprawdzamy dalej kod źródłowy, poniżej warunek aby hasło do kolejnego poziomu zostało wyświetlone.
if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1)
oraz
foreach($_SESSION as $key => $value) {
debug("$key => $value");
$data .= "$key $value\n";
}
Potrzebne są zatem dwie zmienne zapisane w danych sesji. Potrzebne jest ustawienie zmiennej name na admin oraz admin na 1. Dodatkowo w kodzie strony jest dodany znak nowego wiersza po pierwszy parametrze. Wklejam zatem poniższy ciąg do paska URL:
http://natas20.natas.labs.overthewire.org/index.php?debug&name=admin%0Aadmin%201
Pierwszy ciąg cyfr po znaku % to znak nowego wiersza, drugi ciąg to spacja. U mnie musiałem wkleić powyższy ciąg dwa razy i dostałem rozwiązanie.

Hasło do kolejnego poziomu to IFekPyrQXftziDEsUr3x21sYuahypdgJ
NATAS21:
Link do zalogowania: http://natas21.natas.labs.overthewire.org/index.php
Login: natas21, password: IFekPyrQXftziDEsUr3x21sYuahypdgJ

Strona składa się z dwóch elementów, cześć 1:
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas21", "pass": "<censored>" };</script></head>
<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>
<?
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>
Część 2:

<html>
<head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head>
<body>
<h1>natas21 - CSS style experimenter</h1>
<div id="content">
<p>
<b>Note: this website is colocated with <a href="http://natas21.natas.labs.overthewire.org">http://natas21.natas.labs.overthewire.org</a></b>
</p>
<?
session_start();
// if update was submitted, store it
if(array_key_exists("submit", $_REQUEST)) {
foreach($_REQUEST as $key => $val) {
$_SESSION[$key] = $val;
}
}
if(array_key_exists("debug", $_GET)) {
print "[DEBUG] Session contents:<br>";
print_r($_SESSION);
}
// only allow these keys
$validkeys = array("align" => "center", "fontsize" => "100%", "bgcolor" => "yellow");
$form = "";
$form .= '<form action="index.php" method="POST">';
foreach($validkeys as $key => $defval) {
$val = $defval;
if(array_key_exists($key, $_SESSION)) {
$val = $_SESSION[$key];
} else {
$_SESSION[$key] = $val;
}
$form .= "$key: <input name='$key' value='$val' /><br>";
}
$form .= '<input type="submit" name="submit" value="Update" />';
$form .= '</form>';
$style = "background-color: ".$_SESSION["bgcolor"]."; text-align: ".$_SESSION["align"]."; font-size: ".$_SESSION["fontsize"].";";
$example = "<div style='$style'>Hello world!</div>";
?>
<p>Example:</p>
<?=$example?>
<p>Change example values here:</p>
<?=$form?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Z kodu źródłowego pierwszego skryptu można zauważyć interesujący zapis, który jest odpowiedzialny za podanie hasła :
if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1)
Następnie możemy zauważyć wrażliwy kod:
if(array_key_exists("submit", $_REQUEST)) {
foreach($_REQUEST as $key => $val) {
$_SESSION[$key] = $val;
}
}
Powyższy kod pozwala na pobieranie danych ze zmiennej sesji, zatem możemy wstrzykiwać dowolne dane poprzez parametr GET w zapytaniu do strony. Jeżeli w stronie z listingu nr 2 wykonam zapytanie:
http://natas21-experimenter.natas.labs.overthewire.org/index.php?submit&admin=1
To pojawia się ciastko, PHPSESSID o wartości 64e9fs1ld9qaki0dnhiei1f336
Następnie należy dodać to ciastko na stronę nr 1. W tym celu po wpisaniu poprzedniego linku klikam na link do strony poprzedniej i mam hasło do następnego poziomu:

Hasło do następnego poziomu to chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ
NATAS22:
Link do zalogowania: http://natas22.natas.labs.overthewire.org/index.php
Login: natas22, password: chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ

Kod strony przedstawia się poniżej:
<?
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>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas22", "pass": "<censored>" };</script></head>
<body>
<h1>natas22</h1>
<div id="content">
<?
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>
Najbardziej interesujący fragment to:
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: /");
W parametrze GET jest możliwość wpisania zmiennej revelio, która jeżeli wynosi 1 to podglądamy hasło do kolejnego poziomu:
GET /?revelio=1 HTTP/1.1
Host: natas22.natas.labs.overthewire.org
Cache-Control: max-age=0
Authorization: Basic bmF0YXMyMjpjaEc5ZmJlMVRxMmVXVk1nallZRDFNc2ZJdk40NjFrSg==
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 OPR/66.0.3515.72
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: PHPSESSID=5etfncplalrnj7hu60knr1rak5
Connection: close
Wynikiem zapytania jest :

NATAS23:
Link do zalogowania: http://natas23.natas.labs.overthewire.org/index.php
Login: natas23, password: D0vlad33nQF0Hz2EP255TP5wSW9ZsRSE

Poniżej kod strony:
<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src="http://natas.labs.overthewire.org/js/wechall-data.js"></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas23", "pass": "<censored>" };</script></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>";
}
}
// morla / 10111
?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
Najciekawszy fragment skryptu to:
<?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>";
}
}
?>
Hasło do formularza musi spełnić dwa warunki : posiadać w sobie ciąg „iloveyou” oraz być liczbą większą od 10. Jak zatem to zrobić ??
Najpierw należy zrozumieć jak php sprawdza czy ciąg jest liczbą. Sprawdza wpisywany ciąg po każdym znaku od początku i ucina gdy napotka pierwszą literę. Zatem należy wpisać najpierw ciąg cyfr, które będą reprezentowały liczbę większą od 10, a następnie iloveyou

The credentials for the next level are:
Username: natas24 Password: OsRmXFguozKpTZZ5X14zNO43379LZveg