
Эксплойт для удаленного выполнения кода без аутентификации для Oracle WebLogic ADF Faces (CVE-2022-21445, CVSS 9.8). Включает подробные инструкции по настройке окружения, генерации полезной нагрузки и удаленной отладке для тестирования на проникновение.
CVE-2022-21445 (оценка CVSS 9,8) — это уязвимость, связанная с ненадёжной десериализацией данных, обнаруженная в компоненте ADF Faces, которая может быть удалённо эксплуатирована злоумышленниками без аутентификации (pre-authentication) для выполнения RCE.
Уязвимость была обнаружена двумя экспертами по кибербезопасности: PeterJson из VNG Corporation и Nguyen Jang из VNPT. Oracle получила этот отчёт в октябре 2021 года, и потребовалось целых 6 месяцев, то есть до апреля 2022 года, чтобы выпустить исправление.
В данной статье эксплуатация сосредоточена на Oracle Business Intelligence версии 12.2.1.4.0
Условия: Установите Windows 10+ Pro или Windows Home (x64) с активированной лицензией, либо используйте Windows Server (предпочтительно продукт от Oracle).
Шаг 1: Установите Java, версию JDK 8u112 или выше (8Ux), ссылка для скачивания: JDKv8U112

Шаг 2: Установите Oracle Database 19c, ссылка для скачивания: Oracle 19c
Подготовьте папку для установки базы данных, создайте путь, как указано ниже, и распакуйте только что загруженный zip-файл базы данных в C:\app\oracle\product\19c\db_home1
Запустите файл setup.application от имени администратора

Выполните шаг за шагом в соответствии с инструкцией в Руководство по установке БД
Обратите особое внимание:
На шаге 8/17 обязательно отметьте Create as Container database, чтобы создать подключаемую БД для процесса установки Fusion Middleware, который последует далее.

На шаге 9/17 выберите кодировку Unicode (AL32UTF8)



Шаг 3: Установите SQL Developer, версия no-jre, ссылка для скачивания: SQLDev-NoJRE

Запустите файл sqldeveloper.application от имени администратора

Настройте параметры нового подключения, как показано на рисунке ниже, обратите внимание на изменение имени пользователя и пароля (как в примере выше — hr), имени хоста (по умолчанию localhost), порта (по умолчанию 1521), SID (глобальное имя базы данных, установленной на шаге 2)

Если при нажатии Test появляется сообщение Success, значит подключение установлено успешно, нажмите Connect
Шаг 4: Установите Fusion Middleware Infrastructure (FMW) версии 12.2.1.3.0, ссылка для скачивания FMW_ver_12.2.1.3.0

Шаг 5: Установите Oracle Business Intelligence (OBIEE) версии 12.2.1.4.0, ссылка для скачивания: OBIEE_ver_12.2.1.4.0
Запустите файл setup_bi_platform-12.2.1.4.0_win64.exe от имени администратора

Установите пошагово согласно Руководство по установке OBIEE
Обратите внимание: путь к BI должен совпадать с путём, по которому был установлен FMW, то есть Oracle/Middleware/Oracle_Home

Шаг 6: Настройте схему BI с помощью утилиты Repository Creation Utility (RCU)
По пути C:\Oracle\Middleware\Oracle_Home\oracle_common\bin запустите файл rcu.bat от имени администратора
Выполните последовательно следующие шаги




Шаг 7: Настройте переменные среды для OBIEE

Шаг 8: Создайте домен BI





