Показать сообщение отдельно

  #1  
Старый 14.12.2013, 21:04
eclipse
Участник форума
Регистрация: 19.12.2010
Сообщений: 155
С нами: 8103926

Репутация: 85
По умолчанию

Оригинальная статья написана EgiX (c) Karma(In)Security

February 27, 2013


Анализ уязвимости PHP Object injection в Joomla.

Сегодня я раскрыл информацию об уязвиомтси вида PHP Object injection в CMS Joomla (KIS-2013-03 ).

Всего лишь несколько месяцев прошло с тех пор как я сообщил о ней в Joomla Security Strike Team,

но если быть честным я обратил внимание на уязвимую функцию unserialize() давно до этого.

Единственная причина по которой я не оповестил их ранее - это мое отношение к данной уязвимости как к непригодной для использования:

я не знал о каких-либо "волшебных" методах которые можно было бы использовать для осуществления зловредной атаки, поэтому я пришел к выводу,

что данная уязвимость собственно говоря, не является реальной уязвимостью.

Некоторое время спустя, после выхода Joomla 3.0, мне пришло в голову посмотреть еще раз в исходный код Joomla,

чтобы проверить появились-ли новые "волшебные" методы.

По сравнению с Joomla 2.5 я не нашел использования каких-либо новых "волшебных" методов PHP, но я заметил маленькое изменение

в классе деструктора метода которое явилось для меня ключевым моментом, чтобы понять что уязвимость на самом деле существует и

может быть использования через данный (и не только) "волшебный" метод. Я говорю о методе деструктора класса plgSystemDebug,

который в Joomla 2.5 начинается вот так:

