Die Schwachstelle dieser Komponente wurde schon vor langer Zeit aufgedeckt, aber ich bin kürzlich bei der Arbeit wieder darauf gestoßen, als ich mich zufällig mit der Java-Deserialisierung beschäftigt habe, also habe ich beschlossen, sie herauszunehmen und zu analysieren wieder, und ich bin während des Prozesses auch auf einige seltsame Fragen gestoßen.
Die meisten Analyseartikel im Internet fügen die Abhängigkeit von commons-collections4-4.0 manuell hinzu, um die von ysoserial generierte CommonsCollections2-Nutzlast zu verwenden. Die Situation, auf die ich gestoßen bin, ist jedoch, dass die Verwendung von CommonsBeanutils1 direkt erfolgreich sein kann Die Analyse von CommonsCollections2 online nicht wiederholen.
Debugging-Umgebung:
JDK 1.8.0_72
Tomcat 8.0.30
Zuerst klonen wir den Quellcode von Shiro zurück und schneiden ihn auf den problematischen Zweig.
git clone https://github.com/apache/shiro.git shiro-rootcd shiro-root git checkout 1.2.0
Um die mit Shiro gelieferten Beispiele zum Laufen zu bringen, müssen wir einige Änderungen an der Datei „samples/web/pom.xml“ vornehmen. Wir müssen die JSTL-Version auf 1.2 ändern und das Scope-Feld von Servlet-API löschen . Legen Sie jstl-1.2.jar im Verzeichnis WEB-INF/lib ab. Dann sollten Sie in der Lage sein, es auszuführen und zu debuggen.
Wir setzen den Haltepunkt auf die Methode „resolvePrincipals“ in org.apache.shiro.mgt.DefaultSecurityManager und senden eine Anfrage mit „rememberMe Cookie“, und es sollte in der Lage sein, zu brechen.
Wir folgen weiterhin der getRememberedIdentity-Methode:
Folgen Sie weiterhin der getRememberedSerializedIdentity-Methode:
In dieser Methode wird das von uns übergebene Cookie gelesen und Base64 dekodiert:
Connect Als nächstes ruft shiro auf ConvertBytesToPrincipals und übergeben Sie das base64-dekodierte Byte-Array als Parameter:
Sie können es auch anhand des Funktionsnamens erraten, nämlich die Entschlüsselung und die Deserialisierung Durch einfaches Debuggen wurde festgestellt, dass es sich um eine AES-Entschlüsselung handelte und es einen voreingestellten Schlüssel Base64.decode("kPH+bIxk5D2deZiIxcaaaA=="); gab. In dem mit Shiro gelieferten Beispiel wurde keine andere Methode zum Festlegen übergeben geheimer Schlüssel, daher wird hier der Standardwert verwendet.
Der bei der AES-Entschlüsselung auftretende IV wird auch aus den ersten paar Bytes des von uns übergebenen Cookies abgerufen, sodass wir problemlos einen Cookie-Wert mit beliebigem Inhalt erstellen können und der entschlüsselte Klartext serialisiert wird. Der Inhalt wird deserialisiert, um ihn zu deserialisieren.
Abschließend wird die Methode org.apache.shiro.io.DefaultSerializer#deserialize zur Deserialisierung aufgerufen:
Der gesamte Vorgang ist sehr einfach: Cookie lesen -> Base64-Dekodierung -> Entschlüsselung -> Deserialisierung
Unsere Nutzlast ist also sehr einfach zu erstellen. Ich werde den vollständigen PoC auf meinen GitHub stellen.
Während des Debugging-Vorgangs sind einige Probleme aufgetreten und der Rechner wurde nicht erfolgreich angezeigt. Lassen Sie es uns hier aufzeichnen.
Ich habe dieses Problem lange debuggt und dachte, es sei ein Problem mit der Nutzlast oder Shiros Code hätte sich im Laufe der Zeit geändert, denn der Fall, auf den ich damals gestoßen bin, war, dass die Nutzlast in die Seele eingeführt wurde, was mich dazu brachte sehr verwirrt. Später entdeckten wir ein Hauptproblem. In dem von Github geklonten Beispiel ist die abhängige Version von commons-beanutils 1.8.3 und die von ysoserial generierte Version ist 1.9.2, sodass sie nicht erfolgreich ausgeführt werden kann Standardprobe von. Also habe ich die Versionsnummer auf 1.9.2 geändert und es wurde ein Hit.
In dem Fall, auf den wir gestoßen sind, kann die tatsächliche Version der abhängigen Umgebung auch so sein, sodass wir direkt Erfolg haben können.
Nachdem dieses Projekt geklont wurde, können Sie sehen, dass es ein Commons-Collections-Paket gibt:
Beim Versuch, CommonsCollections1 von ysoserial zu verwenden, wird eine Ausnahme ausgelöst, die nicht erfolgreich sein kann
Beim Debuggen Ich habe festgestellt, dass hier eine Ausnahme ausgelöst wurde. Warum das Byte-Array nicht deserialisiert werden kann, ist sehr verwirrend
Ich habe den Unterschied zwischen Class.forName() und ClassLoader.loadClass() in Java überprüft und festgestellt, dass forName() immer den ClassLoader() des Aufrufers verwendet, während LoadClass () ermöglicht es Ihnen, selbst einen anderen ClassLoader anzugeben. Woher kommt also ClasssLoader in Shiro? Es wird über Thread.currentThread().getContextClassLoader(); abgerufen, bei dem es sich um WebappClassLoader handelt. Aber warum wird mir angezeigt, dass das Byte-Array nicht geladen werden kann? Nach einigem Suchen habe ich die folgende Diskussion im orangefarbenen Blog gesehen und die Wahrheit über die ganze Sache erfahren:
Shiro resovleClass used ClassLoader.loadClass( ) anstelle von Class.forName() und ClassLoader.loadClass unterstützt das Laden von Array-Typklassen nicht.
Das obige ist der detaillierte Inhalt vonBeispielanalyse einer Apache Shiro 1.2.4-Deserialisierungsschwachstelle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!