На шаге 4 система сообщает fail to logon — проверьте правильность пароля домена
На шаге 8, если система выводит ошибку, как на рисунке ниже, проверьте, активирована ли у вас лицензия Windows и соответствует ли ваша Windows условиям, описанным в разделе.
![]()
Шаг 9: После завершения настройки перейдите в только что созданный домен BI по пути $Oracle_Home\user_projects\domains\bi\servers\AdminServer\tmp_WL_user\adf.oracle.domain.webapp\i83uao
Скопируйте все jar-файлы отсюда в отдельную папку и передайте их на атакующую машину (в лабораторной среде делаем так; при реальной атаке на атакующей машине также необходимо установить среду, как на целевой, чтобы получить исходный код).
Также добавьте библиотеку coherence.jar из пути $Oracle_Home\coherence\lib в эту папку.
Это критически важная папка, от которой зависит успешность полезной нагрузки, поскольку версии FMW, BI и среда на каждой машине могут отличаться, и необходимо точно подобрать версию, чтобы избежать рисков или появления исключений при передаче полезной нагрузки.
Шаг 10 (выполнять только если требуется удалённая отладка; ещё раз: при тестировании в реальной среде невозможно настроить машину жертвы по своему усмотрению, поэтому атакующему необходимо выполнить настройку целевой машины на своей стороне для удалённой отладки и проверки ошибок)
Установите Mozilla, добавьте Burp Proxy с портом 8181
Включите удалённую отладку на стороне BI-сервера
Перейдите на localhost:9500/console
В Domain Structure -> выберите bi -> Environment -> Servers

Отобразятся два сервера: AdminServer (WebLogic) и bi_server1 (BI)
Изображение 10.2: Отображаемый список серверов
Нажмите Lock & Edit в левом нижнем углу, отметьте bi_server1 для изменения конфигурации. Затем перейдите в Configuration -> Server start -> Прокрутите вниз до конца, выберите Advance (если есть) -> Нажмите для ввода в Arguments -> Введите параметры отладки:
-Xdebug -Xnoagent – Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n
(можно попробовать с 0.0.0.0:5005, если впоследствии возникнет ошибка при перезапуске bi_server1)
Введите пароль WebLogic (установленный ранее при настройке домена BI) -> Apply change & Restart
Запустите терминал Administrator -> Перейдите по пути $Oracle_Home\user_projects\domains\bi\bitools\bin выполните ./stop.cmd и ./start.cmd для перезапуска bi_server1; если в процессе перезапуска не возникнет ошибок, отладка будет включена и будет прослушивать порт 5005, как указано выше. Если возникнут ошибки, проверьте параметры отладки выше на наличие лишних пробелов или ошибок в части address.
Шаг 1: Загрузите IntelliJ IDEA Ultimate, активируйте кодом, найденным на GitHub.
Шаг 2 (Выполняйте этот шаг только если в процессе атаки появляются ошибки, такие как 500 Server Error, ..., что связано с исключениями в полезной нагрузке)
Измените версию JDK/SDK проекта на ту же, что и на целевой машине (способ установки см. в разделе Целевая машина - Шаг 1)
Создайте пустой проект для анализа исходного кода и удалённой отладки.
Добавьте все jar-файлы из папки, полученной от целевой машины, в этот проект.
Project Structure -> Modules -> Нажмите + -> 1 JARS or Directories -> Добавьте всю папку jar.


Настройте удалённую отладку
Run -> Edit Configurations -> + -> Remote JVM Debug

Запустите удалённую отладку; если в консоли появится сообщение: Connected …, значит всё успешно.

Шаг 3:
Клонируйте код из этого репозитория на свою машину, удалите старый файл coherence.jar в папке lib и замените его файлом, полученным от целевой машины на предыдущем шаге.
Затем добавьте его в проект, запустив его в IntelliJ, добавьте jar-файлы из lib с опцией Add as library
Проверьте имя класса LambdaIdentity$.... на соответствие версии WebLogic; если есть изменения, выполните рефакторинг файла и измените имя этого файла.
Weblogic 12.2.1.3: LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A
Weblogic 12.2.1.4: LambdaIdentity$423B02C050017B24DB10DFF759AA56BF
Отредактируйте путь к файлу LambdaIdentity$....class в файле Main.java. Чтобы получить точный путь, есть два способа: можно запустить javac для jar-файла, чтобы он сгенерировал файл .class; другой вариант — закомментировать код функции main, затем запустить проект обычным образом, путь к файлу класса можно найти в папке target.
Проверьте, чтобы JDK и SDK проекта совпадали с теми, что на целевой машине.
Мы видим файл web.xml, в котором описаны отношения маппинга, связанные с servlet-mapping. "resources" — это сервлет, связанный с системными ресурсами, содержащими важные данные и информацию, поэтому это место часто является целью атакующих.






Анализ функции findResource() в RemoteApplicationResourceLoader.class

