freebuf科普 drupal是使用php語言編寫的開源内容管理架構(cmf),它由内容管理系統(cms)和php開發架構(framework)共同構成。連續多年榮獲全球最佳cms大獎,是基于php語言最著名的web應用程式。 前幾天爆了一個 drupal 的 sql injection 注入漏洞,但是這個漏洞不止與 sql 注入這麼簡單,還可以利用其來 rce(遠端代碼執行)。知名安全研究人員stefanesser 在 twitter 上也有提及,可是沒有透露細節。

第一個參數是 function 的名稱,第二個參數是要調用的參數的參數。 利用這幾個特性,可以實作 drupal 的各種花式 getshell。我隻審計出來一種,還有很多方式并沒有去實作(畢竟渣渣看不出來)。
drupal特性引發漏洞
drupal 有一個特性,可以讓管理者添加 php tag 來寫文章,叫做 php filter。這個特性預設是關閉的。當然,由于 pdo 可以執行多行 sql 語句的特性,我們可以直接添加管理使用者然後登入上去,打開 php filter 的 module,然後發表文章,最後 getshell。 想要自動化也簡單,那就是把從打開 php filter 到發表文章的所有執行過的 sql 語句合在一起當作 payload,最後 getshell。這個思路的 poc 我也做過,可惜太過于繁瑣,最後 payload 出來很長很長,一點也不優雅,而且并沒有利用到 callback 的特性。為了鑽個牛角尖,咱就來審計一下如何花式 getshell。 上文中說了 php filter 是一個可以執行 php 代碼的特性,而 php filter 所在的檔案是/modules/php/php.module這個檔案,其中:
這個函數就是用來執行 custom php code 的函數。
callback引發指令執行
對于審計的工具,我這種渣渣直接就 find 然後 grep 定位檔案,在用 phpstorm + ideavim(plugin of phpstorm),來跟蹤函數,輕松愉快ow<。 我們很确定的是我們要找 call_user_func_array 這個函數,利用如下指令來查找:
其實我們可以進一步縮小範圍,因為第一個函數是我們調用的函數,而如果我們想利用的話,call_user_func_array這個函數的第一個參數我們要可以控制,那麼進一步縮小範圍:
結果如下:
我們接下來就要檢視上下文,看從哪裡可以控制那個變量。經過逐一排查,我定位到/include/menu.inc這個檔案中的menu_execute_active_handler函數。 閱讀可以發現,我們可以控制$_get['q']這個參數,接着進入menu_get_item這個函數。這個函數的核心代碼是這裡: 在 menu_router 裡查詢我們輸入的$_get['q'],然後從傳回所有字段。接着回到menu_execute_active_handler函數。
這裡取出router_item中的include_file,然後用require_once來包含。這裡是一個 point, 因為 drupal 預設不開啟 php filter,這裡包含了就可以不用開啟 php filter 了 。 接着取出router_item中的page_callback,帶入call_user_func_array執行。 到此為止整個流程我們已經很清楚了。 需要注意的是page_arguments的第一個參數才會被執行,而第一個參數正是$_get['q']的值。
利用測試
通過注入向 menu_router 表中插入一段資料:
通路位址即可造成 rce。 我們來測試一下。首先在資料庫執行語句:
然後通路http://192.168.1.109/drupal/?q=%3c?php%20phpinfo();?%3e。
<b>原文釋出時間:2017年3月24日</b>
<b>本文由:</b>安全加 <b>釋出,版權歸屬于原作者</b>
<b>原文連結:</b><b>http://toutiao.secjia.com/callback%e5%99%a9%e6%a2%a6%ef%bc%9a%e8%a7%a3%e6%9e%90%e8%91%97%e5%90%8dcms%e6%a1%86%e6%9e%b6drupal-sql%e6%b3%a8%e5%85%a5%e6%bc%8f%e6%b4%9e</b>
<b></b>
<b>本文來自雲栖社群合作夥伴安全加,了解相關資訊可以關注安全加網站</b>