flawopen.com/Incidents/log4shell-jndi-injection-december-2021
Log4Shell (CVE-2021-44228): причина и исправление
CVE-2021-44228 позволяла данным в журнале запускать lookup Log4j 2 и загрузку классов через JNDI. Обновите Log4j и найдите встроенные копии.[1], [2], [4]
В офисе работает клерк, чья единственная обязанность — записывать, что говорят посетители. Кто-то обнаруживает: если посетитель произнесёт определённую фразу, клерк перестаёт писать, идёт по указанному в ней адресу, забирает у незнакомца запечатанный конверт и выполняет инструкции из него. А ведь клерк должен был только записывать.[1]
Ключевые понятия и термины
Lookup в сообщениях- Функция Log4j 2, заменявшая выражения ${...} в сообщениях журнала значениями в момент записи. До 2.15.0 это распространялось и на данные внутри сообщения, а не только на заданный шаблон.[1]
JNDI- Java Naming and Directory Interface — API для поиска объектов в службах каталогов вроде LDAP. JNDI-lookup к удалённому серверу мог вернуть класс, который JVM загружала.[1]
Внедрение выражений (CWE-917)- Недоверенные данные попадают в вычислитель выражений, и текст, переданный как данные, исполняется как инструкция.[1]
Транзитивная зависимость- Библиотека, попавшая в приложение только потому, что от неё зависит другая библиотека. Многие случаи уязвимости к Log4Shell происходили из копий Log4j, которых никто не учитывал.[4]
Связи со стандартами
- Ссылка CWE для слабого места, описанного в этом руководстве: CWE-20 CWE-502 CWE-917
- D3-OTF Фильтрация исходящего трафика — Описанное в руководстве ограничение исходящего сетевого трафика сокращает список адресов, доступных сервису или хосту.
- CISA KEV — добавлено 2021-12-10 — CVE-2021-44228
Хронология инцидента
Чэнь Чжаоцзюнь из Alibaba Cloud Security конфиденциально сообщает об уязвимости в Apache.[1]
CISA издаёт Emergency Directive 22-02, обязывающую федеральные ведомства США найти и нейтрализовать Log4j.[3]
Log4j 2.17.1 исправляет CVE-2021-44832 — последнюю из трёх CVE, выявленных после 2.15.0 (вместе с CVE-2021-45046 и CVE-2021-45105).[1]
Пошаговый сценарий атаки
Текст злоумышленника попадает в вызов журнала
Любое значение, которое приложение пишет в журнал — имя пользователя, заголовок, поисковый запрос, — может содержать выбранное злоумышленником lookup-выражение.[1]
Исходный код: Уязвимый vs Защищённый вариант
Иллюстративная конфигурация Maven. Импорт log4j-bom приводит все модули Log4j, включая копии, подтянутые другими библиотеками, к одной актуальной версии. Правило enforcer проваливает сборку, если хоть какой-то log4j-core старше 2.17.1 остаётся достижим, в том числе транзитивно, — так новая зависимость не вернёт уязвимый код незаметно. Настоящее исправление — обновление; блокировка исходящих LDAP и RMI с серверов приложений — эшелонированная защита, которая срывала эксплуатацию даже там, где с патчами опаздывали.
<!-- pom.xml: a direct dependency pinned to a vulnerable release -->
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<!-- Nothing stops another library from pulling in an older log4j-core transitively. -->
<!-- pom.xml: one version for every Log4j module, and a build that fails on old ones -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>2.24.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>ban-vulnerable-log4j</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<bannedDependencies>
<searchTransitive>true</searchTransitive>
<excludes>
<exclude>org.apache.logging.log4j:log4j-core:[2.0-beta9,2.17.1)</exclude>
</excludes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Чек-лист по защите системы для инженеров
- ✓Обновите log4j-core до 2.17.1 или новее (2.12.4 для Java 7, 2.3.2 для Java 6) и проваливайте сборки, в которых где-либо в дереве зависимостей разрешается более старая версия.[1]
- ✓Формируйте SBOM при каждой сборке и храните его вместе с артефактом, чтобы будущий бюллетень сопоставлялся с затронутыми сервисами за минуты.[4], [3]
- ✓Сканируйте развёрнутые артефакты, а не только репозитории кода: shaded- и встроенные JAR во многих продуктах скрывали Log4j от манифестов зависимостей.[4]
- ✓Запрещайте по умолчанию исходящий трафик с серверов приложений: для эксплуатации нужны были исходящие LDAP, RMI и DNS к произвольным хостам.[4], [3]
- ✓После исправления структурной ошибки ждите новых CVE и не закрывайте инцидент, пока исправления поставщика не устоятся.[1]
Источники
- Apache Log4j — уязвимости безопасности (CVE-2021-44228 и последующие)
- CVE-2021-44228 — запись CVE
- CISA — Emergency Directive 22-02: нейтрализация уязвимости Apache Log4j
- CISA — рекомендации по уязвимости Apache Log4j
- Безопасен ли ObjectInputStream в Java для недоверенных данных?
- Внедрение команд — полный справочник по классу