利用phar實行php反序列化命令執行(測試環境復現)
前言
一般說到反序列化漏洞,第一反應都是unserialize()函數。然而安全研究員Sam Thomas分享了議題”It’s a PHP unserialization vulnerability Jim, but not as we know it”,利用phar偽協議會將用戶自定義的meta-data序列化的形式存儲這一特性,擴展php反序列化的攻擊面。
phar介紹
簡單來說phar就是php壓縮文檔。它可以把多個文件歸檔到同一個文件中,而且不經過解壓就能被 php 訪問並執行,與file:// php://等類似,也是一種流包裝器。
phar結構由 4 部分組成
stub phar 文件標識,格式為xxx<?php xxx; __HALT_COMPILER();?>;
manifest 壓縮文件的屬性等信息,以序列化存儲;
contents 壓縮文件的內容;
signature 簽名,放在文件末尾;
這里有兩個關鍵點,一是文件標識,必須以__HALT_COMPILER();?>結尾,但前面的內容沒有限制,也就是說我們可以輕易偽造一個圖片文件或者pdf文件來繞過一些上傳限制;二是反序列化,phar存儲的meta-data信息以序列化方式存儲,當文件操作函數通過phar://偽協議解析phar文件時就會將數據反序列化,而這樣的文件操作函數有很多。
以上內容摘自:由 PHPGGC 理解 PHP 反序列化漏洞 。
https://kylingit.com/blog/%E7%94%B1phpggc%E7%90%86%E8%A7%A3php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/
復現過程
Phar文件生成
根據文件結構我們來自己構建一個phar文件,php內置了一個Phar類。
phar_gen.php
Evil.class.php
直接運行的時候會報錯
原因是:需要將php.ini中的phar.readonly設置成off。(我在這浪費了很多時間,配置文件一定要改完后保存,然后重啟服務器)
執行之后生成一個vul.phar,用二進制編輯器打開,如圖所示
由圖可以發現,meta-data已經以序列化的形式存在phar文件中。
說明一下:其實就是把要執行的命令序列化保存在phar的壓縮文件里
反序列化
對應序列化,肯定存在着反序列化的操作。php
文件系統中很大一部分的函數在通過phar://
解析時,存在着對meta-data
反序列化的操作。
測試環境如下: test.php
訪問test.php, http://127.0.0.1/test.php?url=phar://vul.phar,得圖
執行成功。
防御
- 在文件系統函數的參數可控時,對參數進行嚴格的過濾。
- 嚴格檢查上傳文件的內容,而不是只檢查文件頭。
- 在條件允許的情況下禁用可執行系統命令、代碼的危險函數。