PHP - Deserialization + Autoload Classes
Last updated
Last updated
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Zuerst solltest du überprüfen, was Autoloading Classes sind.
Wir befinden uns in einer Situation, in der wir eine PHP-Deserialisierung in einer Webanwendung gefunden haben, ohne dass eine Bibliothek anfällig für Gadgets innerhalb von phpggc
ist. In demselben Container gab es jedoch eine andere Composer-Webanwendung mit anfälligen Bibliotheken. Daher war das Ziel, den Composer-Loader der anderen Webanwendung zu laden und ihn auszunutzen, um ein Gadget zu laden, das diese Bibliothek mit einem Gadget aus der Webanwendung, die anfällig für Deserialisierung ist, auszunutzen.
Schritte:
Du hast eine Deserialisierung gefunden und es gibt kein Gadget im aktuellen Anwendungs-Code.
Du kannst eine spl_autoload_register
-Funktion wie die folgende ausnutzen, um jede lokale Datei mit der .php
-Erweiterung zu laden.
Dafür verwendest du eine Deserialisierung, bei der der Name der Klasse in $name
enthalten sein wird. Du kannst "/" oder "." in einem Klassennamen in einem serialisierten Objekt nicht verwenden, aber der Code ersetzt die Unterstriche ("_") durch Schrägstriche ("/"). Ein Klassenname wie tmp_passwd
wird also in /tmp/passwd.php
umgewandelt und der Code wird versuchen, ihn zu laden.
Ein Gadget-Beispiel wäre: O:10:"tmp_passwd":0:{}
Wenn Sie einen Datei-Upload haben und eine Datei mit der .php
-Erweiterung hochladen können, könnten Sie diese Funktionalität direkt ausnutzen und bereits RCE erhalten.
In meinem Fall hatte ich nichts dergleichen, aber es gab im gleichen Container eine andere Composer-Webseite mit einer Bibliothek, die anfällig für ein phpggc
Gadget ist.
Um diese andere Bibliothek zu laden, müssen Sie zuerst den Composer-Loader dieser anderen Webanwendung laden (da der der aktuellen Anwendung nicht auf die Bibliotheken der anderen zugreifen kann). Wenn Sie den Pfad der Anwendung kennen, können Sie dies sehr einfach erreichen mit: O:28:"www_frontend_vendor_autoload":0:{}
(In meinem Fall war der Composer-Loader in /www/frontend/vendor/autoload.php
)
Jetzt können Sie den Composer-Loader der anderen App laden, also ist es Zeit, die phpgcc
Payload zu generieren, die Sie verwenden möchten. In meinem Fall verwendete ich Guzzle/FW1
, das es mir ermöglichte, jede Datei im Dateisystem zu schreiben.
HINWEIS: Das generierte Gadget funktionierte nicht, damit es funktioniert, modifizierte ich diese Payload chain.php
von phpggc und stellte alle Attribute der Klassen von privat auf öffentlich ein. Andernfalls hatten die Attribute der erstellten Objekte nach der Deserialisierung des Strings keine Werte.
Jetzt haben wir die Möglichkeit, den Composer-Loader der anderen App zu laden und eine phpggc-Payload, die funktioniert, aber wir müssen dies IM GLEICHEN ANFRAGE tun, damit der Loader geladen wird, wenn das Gadget verwendet wird. Dazu sendete ich ein serialisiertes Array mit beiden Objekten wie:
Sie können zuerst sehen, wie der Loader geladen wird und dann die Payload
Jetzt können wir eine Datei erstellen und schreiben, jedoch konnte der Benutzer in keinen Ordner auf dem Webserver schreiben. Wie Sie im Payload sehen können, wird PHP system
mit etwas base64 in /tmp/a.php
aufgerufen. Dann können wir den ersten Typ von Payload wiederverwenden, den wir als LFI verwendet haben, um den Composer-Loader der anderen Webanwendung zu laden, um die generierte /tmp/a.php
-Datei zu laden. Fügen Sie es einfach zum Deserialisierungs-Gadget hinzu:
Zusammenfassung des Payloads
Lade das Composer-Autoload einer anderen Webanwendung im selben Container
Lade ein phpggc-Gadget, um eine Bibliothek der anderen Webanwendung auszunutzen (die ursprüngliche Webanwendung, die anfällig für Deserialisierung war, hatte keine Gadgets in ihren Bibliotheken)
Das Gadget wird eine Datei mit einem PHP-Payload in /tmp/a.php mit bösartigen Befehlen erstellen (der Webanwendungsbenutzer kann in keinem Ordner einer Webanwendung schreiben)
Der letzte Teil unseres Payloads wird die generierte PHP-Datei laden, die Befehle ausführt
Ich musste diese Deserialisierung zweimal aufrufen. In meinen Tests wurde beim ersten Mal die Datei /tmp/a.php
erstellt, aber nicht geladen, und beim zweiten Mal wurde sie korrekt geladen.
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)