Hack The Box Writeup für die ausgelaufene Challenge ReactOOPS – Vollständige Lösung und pädagogischer Leitfaden zu CVE-2025-55182/CVE-2025-66478 (React2Shell RCE). Enthält detaillierte Schwachstellenanalyse, Ausnutzungstechniken und Team-Lernmaterialien.
Autor: TheStingR – Team ISP1337Hackers
Challenge: ReactOOPS (Web)
Plattform: Hack The Box
Schwierigkeit: Sehr leicht – ZURÜCKGEZOGEN
Datum gelöst: 13. Dezember 2025
ReactOOPS ist eine Web-Challenge, die CVE-2025-55182 / CVE-2025-66478 ausnutzt – eine kritische, nicht authentifizierte Remote-Code-Ausführung (RCE) in React Server Components und dem Next.js App Router.
Wesentliche Erkenntnisse:
hasOwnProperty-Prüfung in der Flight-Protokoll-DeserialisierungDie Challenge präsentiert eine ausgefeilte Next.js-Anwendung, die das NexusAI-Assistenteninterface bereitstellt. Die Anwendung scheint Benutzereingaben über React Server Components zu verarbeiten, doch subtile Unstimmigkeiten in der reaktiven Schicht deuten auf zugrunde liegende Schwachstellen hin.
Die Anwendung verwendet:
Das Flight-Protokoll ist das proprietäre Serialisierungsformat von React zur Übertragung von Daten zwischen Server und Client in Server-Component-Architekturen. Es verwendet Referenzen wie:
$1 – Referenz auf Objekt an Position 1$1:path:to:value – Property-Pfad-TraversierungVerwundbarer Code in Reacts ReactFlightReplyServer.js:
// Zeile ~450: getOutlinedModel Funktion
function getOutlinedModel(response, id) {
let chunk = chunks.get(id);
const value = chunk.value;
// Referenzen verarbeiten wie "$1:path:to:value"
if (reference.startsWith('$')) {
const refId = parseInt(reference.slice(1).split(':')[0]);
const path = reference.slice(1).split(':').slice(1);
let obj = chunks.get(refId).value;
// VERWUNDBARE SCHLEIFE – KEINE hasOwnProperty-ÜBERPRÜFUNG!
for (let i = 0; i < path.length; i++) {
obj = obj[path[i]]; // ← Erlaubt Prototyp-Ketten-Zugriff
}
return obj;
}
}
Die sichere Version (wie es sein sollte):
for (let i = 0; i < path.length; i++) {
if (Object.prototype.hasOwnProperty.call(obj, path[i])) {
obj = obj[path[i]];
} else {
throw new Error('Ungültiger Property-Zugriff');
}
}
Ohne die hasOwnProperty-Prüfung kann ein Angreifer folgendes durchlaufen:
myObject[__proto__][then] → Chunk.prototype.then
myObject[__proto__][constructor] → Function
myObject[__proto__][constructor][prototype] → function.prototype
Schritt 1: Sende Referenz "$1:__proto__:then"
│
├─ Zugriff auf myChunk[__proto__]
└─ Dann Zugriff auf [then] auf dem Prototyp
Schritt 2: Erstelle gefälschtes Promise-ähnliches Objekt
│
└─ { then: schädlicheFunction }
Schritt 3: React führt await auf dieses Objekt aus
│
├─ Ruft die .then()-Methode auf
└─ Führt die Funktion des Angreifers aus
Schritt 4: Beliebige Code-Ausführung
│
└─ Code wird im Server-Kontext als Root ausgeführt
Die Schwachstelle liegt vor der Next-Action-Validierung:
Request-Verarbeitungsablauf:
├─ Parse Multipart-Formulardaten
├─ Deserialisiere Flight-Protokoll ← RCE PASSIERT HIER
│ └─ Referenzen und Objekte verarbeiten
│ └─ Keine hasOwnProperty-Prüfung!
├─ Extrahiere Next-Action-Header
├─ Validiere Action-ID ← Dies kommt DANACH
└─ Führe Action-Handler aus
Indem der Angreifer während der Deserialisierung RCE auslöst, umgeht er alle Sicherheitsprüfungen auf Action-Ebene.
# Prüfen, ob der Dienst antwortet
curl -v http://<IP>:PORT/
Erwartet: Next.js-Anwendung, die HTML mit aktiviertem RSC ausliefert.
Achte auf Indikatoren:
next--Präfixen<script type="text/x-component">.next-VerzeichnisartefaktenDer zuverlässigste Indikator ist der Versuch eines Prototype-Pollution-Angriffs und die Beobachtung der Antwort:
# Zerstörungsfreies Erkennungspayload
# Sendet: ["$1:a:a"] referenziert {}
# Verwundbar: {}.a.a wirft Fehler → HTTP 500 + E{"digest"
# Gepatcht: hasOwnProperty verhindert Zugriff → kein Absturz
# Navigiere zum Challenge-Verzeichnis
cd /Challenges/ReactOOPS
# Klone das react2shell-Exploit-Framework
git clone https://github.com/freeqaz/react2shell.git
# Stelle sicher, dass alle Skripte ausführbar sind
chmod +x react2shell/*.sh
Ziel: Bestätigen, dass der Server verwundbar ist, ohne Schaden zu verursachen.
cd react2shell
# Führe den Erkennungstest aus
./detect.sh http://<IP>:PORT
Was es tut:
Next-Action: x["$1:a:a"] referenziert leeres Objekt {}{}.a.a zuzugreifenErwartete Ausgabe:
[*] React2Shell Detection Probe (CVE-2025-55182 / CVE-2025-66478)
[*] Ziel: http://<IP>:PORT
[*] HTTP-Status: 500
[!] VERWUNDBAR – Server gab 500 mit E{"digest"-Muster zurück
[*] Antwort-Body:
0:{\"a\":\"$@1\",\"f\":\"\",\"b\":\"s8I48LfEDhqpCdFN5-HbU\"}
1:E{\"digest\":\"346246470\"}
[!] Dieser Server läuft eine verwundbare Version von React RSC / Next.js