溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

發(fā)布時(shí)間:2022-01-17 10:59:42 來(lái)源:億速云 閱讀:138 作者:柒染 欄目:安全技術(shù)

這篇文章給大家介紹如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

前言

      在drupal框架中,比較經(jīng)典又離我們最近的莫過(guò)于18年的CVE-2018-7600這個(gè)漏洞了。但是通過(guò)本人閱讀和學(xué)習(xí)過(guò)此漏洞分析文章的過(guò)程中,發(fā)現(xiàn)都是針對(duì)于此漏洞點(diǎn)的詳細(xì)分析。相對(duì)于此框架運(yùn)行流程不是很熟悉的人可能在閱讀完后很難理解。

下面主要分為兩大部分:

第一部分是對(duì)drupal框架流程的簡(jiǎn)介(這里主要針對(duì)8.x系列),讓我們知道在symfony開(kāi)源框架基礎(chǔ)上的drupal框架是如何利用監(jiān)聽(tīng)者模式支撐起整個(gè)繁雜的處理流程,并讓我們對(duì)框架如何處理一個(gè)請(qǐng)求有基本的了解。

第二部分,結(jié)合框架對(duì)漏洞CVE-2018-7600的運(yùn)行流程進(jìn)行詳細(xì)解讀,在漏洞觸發(fā)的起始點(diǎn)首先通過(guò)動(dòng)態(tài)調(diào)試正常數(shù)據(jù)包來(lái)了解drupal框架對(duì)其的處理流程,借此利用正常包中的可控變量來(lái)構(gòu)造POC包。讓我們不僅能對(duì)開(kāi)頭和結(jié)果得以了解,更能讓中間的過(guò)程透明化。得以觸類(lèi)旁通。

一、背景介紹

Drupal是使用PHP語(yǔ)言編寫(xiě)的開(kāi)源內(nèi)容管理框架(CMF),它由內(nèi)容管理系統(tǒng)(CMS)和PHP開(kāi)發(fā)框架(Framework)共同構(gòu)成。連續(xù)多年榮獲全球最佳CMS大獎(jiǎng),是基于PHP語(yǔ)言最著名的WEB應(yīng)用程序。

Drupal架構(gòu)由三大部分組成:內(nèi)核、模塊、主題。三者通過(guò)Hook機(jī)制緊密的聯(lián)系起來(lái)。其中,內(nèi)核部分由世界上多位著名的WEB開(kāi)發(fā)專(zhuān)家組成的團(tuán)隊(duì)負(fù)責(zé)開(kāi)發(fā)和維護(hù)。

Drupal綜合了強(qiáng)大并可自由配置的功能,能支持從個(gè)人博客(PersonalWeblog)到大型社區(qū)驅(qū)動(dòng)(Community-Driven)的網(wǎng)站等各種不同應(yīng)用的網(wǎng)站項(xiàng)目。Drupal最初是由DriesBuytaert所開(kāi)發(fā)的一套社群討論軟件。之后,由于它的靈活的架構(gòu),方便的擴(kuò)展等特性,使得世界上成千上萬(wàn)個(gè)程序員加入了Drupal的開(kāi)發(fā)與應(yīng)用中。今天,它已經(jīng)發(fā)展成為一套強(qiáng)大的系統(tǒng),很多大型機(jī)構(gòu)都采用基于Drupal的框架建站,包括The Onion,Ain't ItCool News,SpreadFirefox,Ourmedia,KernelTrap,NewsBusters等等。它特別常見(jiàn)于社區(qū)主導(dǎo)的網(wǎng)站。

二、準(zhǔn)備工作

     2.1源碼下載

      首先可以直接通過(guò)官網(wǎng)下載頁(yè)面https://www.drupal.org/download 直接下載最新版本或者通過(guò)https://www.drupal.org/project/drupal/releases/xxx xxx代表你想下載的版本號(hào),來(lái)下載對(duì)應(yīng)版本的源碼文件。  你也可以用PHP包管理工具composer進(jìn)行下載。

     2.2 drupal安裝

    安裝環(huán)境:WIN7 32位

    集成環(huán)境:PHPSTUDY

    調(diào)試環(huán)境:PHPSTORM

    安裝中可能出現(xiàn)的問(wèn)題和解決辦法:

 1.  php版本問(wèn)題:最好為PHP7.0以上

 2.    datetime問(wèn)題

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

