Anwendungen – Apps, Fachartikel

Java Serialization

Java Serialization

Serialisierung (engl. Serialization) ist eine insbesondere bei Java verwendete Technik, mit der Objekte in eine Byte-Sequenz umgewandelt werden, um diese persistent auf eine Festplatte oder in eine Datenbank zu schreiben bzw. für den Datenaustausch über Netzwerke zu verwenden. Ein Angreifer kann eine Applikation, die ungeprüfte und entsprechend präparierte serialisierte Objekte akzeptiert, dazu bringen, beliebigen Code mit den Rechten der Anwendung auszuführen. Zu solchen Angriffen existieren mittlerweile bekannte Exploits und es ist davon auszugehen, dass sich diverse Akteure nun darauf konzentrieren werden, diese auszunutzen. Der Artikel beschreibt die Angriffstechnik und zeigt Gegenmaßnahmen auf.

Die Serialisierungs-Funktionalität wird von Java-Softwareentwickeln häufig verwendet, um Daten zwischen Java-Programmen (z.B. auf ThickClients und Java Servern) oder Webapplikationen (z.B. ViewState) zu übertragen. Der umgekehrte Prozess, also das Auslesen der Byte-Sequenz und das Umwandeln in ein lauffähiges Objekt nennt man Deserialisierung engl. deserialization. Eine Klasse, die serialisierbar sein soll, muss das Java Interface java.io.serializable implementieren. Hierbei handelt es sich um ein Marker Interface, das der Klasse, die dieses implementiert, das Serialisierungs-Verhalten übermittelt. Java bietet eine große API unter der java.io Package an, die (De)Serialisierung behandelt.

•  java.io.serializable
•  java.io.Externalizable
•  ObjectInputStream
•  and ObjectOutputStream etc.

Die in der Vergangenheit häufig gefundenen Schwachstellen in serialisierter Kommunikation werden verursacht, wenn Entwickler annehmen, dass die serialisierten Objekte von einem vertrauensvollen Client bzw. Server kommen. Besonders häufig ist das der Fall, wenn beide Programme von demselben Entwickler oder derselben Firma entwickelt wurden.

Als Beispiel hierfür soll ein in Java implementiertes „Client-Server“-Programm dienen. Hier sendet der Client ein serialisiertes Payload-Objekt über ein TCP-Stream zum Server, dieser deserialisiert das Objekt und gibt die Attribute des Objektes aus.

TcpServer.java

Der Server öffnet den TCP-Port 9999 und erwartet, dass ein Client sich mit ihm verbindet und ein serialisiertes Objekt sendet. Dieses wird per Type-Cast auf ein Object gecastet und dessen Attribute ausgegeben.

TcpClient.java

Hier wird ein Objekt vom Typ TcpPayload instanziiert und dem TcpServer.java per TCP gesendet.

Problembeschreibung

Häufig gehen Entwickler davon aus, dass die serialisierten Objekte Attribute enthalten, denen sie beim deserialisieren vertrauen können, da sie (angeblich) von einem bekannten Client entstammen. Es ist jedoch nicht nur möglich als Angreifer einen eigenen Client zu programmieren, auch ist die Manipulation der Datenübertragung durch einen „Man-in-the-Middle“-Angriff denkbar. Hierzu muss lediglich eine Klassendefinition des übertragenen serialisierten Objektes vorliegen, um den übertragenen serialisierten Bytestrom als „Man-in-the-Middle“ zu deserialisieren, die Attribute zu manipulieren und wieder serialisiert an den eigentlichen Empfänger zu leiten. Denkbar wäre etwa, dass ein String, der ein Attribut eines übertragenen Objektes ist, serverseitig verwendet wird, um SQL-Befehle auszuführen. Um hier eine mögliche SQL-Injection Schwachstelle anzugreifen, muss dieser String von Angreifer manipuliert werden können.

<< Erste < Vorherige 1 2 3 4 Nächste > Letzte >>