Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2022-22965 — Tiefgehende technische Analyse von CVE-2022-22965 (Spring4Shell) mit Umgebungseinrichtung, Debug-Durchlauf und Aufschlüsselung der Exploit-Kette für die Übung im Bildungslabor. | Kitploit
Tools/GitHubGitHub/khidottrivi/cve-2022-22965
SchwachstellenanalyseCode-AnalyseExploitationWebanwendungs-ExploitationLernen & BildungLabs & Praxis
GitHubkhidottrivi/cve-2022-22965

CVE-2022-22965

Tiefgehende technische Analyse von CVE-2022-22965 (Spring4Shell) mit Umgebungseinrichtung, Debug-Durchlauf und Aufschlüsselung der Exploit-Kette für die Übung im Bildungslabor.

Repository anzeigen
42vor 4 JahrenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Analyse von CVE-2022-22965_Spring4Shell

Beschreibung der Schwachstelle

Spring4Shell ist der Name einer CVE, die im Spring Core des Spring Framework existiert.

Mit einem CVSS 3.x Score von 9.8 wird die Schwachstelle als kritisches Risiko eingestuft. Diese Schwachstelle ermöglicht es einem Angreifer, Code aus der Ferne auszuführen und den anfälligen Server zu kontrollieren.

Aufgrund der Verbreitung von Spring Core im Internet und der schwerwiegenden Auswirkungen von Spring4Shell wird diese Schwachstelle von Experten als ebenso einflussreich bewertet wie Log4shell.

Auswirkungsbereich

Spring4Shell betrifft nicht alle Webanwendungen, die Spring Framework im Internet verwenden, sondern erfordert, dass die Webanwendung die folgenden Bedingungen erfüllt:

  • Die Anwendung verwendet Spring Framework Version < 5.2, 5.2.0 – 5.2.19 oder 5.3.0 - 5.3.17
  • Die Anwendung verwendet eine der beiden Abhängigkeiten Spring-webmvc oder Spring-webflux
  • Die Anwendung verwendet Java mit JDK Version >= 9
  • Die Anwendung wird als traditionelles Java-Webarchiv (Datei .war) verpackt und in Tomcat bereitgestellt (es wurde keine Schwachstelle in Anwendungen gefunden, die mit Springboot laufen)

Einrichtung der Umgebung

Die von mir eingerichtete Umgebung hat folgende Parameter:

  • Spring Framework 5.1.0
  • Spring-webmvc Abhängigkeit 5.1.0
  • JDK 11.0.13 (ich verwende eine Kali 2021.4a VM und diese Java-Version ist vorinstalliert)
  • Apache Tomcat 9.0.45

