Плохая логика. Выполняем произвольный код в популярном сервере приложений Oracle WebLogic

Новая уязвимость в Oracle WebLogic позволяет выполнять произвольные команды на целевой системе любому атакующему без какой-либо авторизации. Разберемся, что именно должен делать атакующий и почему это работает.

Сервер приложений WebLogic, как и большинство продуктов Oracle, широко распространен в энтерпрайз-среде и используется крупными компаниями по всему миру. Проблемы, подобные этой, могут грозить огромными убытками и повлечь за собой утечки приватных данных.

Продукты компании PeopleSoft, производящей ПО для управления базами клиентов, финансового планирования и управления персоналом, тоже подвержены этой уязвимости, поскольку один из компонентов — это сервер WebLogic.

Проблема заключается в некорректной фильтрации данных при парсинге пользовательского запроса в XML перед передачей его в XMLDecoder. Отвечает за это модуль WLS Security. Уязвимость получила номер CVE-2017-10271 — это логическое продолжение не до конца запатченной CVE-2017-3506 в модуле Web Services. Баг затрагивает версии WebLogic до 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 и 12.2.1.2.0.

Подготовка

Сначала поднимем и настроим наш первый в 2018 году стенд для тестирования уязвимости. Я сижу на винде и поэтому буду использовать win-версию сервера WebLogic.

Для того чтобы загрузить сам дистрибутив, тебе понадобится рабочий аккаунт Oracle. Если у тебя его нет, то можешь зарегистрироваться тут. Далее переходим в раздел загрузок, принимаем лицензионное соглашение и выбираем нужную версию дистрибутива для загрузки.

Рекомендую использовать ветку 10.3.6, так как там сразу работает уязвимый модуль. Windows Oracle WebLogic распространяется в виде инсталлятора, в котором уже имеется JDK, ведь дистрибутив написан на Java и требует Development Kit для работы.

Инсталлятор WebLogic 10.3.6.0.0

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

Компоненты JDK в инсталляторе

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

Стартовая страница WebLogic

Если ты используешь Linux, то рекомендую поднять окружение через Docker, благо в репозитории ты уже можешь найти готовые сборки WebLogic. Вот, например, одна из них.

Детали

Давай сразу же проверим работу эксплоита. Загрузить один из вариантов PoC можно отсюда.

Для корректной работы в качестве параметра нужно указать адрес сервера WebLogic. По умолчанию скрипт отправляет запрос с эксплоитом к роуту /wls-wsat/CoordinatorPortType.

CVE-2017-10271/exploit.py
54:     url_in = sys.argv[1]
55: do_post(url_in, command_in)
CVE-2017-10271/exploit.py
42: def do_post(url_in, command_in):
43:     payload_url = url_in + "/wls-wsat/CoordinatorPortType"

После запуска PoC будет предложено ввести команду, которую нужно выполнить на удаленной системе.

CVE-2017-10271/exploit.py
53:     command_in = raw_input("Enter your command here: ")
Успешная эксплуатация CVE-2017-10271 в Oracle WebLogic

Поскольку это логическое продолжение уязвимости CVE-2017-3506, сначала взглянем, что делает патч, который Oracle выпустила для нее. Нужные нам файлы находятся в файле /lib/weblogic.jar, поэтому его надо декомпильнуть, например с помощью Java Decompiler.

Декомпиляция weblogic.jar в Java Decompiler GUI

Нас интересует файл WorkContextXmlInputAdapter.java. Вместе с апрельским патчем разработчики добавили метод validate.

WorkContextXmlInputAdapter.java
21: public final class WorkContextXmlInputAdapter
22:   implements WorkContextInput
23: {
24:   private final XMLDecoder xmlDecoder;
25:
26:   public WorkContextXmlInputAdapter(InputStream is)
...
47:   private void validate(InputStream is)
48:   {
49:     WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
50:     try
51:     {
52:       SAXParser parser = factory.newSAXParser();
53:       parser.parse(is, new DefaultHandler()
54:       {
55:         public void startElement(String uri, String localName, String qName, Attributes attributes)
56:           throws SAXException
57:         {
58:           if (qName.equalsIgnoreCase("object")) {
59:             throw new IllegalStateException("Invalid context type: object");
60:           }
61:         }
62:       });
63:     }

Он проверяет переданный XML-запрос на наличие элементов Object, и если такой встречается, то скрипт кидает исключение Invalid context type: object.

Однако не Object’ом единым живет RCE. Существует еще множество способов проэксплуатировать уязвимость в десериализации XML. Посмотрим на этот же файл, но уже из последней версии, где уязвимость исправлена.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


aLLy: @iamsecurity Специалист по информационной безопасности в ONsec. Research, ethical hacking and Photoshop.