當前位置:
首頁 > 最新 > Drupal遠程代碼執行漏洞分析

Drupal遠程代碼執行漏洞分析

閱讀: 273

近日,流行的開源內容管理框架Drupal曝出一個遠程代碼執行漏洞,漏洞威脅等級為高危,攻擊者可以利用該漏洞執行惡意代碼,導致網站完全被控制。漏洞對應的CVE編號為CVE-2018-7600。

本篇文章對Drupal 8 – CVE-2017-7600漏洞進行了詳細分析。這個漏洞看起來是一個漏洞,其實我認為,它是由兩個小的雞肋問題組成的。具體是什麼呢?

漏洞分析

這個漏洞的根本原因出在drupal對錶單的渲染上:

可見,在drupal中,我們不需要直接寫html表單,而是先創建一個數組,表單呈現引擎通過位於drupalcorelibDrupalCoreFormFormBuilder.php文件中的buildForm方法構造出一個名為$form表單,然後成對應的html表單進行呈現。

通過下圖buildform的定義,可以看出它是用來構造一個表單的

最終的$form是如下圖這個樣子:

這個漏洞,恰恰就出在了這裡。

但是對於一個drupal框架的應用程序來說,後台表單數組都是開發者寫好的,像這個樣子

攻擊者是無法改變表單數組元素的key值的。

很多應用都提供了如下的一個便利的方法:

比如要註冊一個用戶,用戶名、密碼、郵箱、電話,這些東西都填好了。當點擊提交的時候,網站告訴你,用戶名已存在。

這時候,你會發現,密碼、郵箱、電話這些元素不需要你再次填寫了,頁面已經將保存下來了。

drupal系統同樣有這樣的功能,具體如何實現的呢?下面我們做個試驗:

我們先提交個正常的表單

先在buildform函數返回處下斷後

填寫表單並提交

頁面跳轉到註冊成功頁面,

我們在buildform函數返回處下的斷點根本沒有斷下來。

接著我們再按著上面的表單一模一樣的註冊一個看看:

但這次呢,在斷點處成功斷下了:

在這處斷點,我們把name的值改為」kingsguard_test_1」試試

這次的返回頁面如下:

整個流程是:

用戶填寫表單->表單沒有問題->返回註冊成功頁面

用戶填寫表單->表單內容有問題(例如用戶名已被註冊)->調用buildform方法,把用戶傳入的內容一同構造為表單數組->渲染表單數組為html頁面返回

這就是剛剛在buildform斷點處把name值由kingsguard改為kingsguard_test_1,返回的頁面里username值也變成kingsguard_test_1的原因。

到這裡,攻擊鏈已經很明確了,攻擊者傳入的值,可以通過buildform(方法構造表單數組,並且這個表單數組接下來還會被drupal表單呈現引擎解析為html頁面。

當我們在這個註冊表單頁面里,如果想上傳一張圖片

這時候發送的請求如下

當上傳成功後,往往有一個縮略圖顯示在那,如下圖菊花處:

這個縮略圖,是通過drupalcoremodulesfilesrcElementManagedFile.php文件中的uploadAjaxCallback方法來解析。

注意,還記的上文buildform方法嗎?buildform生成$form數組後,將生成的$form數組傳遞給uploadAjaxCallback方法來解析,目的是在返回頁面上顯示那個縮率的菊花。

既然流程已經捋順了,我們通過構造poc來動態調試下,發送如下圖post包:

首先會進入buildform函數來構造表單數組,接下來這個表單數組($form)會進入uploadAjaxCallback方法。

看下這個uploadAjaxCallback方法:

傳入uploadAjaxCallback方法中的$form變數,就是buildform方法生成的表單數組:

$form數組傳入uploadAjaxCallback方法中後,可以看到有這麼一行(下圖紅框處):

$form_parents變數竟然可以從get中傳入,意味著這個變數可控,其實就是我們poc中的element_parents=account/mail/%23value。

通過poc,此處的$form_parents變數如下圖

$form_parents變數和$form通過NestedArray::getValue方法後,結果值賦給$form

新的form變數如下:

接下來看這裡的renderRoot方法:

此處傳入的$form變數為:

繼續看renderRoot方法:

裡面調用了render方法

繼續看render方法:

裡面調用了doRender方法

繼續看doRender方法:

在這個方法的505行

調用call_user_func方法

此處的參數如下:

可見,這裡的

$callable=」exec」

$elements[『#children』]=」kingsguard_text」(這裡我們傳入的惡意代碼,這裡我就不演示了)


這個漏洞看起來是一個漏洞,其實我認為,它是由兩個小的雞肋的問題組成的,第一次就是在buildform處,用戶傳入的變數沒有受到限制,導致可以傳入mail[#post_render]、mail[#type]這樣的變數,但是單單這個問題,還不嚴重,因為對於最終渲染的html頁面來說,傳入的數組仍然是數組,不能被當成元素來解析。但是偏偏uploadAjaxCallback方法中的$form_parents變數是直接通過get(『element_parents』)得來的,這下兩個一結合,$form_parents把之前傳入的數值當成元素了,這下就造成了一個大洞。

文章出處:綠盟科技博客

你可能歡

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 黑白之道 的精彩文章:

英國說要對俄國發動網路戰
Snort-開源網路入侵檢測工具

TAG:黑白之道 |