Erstellen der Umgebung, des Projekts mit der Schwachstelle und Einrichten des Debuggings mit IntelliJ

  1. Installation von Apache Tomcat

    Wie oben erwähnt, verwende ich Kali 2021.4a und Apache Tomcat 9.0.45. Wenn Sie nicht wissen, wie man Apache Tomcat installiert, und es unter Kali Linux installieren möchten, können Sie sich diesen Link ansehen.

    Hinweis: Ersetzen Sie den Link https://mirror.kiu.ac.ug/apache/tomcat/tomcat-9/v9.0.45/bin/apache-tomcat-9.0.45.tar.gz durch https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.45/bin/apache-tomcat-9.0.45.tar.gz.

  2. Auswahl der IDE

    Wir benötigen eine IDE, um das Projekt zu codieren, als .war-Datei zu packen und – sehr wichtig – zu debuggen. Ich verwende IntelliJ, Sie können aber auch Eclipse oder Netbeans verwenden, solange die IDE Java unterstützt.

  3. Erstellen eines einfachen Projekts mit der Schwachstelle

    Mein Projekt ist sehr einfach und besteht aus:

    • einem Modell HelloWorld.java

      Untitled

    • einem Controller HelloWorldController.java

      Untitled

    • einer Ansicht hello.jsp

      Untitled

  4. Erstellen der .war-Datei

    Um das Projekt zu packen, gehen Sie wie folgt vor: Build -> Build Artifacts -> helloworld:war -> Build.

    Warten Sie, bis der Build erfolgreich abgeschlossen ist. Dann erscheint ein weiterer Ordner out im Projekt. Gehen Sie zu ./out/artifacts/your_war_name/ und Sie sehen eine Datei your_war_name.war. Diese .war-Datei ist das kompilierte und gepackte Webprojekt und kann in Java-Servern wie Apache Tomcat bereitgestellt werden.

    Falls Build Artifacts ausgegraut ist (nicht möglich), wurde die Build-Artifact-Konfiguration für dieses Projekt noch nicht eingerichtet. Gehen Sie zu: File -> Project Structure -> Artifacts -> Löschen aller vorhandenen Artifacts -> Add (+ ) -> Web Application: Exploded -> From Modules... -> OK (Ende der Erstellung von Exploded) > Add (+ ) -> Web Application: Archive -> For ‘helloworld:war exploded’ -> OK. Führen Sie dann Build Artifacts erneut aus.

  5. Bereitstellung und Einrichtung des Debuggings

    • Bereitstellung

      Um eine .war-Datei in Apache Tomcat bereitzustellen, kopieren Sie die .war-Datei einfach in das Verzeichnis /webapps im Apache-Tomcat-Ordner (z.B.: Ich kopiere die Datei helloworld.war (ich habe sie umbenannt, um sie leichter zu nennen) in das Verzeichnis /opt/tomcat/apache-tomcat-9.0.45/webapps/). Starten Sie dann den Tomcat-Server auf zwei Arten (für Linux):

      • /opt/tomcat/apache-tomcat-9.0.45/bin/catalina.sh start (die Anwendung läuft mit den Rechten des Benutzers, der diesen Befehl ausführt; bei mir root@@)
      • sudo service tomcat start (die Anwendung läuft normalerweise mit Tomcat-Rechten, abhängig von Ihrer Dienstkonfiguration bei der Tomcat-Installation)

      Nach der Bereitstellung rufen Sie http://localhost:8080/helloworld auf.

    • Einrichtung des Debuggings

      Um das Remote-Debugging von Tomcat einzurichten, gehen Sie wie folgt vor:

      1. Serverseite:

        • Öffnen Sie die Datei catalina.sh und ersetzen Sie den Wert localhost durch die IP der VM im Parameter JPDA_ADDRESS.

          Untitled

        • Starten Sie den Tomcat-Server neu mit: /opt/tomcat/apache-tomcat-9.0.45/bin/catalina.sh jpda start. Zusätzlich zum Öffnen von Port 8080 für den HTTP-Server öffnet Tomcat dann Port 8000, um eine Verbindung zum Debuggen herzustellen.

        Hinweis: Im Debugging-Teil führe ich IntelliJ unter Windows 10 aus und den Tomcat auf einer Kali-VM. Daher muss JPDA_ADDRESS geändert werden. Wenn Sie IntelliJ und Tomcat auf demselben Rechner einrichten, ist keine Änderung erforderlich.

      2. IntelliJ-Seite:

        • Gehen Sie zu Run -> Edit Configurations... -> Add (+ ) -> Remote JVM Debug

        • Geben Sie einen Namen ein -> Ändern Sie Host und Port auf die IP und den Port, die Sie in der Datei catalina.sh geändert haben -> OK -> Shift + F9 (Debugging starten)

          Untitled

Detaillierte Analyse