解決方法:

php.ini 中設(shè)置

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

3.安裝警告

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      這兩個(gè)問(wèn)題(warning)可以不解決。

      針對(duì)問(wèn)題1解決方法:升級(jí)php版本為7.1及以上。

      針對(duì)問(wèn)題2解決辦法:

      在php.ini中,找到[opcache],在這個(gè)地下添加如下內(nèi)容。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

zend_extension="C:\xxx\xxx\php\php-7.0.12-nts\ext\php_opcache.dll"

opcache.memory_consumption=128

opcache.interned_strings_buffer=8

opcache.max_accelerated_files=4000

opcache.revalidate_freq=60

opcache.fast_shutdown=1

opcache.enable_cli=1

 4.    因?yàn)閐rupal處理有些請(qǐng)求過(guò)慢,有可能會(huì)導(dǎo)致超時(shí)出現(xiàn)異常,在Php.ini中max_execution_time選項(xiàng)設(shè)置大點(diǎn)即可。

三、框架淺析

3.1目錄結(jié)構(gòu)

下面是drupal 8.5.7 源碼解壓后的目錄:

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

/core drupal的內(nèi)核文件夾,詳見(jiàn)后文說(shuō)明

/modules 里存放 自定義或者下載的模塊

/profiles 里存放 下載和安裝的自定義配置文件

/sites  文件夾,在drupal 7 或者更早的版本中,主要存放站點(diǎn)使用的主題和模塊活其他站點(diǎn)文件。

/themses 里存放 自定義或者下載的主題

/vendor 里存放 代碼的依賴(lài)庫(kù)

接下來(lái)我們來(lái)看核心文件夾core下的目錄結(jié)構(gòu)

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

/core/assets - drupal 所使用的各種擴(kuò)展庫(kù),如jquery,ckeditor,backbone,normalizeCSS等

/core/config  - drupal 中的核心配置文件

/core/includes – 模塊化的底層功能函數(shù),如模塊化系統(tǒng)本身

/core/lib – drupal提供的原始核心類(lèi)

/core/misc – 核心所需要的前端雜項(xiàng)文件,如JS,CSS,圖片等。

/core/modules – 核心模塊,大約80項(xiàng)左右

/core/profiles – 內(nèi)置安裝配置文件

/core/scripts – 開(kāi)發(fā)人員使用的各種命里腳本

/tests – 測(cè)試相關(guān)用的文件

/core/themes – 內(nèi)核主題

3.2框架運(yùn)行邏輯

    Drupal是建立在symfony開(kāi)源框架之上的,在symfony的官網(wǎng)上可知sysmfony就是一個(gè)可復(fù)用的php組件集,可以將任何一個(gè)組件獨(dú)立的運(yùn)用到自己的應(yīng)用程序中來(lái),在symfony官網(wǎng)里每一個(gè)組件都有獨(dú)立的文檔,這些組件有些被drupal直接使用,有些根據(jù)drupal自己的特性進(jìn)行了修改。

我們首先來(lái)看一下symfony的執(zhí)行流程

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

Drupal 與 symfony 在設(shè)計(jì)上也使用了相同的理念,它們都認(rèn)為任何一個(gè)網(wǎng)站系統(tǒng)其實(shí)就是一個(gè)把請(qǐng)求轉(zhuǎn)換為響應(yīng)的系統(tǒng)。

在drupal的路由系統(tǒng)中,我們可以看到各個(gè)組件之間的關(guān)系:

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

在此基礎(chǔ)上,drupal對(duì)symfony的處理流程進(jìn)行了細(xì)化,構(gòu)成了現(xiàn)在這個(gè)龐大的drupal處理響應(yīng)流程。

圖片鏈接地址為https://www.drupal.org/docs/8/api/render-api/the-drupal-8-render-pipeline 如需要可自行下載高清版。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

