一、裂痕闡明
裂痕觸發的代碼位于:/administrator/components/com_contenthistory/models/history.php,getListQuery()函數內:
通過SQL及報錯信息,可以知道我們的注入payload被插入到了赤色框部門內。跟進getState()函數,位于ibraries/legacy/model/legacy.php文件內,代碼如下:
從函數參數和官方注釋,可以知道,getState()函數成果是獲取一個model的屬性及屬性對應的值,getState()函數在model的屬性未配置時,會執行$this->populateState()來對model的一些屬性舉辦賦值操縱。
我們跟進populateState()函數看下做了什么操縱,代碼位于:/administrator/components/com_contenthistory/models/history.php 內:
該函數從用戶輸入中取出item_id,type_id,type_alias,等幾個變量,對當前model的屬性舉辦賦值,可控變量均強制為integer范例,無法操作。順著最后一行代碼:parent::populateState('h.save_date', 'DESC'),繼承跟到父類中看父類populateState()函數的界說,代碼位于:libraries/legacy/model/list.php,482行四周:
getUserStateFromRequest()函數用于將GET/POST中得list[]變量取回到$list中,并在第三個參數中指定該變量范例為array(),繼承跟進:
代碼對取到的list[]數組舉辦了遍歷,并做相應的過濾、拆分,可以看到list[select]沒有處理懲罰邏輯,會進入default的case,后續$this->setState('list.' . $name, $value)代碼執行后,導致請求中list[select]變量沒有任何變量被直接賦值給Model屬性,繼承轉頭看文章最開始的注入位置,,此時我們可以節制$this->getState('list.select')的返回值,結構SQL注入。
確認了輸入可控的位置,結構有效的payload,還需要辦理幾個小問題。結構POC:index.php?option=com_contenthistory&view=history&item_id=1&type_id=1&list[select]=(exp(~(select* from(select md5(1))x)))
會發明呈現錯誤提示:Unknowncolumn 'Array':
需要增加list[ordering]=將原SQL中的order by字段值清空。
最終可執行POC:
/index.php?option=com_contenthistory&view=history&item_id=1&list[ordering]=&type_id=1&list[select]=(exp(~(select* from(select md5(1))x)))
執行會返回:
此帶回顯POC樂成執行需要一個前提條件,就是傳入的item_id 可以在Joomla_ucm_history表中查詢到,不然會返回“500 - Layout default not found.”的提示。按照原文描寫,可以暴力猜解item_id或利用time_basedpayload,不再贅述。
二、裂痕影響
joomla3.2-3.4.4版本
三、修復方案
今朝Joomla官方已經更新3.4.5版本,用戶可登岸靠山舉辦更新。
或下載官方進級包進級,下載地點:
https://github.com/joomla/joomla-cms/releases