作者:LoRexxar'@知道創宇404實驗室
英文版本:http://www.bjnorthway.com/986/

2018年1月30日,joomla更新了3.8.4版本,這次更新修復了4個安全漏洞,以及上百個bug修復。

https://www.joomla.org/announcements/release-news/5723-joomla-3-8-4-release.html

為了漏洞應急這幾個漏洞,我花費了大量的時間分析漏洞成因、尋找漏洞觸發位置、回溯邏輯,下面的文章比起漏洞分析來說,更接近我思考的思路,希望能給大家帶來不一樣的東西。

背景

其中的4個安全漏洞包括

- Low Priority - Core - XSS vulnerability in module chromes (affecting Joomla 3.0.0 through 3.8.3) 
- Low Priority - Core - XSS vulnerability in com_fields (affecting Joomla 3.7.0 through 3.8.3) 
- Low Priority - Core - XSS vulnerability in Uri class (affecting Joomla 1.5.0 through 3.8.3) 
- Low Priority - Core - SQLi vulnerability in Hathor postinstall message (affecting Joomla 3.7.0 through 3.8.3)

根據更新,我們去到github上的joomla項目,從中尋找相應的修復補丁,可以發現,4個安全漏洞的是和3.8.4的release版同時更新的。

https://github.com/joomla/joomla-cms/commit/0ec372fdc6ad5ad63082636a0942b3ea39acc7b7

通過補丁配合漏洞詳情中的簡單描述我們可以確定漏洞的一部信息,緊接著通過這部分信息來回溯漏洞成因。

SQLi vulnerability in Hathor postinstall message

https://developer.joomla.org/security-centre/722-20180104-core-sqli-vulnerability.html

Description
The lack of type casting of a variable in SQL statement leads to a SQL injection vulnerability in the Hathor postinstall message.

Affected Installs
Joomla! CMS versions 3.7.0 through 3.8.3
補丁分析

第一個漏洞說的比較明白,是說在Hathor的postinstall信息處,由于錯誤的類型轉換導致了注入漏洞。

我們來看看相應的補丁

符合漏洞描述的點就是這里,原來的取第一位改為了對取出信息做強制類型轉換,然后拼接入sql語句。

這里假設我們可以控制$adminstyle,如果我們通過傳入數組的方式設置該變量為數組格式,并且第1個字符串可控,那么這里就是一個可以成立的漏洞點。

現在我們需要找到這個功能的位置,并且回溯變量判斷是否可控。

找到漏洞位置

hathor是joomla自帶的兩個后臺模板之一,由于hathor更新迭代沒有isis快,部分功能會缺失,所以在安裝完成之后,joomla的模板為isis,我們需要手動設置該部分。

Templates->styles->adminnistrator->hathor

修改完成后回到首頁,右邊就是postinstallation message

回溯漏洞

回到代碼中,我們需要找到$adminstyle這個變量進入的地方。

$adminstyle = $user->getParam('admin_style', ''); 

這里user為JFactory::getUser(),跟入getParam方法

/libraries/src/User/User.php line 318

public function getParam($key, $default = null)
{
    return $this->_params->get($key, $default);
}

這里$this->_params來自$this->_params = new Registry;

跟入Registry的get方法

libraries/vendor/joomla/registry/src/Registry.php line 201

public function get($path, $default = null)
    {
        // Return default value if path is empty
        if (empty($path))
        {
            return $default;
        }

        if (!strpos($path, $this->separator))
        {
            return (isset($this->data->$path) && $this->data->$path !== null && $this->data->$path !== '') ? $this->data->$path : $default;
        }

        // Explode the registry path into an array
        $nodes = explode($this->separator, trim($path));

        // Initialize the current node to be the registry root.
        $node = $this->data;
        $found = false;

        // Traverse the registry to find the correct node for the result.
        foreach ($nodes as $n)
        {
            if (is_array($node) && isset($node[$n]))
            {
                $node = $node[$n];
                $found = true;

                continue;
            }

            if (!isset($node->$n))
            {
                return $default;
            }

            $node = $node->$n;
            $found = true;
        }

        if (!$found || $node === null || $node === '')
        {
            return $default;
        }

        return $node;
    }

根據這里的調用方式來看,這里會通過這里的的判斷獲取是否存在adminstyle,如果沒有則會返回default(這里為空)

接著回溯$this->data,data來自$this->data = new \stdClass;

回溯到這里可以發現$admin_style的地方是從全局變量中中讀取的。

默認設置為空/administrator/components/com_users/models/forms/user.xml

但我們是可以設置這個的

后臺users->users->super user設置,右邊我們可以設置當前賬戶使用的后臺模板,將右邊修改為使用hathor型模板。

通過抓包我們可以發現,這里顯式的設置了當前賬戶的admin_type,這樣如果我們通過傳入數組,就可以設置admin_type為任意值

然后進入代碼中的數據庫操作 /administrator/templates/hathor/postinstall/hathormessage.php function hathormessage_postinstall_condition