3.3從入口文件來(lái)看

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      入口文件非常簡(jiǎn)潔,只有6行代碼量,卻貫穿了整個(gè)drupal,由于drupal的核心系統(tǒng)過(guò)于龐大,分析不可能面面俱到,我們將從入口文件一行行來(lái)看,分析下它的運(yùn)行流程。

      首先是$autoloader =require_once 'autoload.php'; 表面上看單單的是包含了一個(gè)autoload.php的文件,實(shí)際上drupal會(huì)利用PHP自動(dòng)加載機(jī)制創(chuàng)建一個(gè)自動(dòng)加載器,并獲取了一個(gè)自動(dòng)加載的對(duì)象。

 下面從代碼方面簡(jiǎn)略看下其流程:其根本是調(diào)用vendor/autoload.php 中的getLoader函數(shù)。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

 接著我們進(jìn)入函數(shù)看看它做了什么:

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

ClassLoader對(duì)象就是利用里面定義的基本對(duì)應(yīng)關(guān)系去查找函數(shù)和類(lèi)定義文件。

函數(shù)最后返回實(shí)例化加載器,至此第一步完成,drupal以后就不需要手動(dòng)的 include一大堆文件了,省去了大量工作。

接著是 $kernel =new DrupalKernel('prod', $autoloader); drupal創(chuàng)建了一個(gè)新的drupal內(nèi)核對(duì)象,為處理即將到來(lái)的請(qǐng)求對(duì)象做準(zhǔn)備。

 如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

緊接著是入口文件中的$request= Request::createFromGlobals()這一行代碼。對(duì)于一個(gè)面向?qū)ο蟮南到y(tǒng)來(lái)說(shuō),我們不應(yīng)該直接使用$_POST,$_GET,$_COOKIE等這些全局變量。Drupal把它們?nèi)糠庋b進(jìn)了$request對(duì)象。這樣不僅簡(jiǎn)單方便,而且使用請(qǐng)求的對(duì)象可直接加入一些額外的功能和自定義的屬性。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

最終,會(huì)把相應(yīng)的全局變量加到request對(duì)象中,并返回封裝好的request對(duì)象。

如果說(shuō)上面的操作只是預(yù)備階段,那么接下來(lái)$response = $kernel->handle($request);這行代碼將開(kāi)始步入正題,由drupal內(nèi)核對(duì)象kernel來(lái)處理request請(qǐng)求。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

Drupal的處理核心是利用了設(shè)計(jì)模式里面的監(jiān)聽(tīng)者模式。其中包括一個(gè)事件源,里面包含了不同的事件以及事件等級(jí)。另一部分就是需要執(zhí)行事件的程序或者函數(shù),我們叫它監(jiān)聽(tīng)者。在請(qǐng)求處理的這個(gè)流程中,每到一個(gè)節(jié)點(diǎn),會(huì)派發(fā)出相應(yīng)的事件,監(jiān)聽(tīng)者會(huì)根據(jù)獲取的事件對(duì)象和等級(jí)來(lái)進(jìn)行相應(yīng)的操作。

      其中系統(tǒng)核心事件還是繼續(xù)沿用symfony框架中的事件,位于kernelevents.php中,其中包含八大核心:

      Const REQUEST = ‘kernel.request’ 執(zhí)行框架代碼中的任何代碼之前,請(qǐng)求分派的開(kāi)始觸發(fā)的。

      Const EXCEPTION = ‘kernel.exception’ 出現(xiàn)未捕獲的異常時(shí)觸發(fā)的事件。

      Const VIEW = ‘kernel.view’ 當(dāng)控制器返回值不是response 實(shí)例時(shí)觸發(fā)。此時(shí)控制器返回的是渲染數(shù)組,來(lái)進(jìn)一步進(jìn)行渲染工作。

      Const CONTOLLER = ‘kernel.controller’ 解析request請(qǐng)求找到相對(duì)應(yīng)的控制器時(shí)觸發(fā),并可以對(duì)此控制器進(jìn)行修改。

      Const CONTROLLER_ARGUMENTS =‘kernel.controller_arguments’ 解析控制器的參數(shù)時(shí)觸發(fā),并可對(duì)參數(shù)進(jìn)行更改。

      Const RESPONSE = ‘kernel.response’ 創(chuàng)建響應(yīng)回復(fù)請(qǐng)求時(shí)觸發(fā),并可修改或替換要回復(fù)的相應(yīng)。

      Const TERMINATE = ‘kernel.terminate’ 一旦發(fā)送響應(yīng),就會(huì)觸發(fā)。這個(gè)事件會(huì)允許處理繁重的post-response任務(wù)。

      Const FINISH_REQUEST = ‘kernel.finish_request’完成Request請(qǐng)求時(shí)觸發(fā),可在請(qǐng)求期間更改應(yīng)用程序時(shí)重置應(yīng)用程序的全局和環(huán)境狀態(tài)。

      除了這些核心的事件,drupal中的每個(gè)監(jiān)聽(tīng)者也會(huì)派發(fā)它們自己的事件。這些文件的位置位于\core\lib\Drupal\Core\目錄下相對(duì)應(yīng)文件夾中。它們都是以events.php結(jié)尾,文件中定義了相應(yīng)的靜態(tài)事件變量。

      我們接下來(lái)看下drupal 核心的請(qǐng)求流程:

開(kāi)始請(qǐng)求request---》解析請(qǐng)求得到控制器并修正------》解析控制器參數(shù)----》根據(jù)控制器調(diào)用其中的方法-----》觀察控制器的返回情況:返回響應(yīng)對(duì)象reponse或繼續(xù)進(jìn)行渲染------》發(fā)送響應(yīng)。如果整個(gè)流程中途產(chǎn)生異常,會(huì)直接觸發(fā)異常事件進(jìn)行異常的分發(fā)。請(qǐng)求對(duì)象在整個(gè)流程中除了會(huì)對(duì)核心請(qǐng)求事件的響應(yīng),還會(huì)根據(jù)實(shí)際情況進(jìn)入響應(yīng)其他普通模塊事件的分支,但是不管中途的過(guò)程如何崎嶇坎坷,最終都會(huì)重新回歸主流程返回響應(yīng)對(duì)象response。

接下來(lái)從源代碼中觀察下上述具體行為:

      從index.php中繼續(xù)跟進(jìn)便進(jìn)入了drupalkernel.php文件,我們來(lái)看看做了那些操作。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試   

接下來(lái)就是一系列的處理函數(shù)函數(shù)調(diào)用鏈,我們一直跟進(jìn)handle函數(shù)即可,這樣我們直接可跟進(jìn)核心函數(shù)handleraw

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

這里我們繼續(xù)跟進(jìn)即將返回的filterResponse函數(shù)。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

這里的響應(yīng)對(duì)象將一層一層的返回(需要注意的是不是所有的響應(yīng)結(jié)果都會(huì)走這個(gè)流程),但是最終都會(huì)封裝成respone響應(yīng)對(duì)象,返回至index.php文件中的$response變量中。然后調(diào)用$response->send()發(fā)送封裝好的響應(yīng)對(duì)象。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

有時(shí)我們發(fā)送的請(qǐng)求操作的內(nèi)容會(huì)過(guò)于繁瑣,所以當(dāng)上面的調(diào)用結(jié)束后,我們的drupal內(nèi)核在關(guān)閉前會(huì)做最后的處理。流程進(jìn)入Index.php文件的最后一行,調(diào)用$kernel->terminate($request,$response),我們根據(jù)調(diào)用鏈跟進(jìn)stackedhttpkernel.php文件

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

至此,整個(gè)周期已經(jīng)結(jié)束。

我們發(fā)現(xiàn)上面整個(gè)過(guò)程中出現(xiàn)最多的就是派發(fā)事件這個(gè)操作了,其實(shí)所有派發(fā)進(jìn)行的流程是相同的,派發(fā)的具體過(guò)程在ContainerAwareEventDispatcher.php文件中,我們拿kernel.request事件來(lái)進(jìn)行舉例說(shuō)明。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