Zunächst analysiere ich das Projekt, das ich zum Debuggen verwende. Wie oben erwähnt, besteht dieses Projekt nur aus:

  • Einem Modell HelloWorld.java, bei dem das HelloWorld-Objekt zwei Attribute hat: message (String) und person (String) sowie Getter- und Setter-Methoden (aufgrund dieser einfachen Struktur wird dieses Objekt Plain Old Java Object – POJO genannt). Das Projekt muss eine POJO-Klasse enthalten – dies ist eine notwendige Bedingung, um die Spring4Shell-Schwachstelle auszunutzen.
  • Einem Controller HelloWorldController.java, der eine Methode helloPost mit den Eingabeparametern helloWorld (HelloWorld) und model (Model) enthält. In der Methode helloPost wird addAttribute für das Modellobjekt aus den Werten der Attribute von helloWorld (person und message) durchgeführt – die zweite Bedingung für die Ausnutzung von Spring4Shell ist, dass ein Controller ein POJO-Objekt als Eingabe akzeptiert.
  • Einer Ansicht hello.jsp, die die Attribute des Modells (vom Controller HelloWorldController.java gesendet) aufruft und dem Benutzer anzeigt.

Ich habe ein Beispiel wie folgt:

Untitled

Die Anwendung holt die Informationen aus den Parametern der POST-Anfrage und erstellt ein helloWorld-Objekt {“person”:”Leo”, “message”:”Hi there”}. Dieses helloWorld-Objekt ist die Eingabe für die Methode helloPost. Die Anwendung führt die oben genannten Schritte aus, um die entsprechende Antwort an den Benutzer zurückzugeben.

Der Prozess der Umwandlung von den Parametern im Body der POST-Anfrage in das helloWorld-Objekt wird vollständig automatisch von Spring durchgeführt. Wie macht Spring das und validiert es die eingegebenen Parameter?

Quelle (Source) der Klasse CachedIntrospectionResults

Dieses Bild wurde während des Debuggings aufgenommen, das Beispiel führte eine Anfrage mit dem Body „class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT“ durch. (ich nenne den linken Teil (Stack Trace) (1) und den rechten Teil (2)):

Untitled

In (1) habe ich die wichtigen Punkte hervorgehoben (von unten nach oben betrachtet). Spring führt applyPropertyValue für das helloWorld-Objekt aus den Parametern der POST-Anfrage aus. Wenn die Parameter nur einfach person=Leo&message=Hi%20there sind, kann Spring mit dem Schlüsselwort „person“ helloWorld.person und „message“ helloWorld.message zuordnen.

Aber Spring erlaubt es uns auch, Objekte über HTTP-Anfragen zu senden (es ist übertrieben zu sagen, dass man Objekte über HTTP sendet, aber so kann man es sich vereinfacht vorstellen). Angenommen, das Attribut person ist kein String mehr, sondern ein Objekt Person, das zwei Unterattribute name (String) und age (int) hat. Um Informationen über dieses Person-Objekt an den Server zu senden, würde dies so aussehen: “person.name=Leo&person.age=23”.

Das Format der Parameter ist also A.B.C.D… = X und nicht mehr nur A=X. Um das Format A.B.C.D… = X zu verarbeiten, z.B. einen Parameter wie A.B.C= X, vereinfacht gesagt: Spring wandelt dies in getA.getB.setC(X) um.

Ich werde nicht erklären, was getA ist, sondern ein Beispiel mit dem Anfrage-Body „person.name=Leo&person.age=23“ geben: Spring sucht im helloWorld-Objekt nach dem Attribut person und der Methode getPerson. Wenn vorhanden, ruft Spring helloWorld.getPerson() auf. Zu diesem Zeitpunkt erhält Spring ein Objekt vom Typ Person, nennen wir es person1. Dann sucht Spring in person1 nach einem Attribut namens „name“ und nach setName (da nach „name“ ein „=“ kommt). Wenn vorhanden, ruft Spring setName(Leo) für person1 auf.

Bei person.age ruft Spring nicht erneut von vorne nach person und dann nach age, sondern verwendet die zuvor gefundenen Objekte wieder, in diesem Fall helloWorld und person1.

Nach diesen Schritten existiert auf dem Server ein helloWorld-Objekt {person:{name:”Leo”, age:23}} (das Attribut message lassen wir vorerst weg).

Wie kann Spring die Attribute jedes Objekts finden, z.B. das Attribut „person“ des helloWorld-Objekts?

