© Swill Klitch/Shutterstock.com
Deserialisierungsschwachstellen im Java-Programmcode

Bastelstunde: Deserialisierungs-Exploits


Im diesem Teil unserer Artikelserie zu Deserialisierungsschwachstellen in Java wollen wir selbst einen Exploit Code schreiben. Wir sehen uns an, wie anhand der BeanShell Gadget Chain [1], [2] eine Deserialisierungsschwachstelle unter realen Bedingungen ausgenutzt werden kann. Hiermit sollten wir dann in der Lage sein, eigene Befehle im Betriebssystem auszuführen.

Das java.io-Serialisierungs-API [3] erlaubt die Umwandlung (Serialisierung) eines Java-Objekts in einen Bytestrom und vice versa durch die Deserialisierung mittels der readObject()-Methode. Bei der Deserialisierungsschwachstelle nutzt ein Angreifer sowohl aus, dass keine Validierung vor der Deserialisierung stattfindet, als auch, dass der Angreifer die Properties (den Zustand des Objekts) kontrolliert. Im simpelsten und idealisierten Fall wird beispielsweise Runtime.getRuntime().exec() mit den vom Angreifer kontrollierten Properties ausgeführt, sodass fremde Codeausführung möglich ist. Für einen Angreifer ist es meist einfach, Deserialisierungsschwachstellen zu finden – sie auszunutzen, um Codeausführung zu erlangen, ist jedoch wesentlich komplexer.

Wie sieht ein Exploit Code – ein Programmcode zur Erzeugung eines böswilligen Objekts, das der Deserialisierungsmethode übergeben wird – unter realen Bedingungen aus? Auch hier findet man Techniken wieder, die ähnlich denen bei der Ausnutzung von Stack-Overflow-Schwachstellen in C/C++ [4] sind.

Es kann einfach sein

Bei der Deserialisierungsschwachstelle übergibt ein Angreifer der readObject()-Methode ein beliebiges Objekt, das das Serializable-Interface implementiert, um dessen Zustand (die sogenannten Properties) zu rekonstruieren. Ein Angreifer sucht also ein böswilliges Objekt, das sich im Klassenpfad befindet und das dann der oben genannten Methode übergeben wird, um eigenen Programmcode ausführen zu können. In Ausgabe 11.2020 des Java Magazins [5] wurde die Ausnutzung der Schwachstelle anhand der Logger-Klasse (hier vereinfacht in Listing 1 dargestellt) illustriert.

Listing 1: Logger.java

class Logger implements Serializable { String logfilename; // (1) // ... private void readObject(ObjectInputStream oInput) throws java.io.IOException, ClassNotFoundException // (2) { oInput.defaultReadObject(); // (3) System.out.println("logfilename = "+logfilename); // Debug Output Runtime.getRuntime().exec(new String[]{"bash","-c",logfilename}); // (4) } }

Der Angreifer kontrolliert die Variable logfilename (Listing 1, Kommentar 1). Die Klasse überschreibt ...

Exklusives Abo-Special

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang