Roundcube 1.2.2:通過郵件執行命令

Editor發表於2016-12-13


Roundcube 1.2.2:通過郵件執行命令


Roundcube 是一款廣泛使用的開源的 webmail 軟體,全世界有很多組織和公司都在使用。舉個例子,過去 12 個月,它在 SourceForge 上的映象檔案的下載次數超過 260,000,但是這不過是實際使用者量的一小部分。把 Roundcube 安裝在伺服器上之後,它就可以提供一個網頁給使用者,使用者使用瀏覽器進行登入認證並收發郵件。

在這篇文章裡,我們看看一個攻擊者如何,僅僅只是在 Roundcube1.2.2(>=1.0) 寫一封郵件,就能遠端在底層作業系統上執行任意指令。這個漏洞是高危的,因為所有預設安裝都受影響。我們強烈要求所有 Roundcube 的管理員儘快升級軟體到 1.2.3 版本。

RIPS 分析


譯者注:RIPS 是一款自動化靜態分析 PHP 程式碼的工具。

Roundcube 1.2.2:通過郵件執行命令


RIPS 花了 25 秒的時間完整分析了整個應用,並且檢測出了上圖所示的安全漏洞。雖然看起來問題挺多的,但是大部分都不是很嚴重,因為它們屬於安裝模組或者已棄用的程式碼。不過,我們建議還是要移除掉這些棄用的程式碼來修復這些漏洞,以免後患。

刪減後的分析結果可以在我們的 RIPS  demo 應用裡看到。注意一點,為了確保漏洞可以修復,我們將結果限制在本文提及的問題上。

要求


利用這個漏洞有以下幾個條件。


1、  Roundcube 必須是配置成使用 PHP 的mail() 函式的(預設配置,如果沒有指定 SMTP)。


2、  PHP的mail() 函式配置使用 sendmail(預設配置,檢視 sendmail_path)。


3、  PHP 配置裡的 safe_mode 是關閉的(預設配置,檢視 safe_mode)。


4、  攻擊者必須知道或者猜出 webroot 的絕對路徑。


這些條件都不是很特別的要求,意味著現在在自然環境裡有大量的存在漏洞的系統。

描述


在 Roundcube1.2.2 或者更早的版本里,使用者的輸入未經過濾就被傳到了 PHP 內建函式 mail() 的第五個引數,這已被證明是有很高安全風險的。問題出在 mail() 函式的呼叫會導致 PHP 執行 sendmail 程式。第五個引數可以傳入一些額外的執行引數,更改 sendmail 的配置。因為sendmail 提供了-X選項將郵件通訊記錄到一個檔案,攻擊者可以利用此引數在伺服器的 webroot下建立一個惡意 PHP 檔案。雖然這個漏洞很罕見,極少人知,但是 RIPS 還是很快檢測出來了。以下程式碼引發了漏洞。

program/steps/mail/sendmail.inc

程式碼:

Roundcube 1.2.2:通過郵件執行命令


這裡,獲取 POST 引數 _from 的值,然後傳入到Roundcube 的 deliver_message() 中作為第二個引數使用。

program/lib/Roundcube/rcube.php

程式碼:

Roundcube 1.2.2:通過郵件執行命令


然後這個函式將 $from 引數傳到呼叫的 mail() 函式中。意思是將定製的 from header 通過 -f 選項傳遞給 sendmail 程式。

過濾不夠安全


一個有趣的地方在於,似乎 from 電子郵件地址已被一個正規表示式預先過濾過了。最基本,首先要確保 $from 引數中沒有空格,來減少利用 -f後面的引數進行攻擊的可能性。在這裡使用空格常數如 $IFS 或者新的 shell 命令 ` 都不成功。然而,應用中有一個邏輯缺陷導致這個過濾失效了。

program/steps/mail/sendmail.inc

程式碼:

Roundcube 1.2.2:通過郵件執行命令


在 105 行,從使用者控制的 $from 引數裡提取出一封無空格的郵件。不過,提取只有當rcmail_email_input_format() 返回的值相當於TRUE 時才會進行。接下來,我們分析一下這個函式。

program/steps/mail/sendmail.inc

程式碼:

Roundcube 1.2.2:通過郵件執行命令


在 863 行,這個函式使用了另一個正規表示式,要求這一行在郵件匹配後面必須有個 ($)。攻擊者使用的 payload 當然可以不需要滿足這個條件,因此在 foreach 迴圈後,$result 陣列會保持空白。在這種情況下,876 行的 implode() 函式返回一個空字串(等價於 FALSE),然後 $from的值就不會被過濾和改變了。

概念的實證


當使用 Roundcube 傳送郵件時,HTTP 請求是可以被截斷和更改的。這個地方,我們修改_from 引數來在檔案系統上建立一個惡意檔案。

程式碼:

Roundcube 1.2.2:通過郵件執行命令


這將允許攻擊者在 web 根目錄建立一個可執行檔案 rce.php,內容是 _subject 引數的值,可以包含 PHP 程式碼。執行完請求之後,包含以下內容的檔案就會被建立。


程式碼:

Roundcube 1.2.2:通過郵件執行命令


因為郵件資料沒有被編碼,subject 引數會被直接儲存成明文。這將允許在可執行檔案中注入PHP 標籤。

時間線


日期         事件


2016/11/21  首次聯絡供應商
2016/11/22  供應商在 Github 上修復漏洞
2016/11/28  供應商同意協調披露
2016/11/28  供應商釋出 Roundcube1.2.3

總結


Roundcube 抵抗著來自很多方向的攻擊,有一個大社群持續維護著它的安全。然而,此文描述的漏洞可以溜進來,由於稀有,這也是一種邊緣情況。在自動檢測工具的幫助下,我們不僅可以檢測到此邊緣情況,還節省了大量人力資源,從而可以在安全網路應用的開發過程中專注於不同方面。

我們十分感謝 Roundcube 團隊僅用了一天時間就修復了漏洞,而且一週後就發行了新版本!他們對安全問題的回應非常令人印象深刻,也非常專業。 



相關文章