系統(tǒng)中監(jiān)聽(tīng)者總數(shù)有19個(gè)之多,每個(gè)監(jiān)聽(tīng)者其中又會(huì)有與之相關(guān)的服務(wù)名,我們會(huì)根據(jù)傳入的事件名稱(chēng)匹配相應(yīng)的監(jiān)聽(tīng)者,接著遍歷挨個(gè)調(diào)用其中的服務(wù)名所對(duì)應(yīng)的功能函數(shù)。我們這里是kernel.request事件,調(diào)用方式為回調(diào)調(diào)用。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

四、再看CVE-2018-7600

       通過(guò)第三部分單純的框架分析可能只對(duì)流程有一個(gè)模糊的概念,接下來(lái)我們結(jié)合漏洞實(shí)例,針對(duì)比較經(jīng)典的drupal框架漏洞cve-2018-7600來(lái)仔細(xì)觀察下此漏洞在框架中的詳細(xì)運(yùn)行流程。我們這里利用漏洞觸發(fā)環(huán)境的版本為8.5.0,此版本漏洞觸發(fā)更為直觀,所以我們后面分析所用代碼版本如不做說(shuō)明皆為此版本。

4.1 補(bǔ)丁對(duì)比

      因?yàn)榇寺┒丛?.5.1版本中被修復(fù),5.0 和5.1又只相差一個(gè)子版本,我們可以更清晰的在源碼中對(duì)比出其中的差異??垂俜绞侨绾涡迯?fù)這個(gè)漏洞的:在8.5.1版本的源碼中,新增了一個(gè)RequestSanitizer.php文件,里面是對(duì)request請(qǐng)求部分進(jìn)行過(guò)濾,在stripDangerousValues方法中過(guò)濾了以#開(kāi)頭且不再白名單里的所有鍵名的值。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

  在prehandle方法中調(diào)用了上述文件新增的方法進(jìn)行過(guò)濾,下圖右邊紅色部分為8.5.1新增的過(guò)濾代碼。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試   

此處過(guò)濾代碼的調(diào)用位置是在drupal內(nèi)核處理請(qǐng)求之前。這樣可以一勞永逸,徹底修復(fù)了這個(gè)漏洞。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

接著我們進(jìn)入drupal官網(wǎng)查看官方文檔發(fā)現(xiàn)了drupal render api對(duì)#開(kāi)頭有特殊處理,關(guān)鍵文檔鏈接在下方

https://www.drupal.org/docs/8/api/render-api/render-arrays并根據(jù)checkpoint安全團(tuán)隊(duì)發(fā)布了一份關(guān)于此漏洞相關(guān)技術(shù)細(xì)節(jié)報(bào)告。鏈接如下:https://research.checkpoint.com/uncovering-drupalgeddon-2/。發(fā)現(xiàn)漏洞觸發(fā)的源頭是8.5.0版本中注冊(cè)用戶(hù)功能中的頭像上傳功能。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

4.2數(shù)據(jù)包在框架中的運(yùn)行流程

      我們既然知道了漏洞的觸發(fā)源頭,那么首先隨便上傳一張圖片,抓一個(gè)正常的初始包看看情況。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      接著在入口文件index.php中,經(jīng)過(guò)createfromglobals函數(shù)的包裝,drupal把我們傳入的參數(shù)全部封裝進(jìn)了request對(duì)象中。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

4.2.1KernelEvents::REQUEST派發(fā)事件 

      由于上文中對(duì)框架流程做了介紹,下面就是drupal內(nèi)核處理我們的request請(qǐng)求階段了,我們這里直接把斷點(diǎn)下在handleRaw上,并進(jìn)入第一個(gè)KernelEvents::REQUEST派發(fā)事件,看看監(jiān)聽(tīng)者們都對(duì)此次請(qǐng)求做了什么。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      首先drupal嘗試去處理Option請(qǐng)求,可惜我們這里是POST請(qǐng)求,所以不處理,直接放行。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試     