Код:
74:| public function __destruct()
75:| {
76:|    // Do not render if debugging or language debug is not enabled
77:|   if (!JDEBUG && !JFactory::getApplication()->getCfg('debug_lang'))
78:|    {
79:|       return;
80:|    }
Когда в Joomla 3.0 он был изменен на:

Код:
84:| public function __destruct()
85:| {
86:|    // Do not render if debugging or language debug is not enabled
87:|   if (!JDEBUG && !$this->debugLang)
88:|    {
89:|        return;
90:|    }
В конфигурации по умолчанию плагин System Debug активирован, но опции Debug System и Debug Language выключены.

Это значит, что при проведении атаки в Joomla 2.5 этот метод может быть использован только тогда,

когда одна или обе из вышеназванных опций будут включены,

тогда как в Joomla 3.0, из-за проверки значения свойства объекта debugLang, он может быть благополучно использован с конфигурацией по умолчанию.

Взглянув на метод plgSystemDebug::__destruct может показаться что в он никак не пригоден для осуществления зловредной атаки,

но есть такая строка кода с вызовом метода get объекта хранимого в свойстве params:

Код:
$filterGroups = (array) $this->params->get('filter_groups', null);
Это свойство - член класса JPlugin и по идее должен быть объектом JRegistry содержащим в себе параметры пллагина.

Однако злоумышленник может присвоить свойству params произвольный PHP объект, так что я стал искать get методы и нашел два различных

вектора проведения атак.

Удаление произвольной директории

Первый вектор атаки позволяет злоумышленнику удалить произвольную директорию для которого у web-сервера есть соответствующие права.

Это возможно в результате злоупотребление двумя различными методами, первый из них - JInput::get:

Код:
157:| public function get($name, $default = null, $filter = 'cmd')
158:| {
159:|    if(isset($this->data[$name]))
160:|    {
161:|        return $this->filter->clean($this->data[$name], $filter);
162:|    }
В строке 161 вызывается метод clean объекта хранимого в свойстве filter, предпологается что это объект JFilterInput.

Но как уже объяснялось ранее, данному свойству может быть присвоен произвольный PHP объект, что привело к том что я стал искать

полезные clean методы. В результате я нашел метод JCacheStorageFile:clean:

Код:
182:| public function clean($group, $mode = null)
183:| {
184:|    $return = true;
185:|    $folder = $group;
186:| 
187:|   if (trim($folder) == '')
188:|    {
189:|        $mode = 'notgroup';
190:|    }
191:|     
192:|    switch ($mode)
193:|    {
194:|        case 'notgroup';:
195:|            $folders = $this->_folders($this->_root);
196:|            for ($i = 0, $n = count($folders); $i _deleteFolder($this->_root . '/' . $folders[$i]);
201:|                }
202:|            }
203:|            break;
204:|        case 'group':
205:|        default: 
206:|           if (is_dir($this->_root . '/' . $folder))
207:|            {
208:|                $return = $this->_deleteFolder($this->_root . '/' . $folder);
209:|            }
Если переменной $mode будет присвоено значение "cmd", оператор switch передаст управление условию по умолчанию, на строку 192,

тогда, в строке 208 будет вызван метод JCacheStorageFile::_deleteFolder и как подсказывает имя, этот метод будет пытаться

провести рекурсивное удалени директории. Из-за возможности использования относительных адресов,

для того, чтобы удалить директорию у атакующего злоумышленниа даже нет необходимости в знании абсолютного пути,

например он может привсвоить свойству _root инъекцированного объекта JCacheStorageFile, значение "./", и попытаться удалить корневой

каталог Joomla, что может вылиться в ошибку отказа от сервиса (DoS).

Слепая SQL инъекция

Второй вектор атаки позволяет злоумышленнику провести SQL injection. Это становится возможным злоупотребив методом get класса JCategories:

Код:
166:| public function get($id = 'root', $forceload = false)
167:| {
168:|   if ($id !== 'root')
169:|    {
170:|        $id = (int) $id;
171:| 
172:|       if ($id == 0)
173:|        {
174:|            $id = 'root';
175:|        }
176:|    }
177:| 
178:|    // If this $id has not been processed yet, execute the _load method
179:|   if ((!isset($this->_nodes[$id]) && !isset($this->_checkedCategories[$id])) || $forceload)
180:|    {
181:|        $this->_load($id);
182:|    }
На строке 181 вызывается метод JCategories::_load, который по идее должен получить указанную категорию из хранимой на сервере базы данных.

Внутри метода можно использовать произвольные SQL команды через различные свойства объекта, такие как _table,_field,_key и _statefield.

Еще...

Как я упомянал в начале данной статьи, метод plgSystemDebug::__destruct не является единственным "волшебным" методом который может

быть использован для эксплуатации уязвимости. Есть еще один "волшебный" метод добавленный в Joomla 3.0 с его __toString методом класса

JViewHtml, вызывающий метод JViewHtml::render:

Код:
135:| public function render()
136:| {
137:|     // Get the layout path.
138:|     $path = $this->getPath($this->getLayout());
139:|  
140:|     // Check if the layout path was found.
141:|    if (!$path)
142:|     {
143:|         throw new RuntimeException('Layout Path Not Found');
144:|     }
145:|  
146:|     // Start an output buffer.
147:|     ob_start();
148:|  
149:|     // Load the layout.
150:|     include $path;
Метод JViewHtml::getPath может возвращать строку которая будет полностью подконтрольна атакующему злоумышленнику, это может повлечь

за собой проведение атаки вида PHP File Inclusion на строке 150. Однако, JViewHtml

является абстрактным классом который по идее должен быть использован сторонними

расширениями, значит данный вектор атаки может быть проведен только в случае если

в атакуемой системе Joomla установлено расширение использующее класс наследующий JViewHtml.

Как бы там ни было, этот интересный кусок кода оказался для меня подсказкой к пониманию

что на ряду с вышеописанными могут быть использованы и другие "волшебные" методы описываемые сторонних расширений.

Это возможно благодаря уязвимости unserialize() вызываемой в методе onAfterDispatch который срабатывается когда Joomla перехватывает

запрос и адресует его компонентам, так что все классы выбранного компонента декларируются при срабатывании метода. Это значит,

что возможны другие векторы атак с использованием "волшебных" методов сторонних расширений.

 
Ответить с цитированием