Эта функция возвращает метод, содержащий пользовательский протокол RAStreamHandler(). RAStreamHandler создаёт объект URLConnection со значением new RAURLConnection

Функция RAURLConnection вызывает функцию _getPathBean

Функция _getPathBean содержит объект bean, созданный вызовом функции getInstanceFromString(), которая обрабатывает входную строку для извлечения соответствующих ключей (фильтр).

Входная строка bean преобразуется через класс SerializationUtils из URL-кодированного вида в объект URLEncoderPathBean. Если всё в порядке, последующие входные данные продолжают передаваться в функцию fromURLEncodeString().


Если во входной строке возникает ошибка, выбрасывается исключение. Исключения в основном связаны с библиотекой, используемой в полезной нагрузке, из-за несовпадения версий или неправильного пути к файлу Lambda.
В функции fromURLEncodedString() возвращается функция fromString с параметром url, и её код выглядит следующим образом:

В функции fromString данные читаются через readObject() и возвращаются. Видно, что входные данные не фильтруются, проходят через множество функций и в конечном итоге десериализуются в fromString(). Это и есть точка (sink) для эксплуатации. Раз sink найден, теперь нужно найти источник (source).
Поэтому для вызова вышеупомянутого класса нам нужно регулярное выражение вида “/.*/remote/(.*)”. Следовательно, когда маршрут или входной путь имеет вид /em/afr/foo/remote/payload, он будет соответствовать структуре, заданной в этом файле, и тогда RemoteApplicationResourceLoader будет использоваться в качестве загрузчика в doGet, а соответствующий файл класса oracle.adfinternal.view.resource.rich.RemoteApplicationResourceLoader вызовет переопределенный метод findResource(). Поэтому, если полезная нагрузка передана на правильный адрес, данные будут передаваться легко, минуя фильтр.
Это конечный URL, используемый для эксплуатации:
__hostname:port/contextApp/afr/foo/remote/payload/__
Где contextApp — это один из путей, которые появляются после установки OBIEE, например /em; /bicomposer; ….
Foo — произвольная строка.
Payload — строка, сгенерированная при выполнении функции Main подготовленного проекта атаки.
### Анализ кода, используемого для создания полезной нагрузки
Этот проект следует цепочке гаджетов CVE-2020-14644

Класс LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A наследуется от AbstractRemotable и используется для взаимодействия с удаленной системой.
Используя Java Reflection API, атакующий может легко получить WorkAdapter из текущего потока выполнения.
Затем будет получено поле connectionHandler из WorkAdapter и выполнен запрос для получения ServletRequest и ServletResponse из connectionHandler.
Затем извлекается значение заголовка "cmd" из запроса (ServletRequest), после чего проверяется, не пусто ли значение "cmd", и выполняется соответствующая команда shell для текущей операционной системы (Windows или Linux/Unix).
Результат команды shell считывается и отправляется обратно в ответе (ServletResponse).
Если в процессе выполнения возникает какая-либо ошибка, она выводится на консоль через метод printStackTrace().
Id после имени класса LamdaIdentity зависит от версии сервера WebLogic, это строка, закодированная по MD5-хешу класса com.tangosol.internal.util.invoke.ClassIdentity, и поскольку этот класс различается в разных версиях, как уже было сказано, чтобы полезная нагрузка не вызывала ошибок, необходимо тщательно это проверить.
Здесь переменная cmd извлекается из заголовка входящего запроса, затем добавляется в команду Runtime.getRuntime().exec() ниже, кодируется и декодируется в виде MD5-шестнадцатеричного кода, и после передачи в систему OBIEE возвращает десериализованное значение.
Наконец, в функции Main создается объект RemoteConstructor, который через библиотеку SerializationUtils преобразуется в строку URL-encoded. Эта строка напрямую передается в URL-источник, предоставляя атакующему возможность вставить произвольную команду __cmd__.

## Воспроизведение эксплуатации


## Ссылки
1. https://peterjson.medium.com/miracle-one-vulnerability-to-rule-them-all-c3aed9edeea2
2. https://testbnull.medium.com/oracle-access-manager-pre-auth-rce-cve-2021-35587-analysis-1302a4542316
## Автор уязвимости: Jang Nguyen и Duc PeterJson