接著會(huì)去處理URL路徑上的斜杠問(wèn)題,會(huì)把多個(gè)斜杠開(kāi)頭的路徑轉(zhuǎn)換成單個(gè)斜杠

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

    然后會(huì)根據(jù)請(qǐng)求驗(yàn)證身份,我們這里沒(méi)有做登陸,是游客身份,所以這里也不做特殊處理。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

     接下來(lái)會(huì)清理含有$ _GET['destination']和$ _REQUEST ['destination']目標(biāo)參數(shù),防止重定向攻擊。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      緊接著會(huì)根據(jù)POST請(qǐng)求中的_drupal_ajax參數(shù)來(lái)判斷此次請(qǐng)求是否為AJAX請(qǐng)求,并設(shè)置相關(guān)屬性。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      接下來(lái)就是根據(jù)請(qǐng)求中的URL部分來(lái)匹配相應(yīng)的路由,這里drupal會(huì)先在路由緩存中查找相應(yīng)的匹配項(xiàng),如果沒(méi)有則再進(jìn)行全部的路由查表操作。(由于代碼比較多,這里不做全部截取,只截取部分代碼),處理函數(shù)在onKernelRequest 中,同時(shí),我們也可以在user.routing.yml文件中找到相關(guān)信息。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

路由找到了,接下來(lái)就是去檢查此路由是否可用

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

緊接著就是檢查站點(diǎn)是否處于維護(hù)模式,如果是維護(hù)模式則退出賬戶(hù),檢查站點(diǎn)是否脫機(jī),檢查動(dòng)態(tài)頁(yè)面緩存,預(yù)先處理非路由設(shè)置,根據(jù)參數(shù)看是否禁用副本服務(wù)器。這些操作的相關(guān)函數(shù),均截圖在下方。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      至此,KernelEvents::REQUEST 的所有監(jiān)聽(tīng)者的行為分析完畢,我們可以看到上面這些操作主要做的是一些額外的措施,我們可以忽略不看,但是從中我們也提煉出了一些有價(jià)值的信息,通過(guò)請(qǐng)求對(duì)象匹配到了相關(guān)的路由信息。

4.2.2KernelEvents::CONTROLLER與KernelEvents::CONTROLLER_ARGUMENTS事件

      接下來(lái)在handleraw函數(shù)中,drupal通過(guò)剛剛匹配到的路由信息來(lái)找到真正的請(qǐng)求控制器和相應(yīng)的參數(shù)。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      我們先來(lái)看看KernelEvents::CONTROLLER的監(jiān)聽(tīng)者們會(huì)做那些操作。

      首先,為了以后不做沖突,在相應(yīng)的管理器上設(shè)置了關(guān)鍵的KEY

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      緊接著為了確保后面處理數(shù)據(jù)時(shí)的完整性,這里利用閉包把回調(diào)處理控制器的函數(shù)存進(jìn)$event對(duì)象中

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      因?yàn)镵ernelEvents::CONTROLLER_ARGUMENTS并沒(méi)有屬于它自己的監(jiān)聽(tīng)者,所以這里派發(fā)直接放行。

