阿碼外傳-阿碼科技非官方中文 Blog: 2008/8/27

2008年8月27日

Joomla Hack Analysis

Joomla 是一套使用 PHP 程式語言加上 MySQL 資料庫所開發的內容管理系統(CMS, Content Management System),可以在 Linux、Windows、Mac OS X 等各種不同的平台上執行。目前 Joomla 是由 Open Source Matters (www.opensourcematters.org) 這個開放源碼組織進行開發與支援,組織的核心成員約 150 人,來自全世界各地,其中包含了開發者、設計者、系統管理者、文件撰寫者,另外有超過 9 萬名(2007.3)的參與會員。更多相關資訊可參考Joomla 官方網站

此漏洞名為:「Remote Admin Password Change」(CVE-2008-3681MILW0RM:6234BID:30667)於2008年8月12日被公開之後,Joomla 的官方網站在當天就緊急發布了 1.5.6 的更新,也呼籲所有 1.5 版本要趕快升級到 1.5.6 ,不然管理者的密碼有可能會被入侵修改。但是大多數使用者,可能還不知道有這回事呢,導致大家如果有看到近期這幾天被淪陷網站紀錄,很多都是 Joomla,請參考新聞:大量 Joomla 系統網站遭入侵

Joomla 居然這麼容易就被打下讓我們非常的好奇,於是就分析了一下 Joomla 1.5.5 原始碼。這個弱點其實不是針對程式碼來做攻擊(例如 SQL Injection 或 XSS),而是針對 Joomla 本身 business logic 的漏洞,Joomla 原先重設密碼都是要求使用者輸入 email,程式將密碼直接寄到使用者的 email,但是在1.5版之後,Joomla 改成寄送一個 32 bytes 的 token 到使用者的信箱,使用者在 Joomla 上再使用這個 token 來設定密碼。

以下是重設的 function:

function confirmReset($token)
{
global $mainframe;

$db = &JFactory::getDBO();
$db->setQuery('SELECT id FROM #__users WHERE block = 0 AND activation = '.$db->Quote($token));

// Verify the token
if (!($id = $db->loadResult()))
{
$this->setError(JText::_('INVALID_TOKEN'));
return false;
}

// Push the token and user id into the session
$mainframe->setUserState($this->_namespace.'token', $token);
$mainframe->setUserState($this->_namespace.'id', $id);

return true;
}

一般常見的入侵方式是偽造一個密碼重設的要求,再預測 token 的值。Joomla 使用 GUID 作為 token,被預測的可能性相當低。然而,Joomla 卻犯了一個邏輯上的錯誤。一般類似的密碼重設功能,都會在資料庫中紀錄使用者是否有要求重設密碼,如果有要求,才會比對 token。但是 Joomla 卻是直接比對 token,在資料庫中,沒有要求重設密碼的使用者的 token 當然是一個空字串,因此,只要在 token 欄位的值是一個空字串即可,Joomla 的重設網頁是使用 JavaScript 來檢查 TextBox 是否為空,因此只要將 JavaScript 關閉,按下 Submit,即可重設ID最小的使用者的密碼,而 ID 最小的使用者通常都是 admin。

另外,由於 Joomla 在將 token 送進資料庫前,會將 token 中的符號過濾掉,因此,我們也可以不用關閉 JavaScript,直接在 TextBox 中隨便輸入幾個符號,進入資料庫比對的 token 一樣是空字串。

Joomla 1.5.6修補了這個弱點,修補的方法是在 confirmReset 中加入了下面的程式碼:

if(strlen($token) != 32)
{
$this->setError(JText::_('INVALID_TOKEN'));
return false;
}

強制與資料庫比對的 token 長度一定要是32 bytes,因此空字串都會輸出 IVALID_TOKEN 錯誤。

正確的修補方式應該是在資料庫中加上一個型態為 bit 的欄位,紀錄使用者是否有要求重設密碼。但是這樣的修補方式必須要更動到資料庫,而 Joomla 1.5.6 的修補方式只需要覆蓋一個檔案即可。我們認為 Joomla 這算是一個救火的修補方式,也期待在 Joomla 的下一個 major release 中,能夠以加上 bit 欄位的方式來修補這個問題。

目前我們已通知許多使用 Joomla 1.5 - 1.55 還存有安全漏洞的使用者以免更多的無辜使用者被攻擊。


作者 Sun 與 Jim 為 阿碼科技 資安顧問

繼續閱讀全文...