
Firefox Content-zu-Parent-IPDL-Privilegieneskalation (N-day, Bug 2054416): gefälschter PDocumentChannel mit RemoteTypeOverride -> Platzierung im privilegedabout-Prozess durch Injection in den Send-Pfad des Mojo-Ports aus einem kompromittierten Content-Prozess
Proof-of-Concept für einen Sandbox-Escape in Firefox 149.0a1 Nightly (2fbc0748c4, vor dem Fix). Ein kompromittierter Content-Prozess fälscht eine IPDL-Nachricht, die den Parent dazu bringt, eine Seite in einem privilegierten (privilegedabout) Prozess zu laden.
Dies ist der Sandbox-Escape der Stufe 2, der dazu entwickelt wurde, sich an eine Content-Prozess-RCE (z. B. CVE-2026-2796) anzuschließen.
Der Parent-Prozess deserialisiert ein nsDocShellLoadState aus IPDL-Nachrichten von content→parent. Der verwundbare Build weist ein von Content gesetztes RemoteTypeOverride-Feld nicht zurück, sodass Content wählen kann, in welchem Prozesstyp eine Navigation landet.
Der Fix (Commit 3ec5c71b41bb, "Validate RemoteTypeOverride") bewirkt, dass der nsDocShellLoadState-Konstruktor jeden Override bei einem von Content ausgelösten Ladevorgang ablehnt.
Wenn der Override berücksichtigt wird — Laden des Dokuments about:blank, Top-Level-Kontext — setzt IsolationOptionsForNavigation den Remote-Typ des Ladevorgangs auf den Override-Wert, und die Seite wird in einem privilegierten Prozess platziert. Sandbox-Grenze verletzt.
Der Override wird über PNecko::PDocumentChannel übertragen, eine Nachricht, die jeder Content-Prozess für jeden Dokumentladevorgang sendet (DocumentChannelCreationArgs.loadState ist ein nsDocShellLoadState).
Die Übermittlung ist der interessante Teil: Rohe Schreibvorgänge in den IPC-Socket werden stillschweigend verworfen, da IPDL-Nachrichten jetzt über Mojo-Ports laufen. Stattdessen steuert der PoC den echten Sendepfad aus JavaScript über native Aufrufe (mithilfe der funcref-Primitive aus CVE-2026-2796):
operator new — einen Heap-Block für die IPC::Message allokierenIPC::Message::Message(routing, type, capacity, flags) — Placement-KonstruktorPickle::WriteBytes — die gefälschte Payload anhängenMessageChannel::Send auf dem PContent-Kanal — Mojo-Framing, Port-Routing und Sequenznummern werden nativ gehandhabtDie Payload (erstellt von forge.py) trägt RemoteTypeOverride = "privilegedabout", URI about:blank, einen Null-Principal und zur Laufzeit geleakte Werte (BrowsingContext-ID, TriggeringRemoteType).
./irun
Logs auf der Parent-Seite (MOZ_LOG=ProcessIsolation:5,DocumentChannel:5) zeigen den Prozesswechsel in den privilegierten Prozess:
V/ProcessIsolation using remote type override (privilegedabout) for load
I/ProcessIsolation Process Switch: Changing Remoteness from 'webIsolated=http://127.0.0.1' to 'privilegedabout'
3ec5c71b41bb "Validate RemoteTypeOverride"| Datei | Zweck |
|---|
privesc.html | PoC-Seite, die im kompromittierten Content-Prozess ausgeführt wird |
forge.py / forge.json | erstellt die gefälschte IPDL-Nachricht (selbstverifizierend) |
wasm-bytes.js | Stufe-1-Primitive: arbiträres R/W, funcref-Aufrufe |
mdrive.py / mdrive2.py | Marionette-Harness zum Starten und Steuern von Nightly |
irun | instrumentierter Lauf: lldb an Parent anhängen + MOZ_LOG-Nachweise |
profile.user.js | Firefox-Profil-Einstellungen (Fission an, Dump aktiviert) |
parse_dc.py | byte-exakter Parser für erfasste DocumentChannel-Nachrichten |
scan_sentinels.py / extract_fields.py | Feldzuordnungs-Scanner für Captures |