Author：LoRexxar'@Knownsec 404 Team
Date: Feburary 7, 2018
Chinese Version: https://paper.seebug.org/529/

On January 30, 2018, Joomla updated version 3.8.4. This update fixes 4 security vulnerabilities and hundreds of bug.

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

For the vulnerability emergency, I spent a lot of time analyzing the causes, finding the location and backtracking the logic of these vulnerabilities. The following article is rather my thinking than analysis and I hope it may give you some inspiration.

Background

Four of these security vulnerabilities include

- 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)

According to the update, I went to the Joomla project on github and looked for the corresponding fix. The four security vulnerabilities were updated at the same time as the release version of 3.8.4.

We can know about the vulnerability through the simple description in the patch and the details. Then we can use the information to trace back the cause of the vulnerability.

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
Analysis of the Patch

The first vulnerability shows that in the postinstall of Hathor, the injection is caused by the incorrect type conversion.

Let's take a look at the corresponding patch.

The point that matches the description of the vulnerability is here. Taking the first bit has been changed to forcing type conversion, and then be spliced into the sql statement.

We assume that we can control $adminstyle. If we set its format to array by passing in an array, and its first string is controllable, then this can cause vulnerability. Now we need to find the location of this function, backtrack the variable and judge whether it is controllable. Find the Location of the Vulnerability Hathor is one of the two background templates that comes with Joomla. Since Hathor's update iteration is not as fast as Isis's, some functions will be missing. So after the installation, we need to set the template as Isis manually. Templates->styles->adminnistrator->hathor Go back to the home page and the postinstallation message is on the right. Backtracking Back in the code, we need to find the place where the $$adminstyle variable enters. $adminstyle = $user->getParam('admin_style', '');  Here the user is JFactory::getUser(). Follow up the getParam method. /libraries/src/User/User.php line 318 public function getParam($key, $default = null) { return$this->_params->get($key,$default);
}

The $this->_params is from $this->_params = new Registry;

Follow up the 'get' method of Registry.

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;
}

According to the calling method, the program will determine whether there is adminstyle through the judgment , if not, it will return default (empty).

Then it backtracks $this->data. The 'data' is from $this->data = new \stdClass;

You can see that $admin_style is read from the global variable. The default setting is empty /administrator/components/com_users/models/forms/user.xml But we can set this up. Operate users->users->super user in the backgrond to go to the settings. On the right we can set the background template. Set to use the Hathor type template. By catching the package, we can see that the current account's admin_type is explicitly set. This means we can set admin_type to any value by passing an array. Then enter the database operation. /administrator/templates/hathor/postinstall/hathormessage.php function hathormessage_postinstall_condition. Visite post_install page and trigger it. XSS vulnerability in com_fields 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 Patch Analysis There is enough details of the vulnerability, but the patch is rather vague. We could guess that when the inserted field type is list, radio, checkbox, some of the variables are not escaped. First we need to find the trigger point. Operate content->fields->new in the background , set the type to radio, add the corresponding payload at the key name. And keep this article. Then we can achieve the triggering. Vulnerability Analysis Because the patch was fixed in a special way, we could guess that the textContent is used instead of nodeValue when calling. We should focus on it when analyzing variables. The starting point of the vulnerability is /administrator/components/com_fields/libraries/fieldslistplugin.php line 31 Since we could not find where this method is called, we could analyse the process through these triggers. The upper side of the edit article is loaded via administrator/components/com_content/views/article/tmp/edit.php line 99. The JLayoutHelper:render will enter /layouts/joomla/edit/params.php. And it will enter JLayoutHelper::render('joomla.edit.fieldset',$displayData); in line 129.

Follow up the/layouts/joomla/edit/fieldset.php line 16. The code gets the submitted custom field information by executing the getFieldset of the form.

Follow up the /libraries/src/Form/Form.php line 329 function getFieldset.

Follow up the findFieldsByFieldset function in line 1683.

Here the program calls xml to get the data, matching it from the global xml variable.

The option field in the global variable xml comes from the $option->textContent at the time of setting, and only the list, radio and checkbox. types will be processed by this function. The list type is special. In the following processing, the custom field of the list type will be processed twice in /libraries/cms/html/select.php line 742 function options, but the radio type will not, so the vulnerability exists. Since the entire xss vulnerability goes through lots of limitations from insertion to triggering, it is not practical enough. 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 Patch Analysis Compared to others, this vulnerability is simply not making filtering when obtaining the system variables. The front-end triggering method is simple, because the script_name is the path to get the basic url and it will be spliced into all places related to the link, including the introduction of js or css. Exploiting Let's take a look at the complete code. 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), '/\\');

Obviously, only when $script_name =$_SERVER['PHP_SELF']， the vulnerability is possible to exist.

Only when php is run by fastcgi, and cgi.fix_pathinfo = 0 can we enter this judgment. And when the server has a problem with the resolution of the path can we exploit the vulnerability.

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

--->

http://127.0.0.1/index.php

When the path can be parsed normally, http://127.0.0.1/index.php/{evil_code} will be incorrectly set to the base URL and spliced into the page.

An unrestricted xss is set up.

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
Patch Analysis

What is clear about the vulnerability is that \$moduleTag is escaped during repairing. This happened 3 times, but they were all caused by the same variable.

This trigger is also simple. When we set the foreground template to protostar (the default), accessing the foreground will trigger the modChrome_well function.

Exploiting

Let's take a look at the complete code.

Obviously, the module_tag is output without further processing. If we can control module_tag, then the vulnerability.

The problem is how to control it. In function, places that can be triggered returns the second value passed in. I guess it is the same as get_param above. If the variable is not set, return default value.

But I still did not find a good way to handle this, and I can only stop here temporarily.