Новоразкрит проблем в Apache Log4j2 би могъл да позволи на атакуващите да заобиколят списък с разрешени класове (allowlist) за десериализация и да изпълнят отдалечен код в строго дефинирани внедрявания.
Проблемът, проследяван като Log4j2 #4255, засяга приложения, които приемат сериализирани Log4j събития през достъпен по мрежата път за десериализация на Java.
Докладваната слабост е свързана с FilteredObjectInputStream в Log4j – помощен инструмент, проектиран да ограничава кои Java класове могат да бъдат зареждани по време на четене на сериализирани регистрационни събития. Неговият списък с разрешени класове включва java.rmi.MarshalledObject – Java контейнер, който може да съхранява друг сериализиран обект като непрозрачен масив от байтове.
Изследователите откриха, че този външен обект може да премине през списъка с разрешени класове на Log4j, докато прикрива злонамерен вътрешен обект. Когато по-късно Log4j извика MarshalledObject.get(), Java десериализира вградения злонамерен код, използвайки нов, нефилтриран ObjectInputStream. Това означава, че първоначалният списък с разрешени класове не инспектира скритата графа от обекти.
Нова уязвимост в Apache Log4j2
Уязвимият поток е свързан с Log4jLogEvent$LogEventProxy, който представлява сериализираното представяне на събитие от Log4j. Проксито поставя съобщението за събитието в MarshalledObject и го извлича автоматично по време на десериализацията.
Атакуващият би могъл да създаде специално подготвено злонамерено сериализирано Log4j събитие, да го изпрати на уязвим приемник и да предизвика изпълнението на налична в целевия classpath верига от джаджи (gadget chain).
Потребителят Dinosn докладва за Log4j2 #4255 в GitHub, където публична лаборатория за възпроизвеждане демонстрира проблема в Log4j версия 2.26.1, работеща върху JDK 17. В тестовата среда злонамерен код, вграден в MarshalledObject, е задействал изпълнение на код при обработка от неавтентифициран TCP приемник, използващ FilteredObjectInputStream.
Лабораторията показва също, че верига от джаджи в Commons Collections 3.2.1 може да бъде изпълнена, без да се изисква предоставен от атакуващия клас в компрометираната система. Въпреки това, този проблем не може да се сравни с широко разпространената уязвимост Log4Shell. Той не може да бъде задействан просто чрез поставяне на злонамерен низ в регистрационно съобщение на приложението.
Експлоатацията изисква специфична и рядко срещана конфигурация: приложението трябва да разполага с приемник, който приема контролирани от атакуващия сериализирани Log4j събития, обработва ги с помощта на FilteredObjectInputStream и съдържа използваема верига от Java десериализационни джаджи.
Указанията за сигурност от Apache подчертават, че текущият производствен код на Log4j Core обикновено не десериализира данни, получени от сокети, опашки или други външни източници.
Проектът описва FilteredObjectInputStream като инструмент за ешелонирана защита, а не като пълна граница на сигурността. Той предупреждава, че приложенията не трябва да десериализират потоци от несигурни регистрационни събития.
Организациите трябва да идентифицират наследени приемници на сериализирани Log4j събития, особено неавтентифицирани мрежови услуги, базирани на стари сокет мостове.
Временно ограничаване на риска може да се постигне чрез конфигуриране на десериализационния филтър на JVM да отхвърля java.rmi.MarshalledObject, въпреки че това може също така да блокира легитимни сериализирани Log4j събития.
По-трайните защити включват премахване на Java сериализацията от транспорта на регистрационни файлове, обновяване или премахване на зависимостите с уязвими вериги от джаджи, използване на взаимно автентифицирани крайни точки и мигриране към структурирано регистриране (JSON или RFC 5424) през TLS.
От Apache изрично препоръчват структурирани формати и TLS вместо транспорт на регистрационни данни със сериализация на Java. Към момента на докладването проблемът Log4j2 #4255 остава отворен и няма присвоен CVE номер.
Дефектът се разбира най-добре като опасно заобикаляне на десериализацията в наследени или персонализирани приемници на събития на Log4j, а не като универсална уязвимост за отдалечено изпълнение на код, засягаща обикновените внедрявания на Log4j.