4.2.3 調(diào)用控制器

      在handleRaw中處理完了請(qǐng)求相關(guān)的事件派發(fā),并從request中找到了相應(yīng)的控制器后,就該根據(jù)控制器找到相應(yīng)的處理函數(shù)了。下方call_user_function中的控制器已經(jīng)被替換為上圖中閉包回調(diào)函數(shù)了,這里的調(diào)用控制器相當(dāng)于直接進(jìn)入上圖中的閉包函數(shù)中。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      在drupal中,控制器都會(huì)被加入渲染上下文,以保證每個(gè)控制器處理過(guò)程中如果有需要渲染的地方直接進(jìn)行渲染操作。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      根據(jù)控制器進(jìn)入到了真正的調(diào)用方法,也就是getContenResult中,表單的構(gòu)建正式開(kāi)始。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

 4.2.4 表單構(gòu)建

      在進(jìn)入buildForm 函數(shù)后,我們首先會(huì)得到POST的信息并存入form_state。    

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      在buildForm函數(shù)的retrieveForm函數(shù)中,form表單開(kāi)始初步組裝,如果其中有元素需要渲染,drupal大部分會(huì)直接利用\Drupal::service('renderer')->renderPlain();這個(gè)渲染服務(wù)對(duì)元素進(jìn)行渲染操作,最終渲染函數(shù)的主要操作在doRender函數(shù)中。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      根據(jù)rquest組裝的form表單在組裝完成之后,馬上就要處理表單請(qǐng)求了,這里processForm這個(gè)函數(shù)進(jìn)行了這個(gè)操作,在這個(gè)函數(shù)中,運(yùn)用遞歸的操作來(lái)處理行為,我們是一個(gè)圖片上傳操作,在這其中也會(huì)對(duì)此行為進(jìn)行處理,處理完畢后會(huì)進(jìn)行圖片的移動(dòng)。接著對(duì)每個(gè)元素和token進(jìn)行檢查校驗(yàn),最后根據(jù)結(jié)果rebuild整個(gè)Form表單。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      如果想在processForm中跟蹤對(duì)圖片的處理流程,可直接對(duì)下方函數(shù)進(jìn)行斷點(diǎn)設(shè)置,并根據(jù)?;厮輥?lái)查找你關(guān)心的操作。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試     

在運(yùn)行完processForm函數(shù)后這里給出rebuild后部分FORM表單截圖

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

    到這里整個(gè)表單的處理操作已經(jīng)完成了。

4.2.5 異常派發(fā)。

      在上一步完成表單操作之后,不知不覺(jué)中已把request請(qǐng)求對(duì)象轉(zhuǎn)換成了響應(yīng)response對(duì)象。眼看就要逐層返回并進(jìn)行send操作了,但是在接下來(lái)的流程中drupal發(fā)現(xiàn)這是一個(gè)ajax請(qǐng)求,這里主動(dòng)把操作攔截了下來(lái),并拋出AJAX異常來(lái)對(duì)此次請(qǐng)求做額外的處理。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      捕獲到異常之后再處理異常中進(jìn)行對(duì)異常的派發(fā)操作。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      在這里的派發(fā)其實(shí)是一個(gè)遍歷并匹配異常的過(guò)程,發(fā)生異常有很多種情況,匹配到正確的異常然后進(jìn)行具體的處理。如果沒(méi)有匹配到,放行即可。我們這里匹配到了AJAX的異常,如果還比較關(guān)心其他異常的處理流程,在kernel.exception數(shù)組中尋找即可。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試     

我們進(jìn)一步跟進(jìn)發(fā)現(xiàn)onException的buildResponse函數(shù)中,有對(duì)AJAX的具體處理方法。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      在uploadAjaxCallback函數(shù)中,我們從數(shù)據(jù)包的URL中獲取element_parents參數(shù)的值,并以此為key從我們最終處理完成的FORM表單中獲取出結(jié)果,接著對(duì)此結(jié)果進(jìn)行渲染并呈現(xiàn)在HTML頁(yè)面上。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      根據(jù)我們POST包中URL得參數(shù),我們這里取出了FORM表單中user_picture下widget數(shù)組中的第一項(xiàng)。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      最終在doRender中要被渲染的對(duì)象就是剛剛?cè)〕鰜?lái)的元素。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      渲染過(guò)后整個(gè)處理過(guò)程已即將步入尾聲,開(kāi)始構(gòu)建response并逐層返回。

4.2.6 kernel.response事件

      既然到了response階段,那么肯定就要開(kāi)始觸發(fā)response相應(yīng)了,接下來(lái)我們來(lái)看看response 有哪些監(jiān)聽(tīng)者

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      在response的派發(fā)函數(shù)中,其根本是對(duì)response對(duì)象的添磚加瓦以及做一些相應(yīng)的擴(kuò)展操作。如判斷動(dòng)態(tài)頁(yè)面是否需要緩存,是否需要添加緩存上下文,處理占位符,在成功響應(yīng)時(shí)設(shè)置額外標(biāo)頭等。上述所有的操作都會(huì)在listeners下的kernel.response數(shù)組中,這里不做詳細(xì)展開(kāi)介紹。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

