Minimierung von Angriffsoberflächen in Java

vorhergehende Artikel in: Java Software-Test Security
09.03.2024

Ich habe in einem früheren Artikel darauf hingewiesen, dass Java (17) und Python (3.10) sich bei der Validierung von x509-Zertifikaten ein wenig unterscheiden. Einer der Unterschiede ist die Schwelle, ab der Schlüssel wegen zu geringer Länge als unsicher bewertet und die damit verbundenen Zertifikate abgelehnt werden.

Dabei ging es um RSA-Schlüssel Python 3.10 weist solche mit einer Schlüssellänge von 1024 Bit zurück, während Java diese zunächst einmal zulässt.

Inzwischen ist ein wenig Zeit vergangen: Ich habe einen Vortrag zur Validierung von Zertifikaten beim 37C3 eingereicht, der aber abgelehnt wurde. Zu diesem Vortrag habe ich ein Repository erstellt, das dabei hilft, diverse Zertifikate mit kleineren und größeren Fehlern zu generieren, um die Validierung von Zertifikaten mit der in eigenen Projekten gewählten Sprache oder dem benutzten Framework zu testen.

In dem damit verbundenen Projekt zur Demonstration habe ich einige Java-Tests geschrieben, die als Illustration und Anregungen für eigene Testsuiten dienen können. Hier habe ich entsprechende Vorkehrungen getrofen, individuell zu kurze Schlüssel abweisen zu können. Zu Testzwecken mag das auch erst einmal akzeptabel sein - in Production-Code sollte man natürlich die von Java zur Verfügung gestellten Mittel benutzen...

In diesem Zusammenhang überlegte ich, ob es wohl möglich wäre, andere Angriffsoberflächen, die sich in Java verbergen ebenfalls zu verkleinern oder ganz auszuräumen. Ein Beispiel dafür sind Multimediadateien: Immer wieder finden sich in den Bibliotheken zur Verarbeitung solcher Dateien Lücken, die es erlauben, sie mit speziell dafür erstellten Multimediadateien anzugreifen. Auswirkungen sind dabei ganz verschieden und können mitunter auch sehr schlimm werden.

Java bedient sich diverser Methoden, Bilder zu laden. Dabei ist es so, dass Standard-Java-Programme die eingebauten Methoden nutzen, da sie für den Entwickler der Software so wenig Aufwand bedeuten: Er muss lediglich sagen, dass eine Datei geladen werden soll - Java sucht sich den passenden Codec und wendet ihn an. Wenn aber von vornherein klar ist, dass die Anwendung lediglich JPGs und PNGs verarbeiten soll - wieso sollten dann überhaupt Codecs für BMP oder GIF (oder andere) verfügbar sein?

Das Szenario hier ist, dass ein Angreifer eine Lücke im BMP-Codec ausnutzen will. Er speichert also ein Bild mit der Endung .jpg ab, das aber ein BMP ist, das er exakt so erzeugt hat, dass es die Lücke triggert. Java analysiert die Datei und findet heraus, dass der BMP-Codec gebraucht wird, wendet ihn an und - hey, presto! Das Opfer wurde erfolgreich attackiert!

Um dies zu verhindern, müsste es eine Möglichkeit geben, diese nicht benötigten Codecs zu deaktivieren oder man müsste eine Whitelisting Regel erstellen können, in der vermerkt ist, welche Codecs die Anwendung benutzen soll.

Diese Analyse bezieht sich nicht nur auf Multimedia Codecs, sondern auf alle Bereiche von Java, die mittels der ServiceProviderInfrastructure erweiterbar sind.

Dafür gibt es verschiedene Ansätze, die aber nur dazu taugen, bekannte Codecs oder andere Bibliotheken zu deaktivieren.

Diese helfen aber nicht vollständig gegen einen bösartigen Angreifer, da sie konfigurative Maßnahmen darstellen und zum Beispiel auf die Manifest-Dateien in JARs abzielen. Ein Angreifer kann aber diese Datei ändern und damit geht der vermeintliche Schutz ins Leere.

Der ServiceLoader bietet weitere Möglichkeiten wie etwa die Inspektion der verschiedenen Provider mittels der Methode stream() - sie erlaubt es zum Beispiel, die gefunden Implementationen auf vorhandene oder fehlende Annotations zu checken.

Auch das ist aber keine Komplettlösung, da ja - wie in unserem Beispiel der Multimedia-Codecs die Serviceprovider nicht unter unserer Kontrolle stehen und wir daher keine Annotations hinzufügen können - außerdem können Angreifer ja einfach ihre verseuchten Bibliotheken mit unseren Whitelisting-Annotations versehen.

Es existieren Stellen in Java, in denen SPI nicht automatisch aktiv ist - dazu zählt unter anderem die Lokalisierung.

Es existiert aber bisher meines Wissens keine Möglichkeit, SPI global abzuschalten und nur für bestimmte Services und ServiceProvider zu aktivieren.

Alle Artikel rss Wochenübersicht Monatsübersicht Github Repositories Gitlab Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Mandelbrot-Sets mittels Shadern berechnen

    17.05.2019

    Nachdem ich in den letzten verregneten Tagen auf Youtube in den Videos von Numberphile versunken bin, hat mich eines davon angestachelt, mich selbst mit dem Mandelbrotset zu beschäftigen. Als ich dann noch Code fand, der behauptete, das auf einer Graphikkarte mittels Shadern berechnen zu können, war es um mich geschehen...

    Weiterlesen...

Neueste Artikel

  • Erste Vor-Version eines Gis-Plugin für die sQLshell

    Wie bereits in einem früheren Artikel erwähnt plane ich, demnächst ein Plugin für die sQLshell anzubieten, das eine Visualisierung von Daten mit räumlichem Bezug im Stil eines Geoinformationssystems erlaubt.

    Weiterlesen...
  • bad-certificates Version 2.1.0

    Das bereits vorgestellte Projekt zur automatisierten Erzeugung von Zertifikaten mit allen möglichen Fehlern hat eine Erweiterung erfahren und verfügt über ein Partnerprojekt - beide sind nunmehr in der Version 2.1.0 freigegeben

    Weiterlesen...
  • SQLite als Geodatenbank

    Wie bereits in einem früheren Artikel beschrieben treibe ich derzeit Anstrengungen voran, die sQLshell attraktiver für Nutzer zu machen, die mit Geodatenbanken arbeiten.

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muß damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.