Sie sehen im oberen Teil von (1) die Funktion CachedIntrospectionResults(beanClass). Diese Funktion listet die Attribute von beanClass auf. In (2) sehen Sie, dass beanClass = model.HelloWorld drei Attribute hat. Das von mir erstellte Modell HelloWorld hat jedoch nur zwei Attribute: „person“ und „message“. Die obige Funktion hat also ein weiteres Attribut „class“ zurückgegeben. Wenn Sie die Zeile „class“ erweitern, sehen Sie, dass propertyType „java.lang.class“ ist.

Wir können also auf ein class-Objekt vom Typ java.lang.classclass einwirken – dies ist die Quelle (source) von Spring4Shell.

CVE-2010-1622

In Bezug auf die obige Quelle gab es bereits eine CVE-2010-1622, die sich auf diese Quelle bezieht. Der Autor von CVE-2010-1622 nutzte diese Quelle mit dem Payload class.classLoader.URLs[0] = X aus.

Weil die Klasse java.lang.class eine Methode getClassLoader() enthält, die ein ClassLoader-Objekt zurückgibt, und dieser ClassLoader kann auf das URLs-Array von Tomcat (zum Laden von Ressourcen) einwirken. Durch die Beeinflussung von URLs kann ein Angreifer den Wert von URLs[0] auf eine URL ändern, um eine Remote-Verbindung zu einer bösartigen Jar-Datei (die der Angreifer kontrolliert) herzustellen.

Um diesen Fehler zu beheben, hat Spring einen Filter (Blacklist) in der Funktion CachedIntrospectionResults(beanClass) implementiert:

Untitled

Wenn „beanClass“ == Class.class (java.lang.class) ist, muss pd sich von „classLoader“ und „protectionDomain“ unterscheiden. Dies zeigt sich darin, dass nach dem Laden aller Attribute von java.lang.class durch CachedIntrospectionResults die beiden Attribute „classLoader“ und „protectionDomain“ nicht vorhanden sind:

Untitled

Aber stattdessen hat Class.class ab JDK 9 ein zusätzliches Attribut „module“ erhalten, und Class.module hat ein Attribut classLoader:

Untitled

→ Mit JDK 9 oder höher kann man also die Blacklist von Spring umgehen!!!

Ziel (Sink) der Klasse AccessLogValue

Basierend auf dem öffentlichen PoC des Spring4Shell-Fehlers sieht das verwendete Payload so aus:

class.module.classloader.resources.context.parent.pipeline.first ⇔ Class.getModule().getClassLoader().getResources().getContext().getParent().getPipeline().getFirst()

Basierend auf dem Debugging sehen wir folgende Gadget-Chain:

java.lang.class.getModule() -> java.lang.module.getClassLoader() -> org.apache.catalina.loader.ParallelWebappClassLoader.getResources() -> org.apache.catalina.webresources.StandardRoot.getContext() -> org.apache.catalina.core.StandardContext.getParent() -> org.apache.catalina.core.StandardHost.getPipeline() -> org.apache.catalina.core.StandardPipeline.getFirst() -> org.apache.catalina.valves.AccessLogValue.

Und die Klasse AccessLogValue hat die folgenden Attribute:

Untitled

Wir können ein AccessLogValue-Objekt aufrufen, und dieses AccessLogValue beeinflusst die Log-Erstellung von Tomcat.

→ Wir können auf dem Server Dateien erstellen, indem wir die Attribute des AccessLogValue-Objekts im Tomcat-Server setzen. Dazu setzen sie im PoC die Attribute Prefix, Suffix, Pattern, Directory und fileDateFormat. Die Payload-Anfrage sieht wie folgt aus:

“class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di%20java.io.InputStream%20in%20%3D%20%25%7Bc%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=”

  • Liste der Breakpoints

    Um das Debuggen zu erleichtern, können Sie an den folgenden Stellen Haltepunkte setzen:

    Untitled

Fazit

Diese Analyse hat eigentlich kein Fazit, dieser Abschnitt dient nur der Vollständigkeit!!!

Wenn Sie nach einer Lösung suchen, finden Sie sie hier.

Tool herunterladen