Joomla! 3.7 Core SQL Injection (CVE-2017-8917)

ID SSV:93113
Type seebug
Reporter Root
Modified 2017-05-18T00:00:00


Author: p0wd3r (know Chong Yu 404 security lab)

Date: 2017-05-18

0x00 vulnerability overview

Vulnerability description

Joomla to 5 on 17 May released the new version 3. 7. 1, and this update fixes a high risk SQL injection vulnerability <>, the successful exploitation of the vulnerability an attacker can unauthorized for SQL injection.


Unauthorized state of SQL injection

Affects versions: 3.7.0

0x01 vulnerability reproduction

Joomla in 3.7.0 added a new com_fieldAssembly, which controls the controller's constructor as follows, in components/com_fields/controller.phpin:

You can see when access to the view's fields, the layoutis modal, the program will be from JPATH_ADMINISTRATORloaded com_fields, which means that the ordinary user can through this a request to use the Administrator's com_fieldsit.

Next, we custody of the administrator of the com_fieldsAssembly, we came to administrator/components/com_fields/models/fields.php, wherein the getListQuerythe part of the code is as follows:

Program by$this-&gt;getStatetaken to the list. fullordering, and then use$db-&gt;escapeprocessing after the incoming$query-&gt;orderfunction, mysqli's escapefunction code is as follows:

Here call mysqli_real_escape_stringto escape characters, the function specific action is as follows:

Only the single and double quotes and other characters to be escaped, and not do more filtering. In addition$query-&gt;orderfunction of the role is only the data spliced to the ORDER BYstatement, it is not filtered, so if the list. fullorderingcontrollable, then it can be injected.

We can see the list. fullorderingis a state, the statewill be in the view displayfunction settings:

Follow this setup process, the program will go to libraries/legacy/model/list.phpin the populateStatefunction, the specific call stack is as follows:

This function has the next code:

``php 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-&gt;setState('list.' . $name, $value);

} ``

Program through$app-&gt;getUserStateFromRequestget to a$listarray, if the array key is not in the blacklist, then traverse the array to the corresponding stateregister getUserStateFromRequestthe code is as follows:

The combination of the previous call, we can through the request parameter listto set the$listvariable, thus we access http://ip/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml(2,concat(0x7e,(version())),0)and turn on dynamic debugging dynamic debugging, the results are as follows:

You can see the list. fullorderinghas been our control.

Back to the getListQueryfunction, the function will be in view when loaded are automatically called, the specific function the call stack is as follows:

So our payload will by getStateis passed to this function, ultimately leading to SQL injection:

0x02 patch analysis

To take the list. orderingand list. directionas a query parameter, this two parameters in the populateStatefunction to do the following treatment:

If the value is not within the specified range then change it to the default value, so no longer will the payload into.

0x03 reference