訪問post_install頁面觸發

XSS vulnerability in com_fields

https://developer.joomla.org/security-centre/720-20180102-core-xss-vulnerability.html

Description
Inadequate input filtering in com_fields leads to a XSS vulnerability in multiple field types, i.e. list, radio and checkbox.

Affected Installs
Joomla! CMS versions 3.7.0 through 3.8.3
補丁分析

漏洞詳情寫了很多,反而是補丁比較模糊,我們可以大膽猜測下,當插入的字段類型為list、radio、checkbox多出的部分變量沒有經過轉義

首先我們需要先找到觸發點

后臺content->fields->new,然后設置type為radio,在鍵名處加入相應的payload

然后保存新建文章

成功觸發

漏洞分析

由于補丁修復的方式比較特殊,可以猜測是在某些部分調用時使用了textContent而不是nodeValue,在分析變量時以此為重點。

漏洞的出發點/administrator/components/com_fields/libraries/fieldslistplugin.php line 31

由于找不到該方法的調用點,所以我們從觸發漏洞的點分析流程。

編輯文章的上邊欄是通過administrator/components/com_content/views/article/tmp/edit.php line 99載入的

這里JLayoutHelper:render會進入/layouts/joomla/edit/params.php

然后在129行進入JLayoutHelper::render('joomla.edit.fieldset', $displayData);

跟入/layouts/joomla/edit/fieldset.php line 16,代碼在這里通過執行formgetFieldset獲取了提交的自定義字段信息。

跟入/libraries/src/Form/Form.php line 329 function getFieldset

跟如1683行 findFieldsByFieldset函數。

這里調用xml來獲取數據,從全局的xml變量中匹配。

這里的全局變量中的xml中的option字段就來自于設置時的$option->textContent,而只有list, radio and checkbox.這三種是通過這里的函數做處理,其中list比較特殊,在后面的處理過程中,list類型的自定義字段會在/libraries/cms/html/select.php line 742 function options被二次處理,但radio不會,所以漏洞存在。

整個xss漏洞從插入到觸發限制都比較大,實戰價值較低。

XSS vulnerability in Uri class

https://developer.joomla.org/security-centre/721-20180103-core-xss-vulnerability.html

Description
Inadequate input filtering in the Uri class (formerly JUri) leads to a XSS vulnerability.

Affected Installs
Joomla! CMS versions 1.5.0 through 3.8.3
補丁分析

比起其他幾個來說,這里的漏洞就屬于特別清晰的,就是在獲取系統變量時,沒做相應的過濾。

前臺觸發方式特別簡單,因為這里的script_name是獲取基礎url路徑的,會拼接進所有頁面的和鏈接有關系的地方,包括js或者css的引入。

漏洞利用

讓我們來看看完整的代碼

if (strpos(php_sapi_name(), 'cgi') !== false && !ini_get('cgi.fix_pathinfo') && !empty($_SERVER['REQUEST_URI']))
{
    // PHP-CGI on Apache with "cgi.fix_pathinfo = 0"

    // We shouldn't have user-supplied PATH_INFO in PHP_SELF in this case
    // because PHP will not work with PATH_INFO at all.
    $script_name = $_SERVER['PHP_SELF'];
}
else
{
    // Others
    $script_name = $_SERVER['SCRIPT_NAME'];
}

static::$base['path'] = rtrim(dirname($script_name), '/\\');

很明顯只有當$script_name = $_SERVER['PHP_SELF']的時候,漏洞才有可能成立

只有當php是fastcgi運行,而且cgi.fix_pathinfo = 0時才能進入這個判斷,然后利用漏洞還有一個條件,就是服務端對路徑的解析存在問題才行。

http://127.0.0.1/index.php/{evil_code}/321321

--->

http://127.0.0.1/index.php

當該路徑能被正常解析時,http://127.0.0.1/index.php/{evil_code}就會被錯誤的設置為基礎URL拼接入頁面中。

一個無限制的xss就成立了

XSS vulnerability in module chromes

https://developer.joomla.org/security-centre/718-20180101-core-xss-vulnerability.html

Description
Lack of escaping in the module chromes leads to XSS vulnerabilities in the module system.

Affected Installs
Joomla! CMS versions 3.0.0 through 3.8.3
補丁分析

漏洞存在的點比較清楚,修復中將$moduleTag進行了一次轉義,同樣的地方有三處,但都是同一個變量導致的。

這個觸發也比較簡單,當我們把前臺模板設置為protostar(默認)時,訪問前臺就會觸發這里的modChrome_well函數。

漏洞利用

讓我們看看完整的代碼

很明顯后面module_tag沒有經過更多處理,就輸出了,假設我們可控module_tag,那么漏洞就成立。

問題在于怎么控制,這里的函數找不到調用的地方,能觸發的地方都返回了傳入的第二個值,猜測和上面的get_param一樣,如果沒有設置該變量,則返回default值。

經過一番研究,并沒有找到可控的設置的點,這里只能暫時放棄。

ref


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/529/