4.2.7 kernel.finish_request

      當(dāng) request 和response 的操作都做完了之后,接下來(lái)會(huì)告訴drupal 內(nèi)核所有已經(jīng)完畢,會(huì)發(fā)送finish_request事件,這個(gè)事件的監(jiān)聽(tīng)者只有一個(gè):為了讓URL生成器在正確的上下文中運(yùn)行,我們需要把當(dāng)前請(qǐng)求設(shè)置為父請(qǐng)求。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

4.2.8 kernel.terminate事件

      做完上述操作后,request請(qǐng)求從請(qǐng)求棧中彈出,并逐層返回至Index.php入口主頁(yè)面進(jìn)行reponse的發(fā)送。最后進(jìn)行掃尾工作,觸發(fā)kernel.terminate事件,判斷相關(guān)換成是否需要寫(xiě)入文件。最終drupal內(nèi)核關(guān)閉。整個(gè)流程結(jié)束。

4.3 整個(gè)流程總結(jié)

      通過(guò)上一個(gè)小節(jié)分解式的解析了整個(gè)流程,我們下面來(lái)簡(jiǎn)單概括下:

發(fā)送數(shù)據(jù)包-->根據(jù)URL匹配相關(guān)路由-->根據(jù)路由找到相應(yīng)的控制器-->根據(jù)控制器得到處理方法(我們這里是表單相關(guān)操作)-->進(jìn)行表單的構(gòu)建與渲染-->處理表單請(qǐng)求-->處理完表單后判斷是否為AJAX操作-->主動(dòng)拋出異常利用AJAX回調(diào)來(lái)重新渲染URL中標(biāo)注的FORM表單key-->完成相應(yīng)構(gòu)建響應(yīng)對(duì)象-->發(fā)送相應(yīng)-->掃尾結(jié)束。

五、漏洞POC構(gòu)建

      結(jié)合上面框架的分析與理解開(kāi)始對(duì)POC進(jìn)行構(gòu)建。在checkpoint安全團(tuán)隊(duì)發(fā)布了一份關(guān)于此漏洞相關(guān)技術(shù)細(xì)節(jié)報(bào)告(上文有鏈接)中可知,漏洞觸發(fā)點(diǎn)是在表單構(gòu)建好之后,觸發(fā)AJAX異常,從FROM表單提取出要渲染的對(duì)象,進(jìn)行渲染時(shí)觸發(fā),也就是在最終的doRender函數(shù)中。我們?cè)赿oRender中發(fā)現(xiàn)如下可利用點(diǎn):

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

       根據(jù)第四部分我們對(duì)一個(gè)正常上傳包在框架中運(yùn)行的流程的分析,我們可知想讓我們自己構(gòu)造的內(nèi)容在doRender中成功觸發(fā)漏洞,首先需要控制流程,讓其進(jìn)入AJAX回調(diào)部分。在下方這個(gè)if判斷中,我們可知需要同時(shí)滿足三個(gè)條件,$ajax_form_request ,$form_state->isProcessingInput() 和$request->request->get('form_id')== $form_id。$ajax_form_request的值從下圖可知是由ajax_form這個(gè)變量控制,form_id 是表單的id。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

      接下來(lái),利用url中的element_parents參數(shù)值來(lái)獲取表單數(shù)組中的值。在第四部分4.2.5小節(jié)有所講述,此處不再重復(fù)說(shuō)明。 最后構(gòu)造相應(yīng)的變量利用doRender函數(shù)中的call_user_func_array來(lái)觸發(fā)漏洞。

      根據(jù)上述描述,我們利用mail參數(shù)構(gòu)造了如下POC包

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

     除了上述mail參數(shù)可控外,在分析過(guò)程中同時(shí)發(fā)現(xiàn)form_build_id參數(shù)也可控,另一種POC如下。

如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試

關(guān)于如何深入分析drupal8框架和漏洞動(dòng)態(tài)調(diào)試就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI