Author: p0wd3r (知道創(chuàng)宇404安全實驗室)
Date: 2017-05-18
0x00 漏洞概述
漏洞簡介
Joomla于5月17日發(fā)布了新版本3.7.1,( https://www.joomla.org/announcements/release-news/5705-joomla-3-7-1-release.html ),本次更新中修復一個高危SQL注入漏洞( https://developer.joomla.org/security-centre/692-20170501-core-sql-injection.html ),成功利用該漏洞后攻擊者可以在未授權(quán)的情況下進行SQL注入。
漏洞影響
未授權(quán)狀態(tài)下SQL注入
影響版本: 3.7.0
0x01 漏洞復現(xiàn)
Joomla 在 3.7.0 中新增了一個 com_field 組件,其控制器的構(gòu)造函數(shù)如下,在 components/com_fields/controller.php 中:

可以看到當訪問的 view 是 fields , layout 是 modal 的時候,程序會從 JPATH_ADMINISTRATOR 中加載 com_fields ,這就意味著普通用戶可以通過這樣的請求來使用管理員的 com_fields 。
接下來我們看管理員的 com_fields 組件,我們來到 administrator/components/com_fields/models/fields.php ,其中的 getListQuery 的部分代碼如下:

程序通過 $this->getState 取到 list.fullordering ,然后使用 $db->escape 處理后傳入$query->order 函數(shù),mysqli的 escape 函數(shù)代碼如下:

這里調(diào)用 mysqli_real_escape_string 來轉(zhuǎn)義字符,該函數(shù)具體作用如下:

僅對單雙引號等字符進行轉(zhuǎn)義,并未做更多過濾。另外 $query->order 函數(shù)的作用僅僅是將數(shù)據(jù)拼接到 ORDER BY 語句后,也并未進行過濾,所以如果 list.fullordering 可控,那么就可以進行注入。
我們可以看到 list.fullordering 是一個 state , state 會在視圖的 display 函數(shù)中進行設置:

跟進這個設置過程,程序會走到 libraries/legacy/model/list.php 中的 populateState 函數(shù)中,具體的調(diào)用棧如下:

該函數(shù)中有如下一段代碼:
if ($list = $app->getUserStateFromRequest($this->context . '.list', 'list', array(), 'array'))
{
foreach ($list as $name => $value)
{
// Exclude if blacklisted
if (!in_array($name, $this->listBlacklist))
{
...
$this->setState('list.' . $name, $value);
}
}
}
程序通過 $app->getUserStateFromRequest 取到一個 $list 數(shù)組 ,如果數(shù)組的key不在黑名單中,則遍歷該數(shù)組對相應 state 進行注冊, getUserStateFromRequest 的代碼如下:

結(jié)合前面的調(diào)用來看,我們可以通過請求中的參數(shù) list 來設置 $list 變量,因此我們訪問 http://ip/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml(2,concat(0x7e,(version())),0) 并開啟動態(tài)調(diào)試動態(tài)調(diào)試,結(jié)果如下:

可以看到 list.fullordering 已經(jīng)被我們控制。
回到 getListQuery ,該函數(shù)會在視圖加載時被自動調(diào)用,具體函數(shù)調(diào)用棧如下:

所以我們的payload也就通過 getState 傳入了這個函數(shù),最終導致SQL注入:


0x02 補丁分析

改為取 list.ordering 和 list.direction 作為查詢的參數(shù),這兩個參數(shù)在 populateState函數(shù)中做了如下處理:

如果值不在指定范圍內(nèi)則將其更改為默認值,因此無法再將payload帶入。
0x03 參考
https://www.seebug.org/vuldb/ssvid-93113
https://blog.sucuri.net/2017/05/sql-injection-vulnerability-joomla-3-7.html
https://developer.joomla.org/security-centre/692-20170501-core-sql-injection.html
https://www.joomla.org/announcements/release-news/5705-joomla-3-7-1-release.html
|