
Einzeldatei-PoC für Rails CVE-2026-66066: beliebiges Dateilesen, Secret-Wiederherstellung, threadbasiertes Scannen und bedingte RCE über signierte Bildvarianten.
Ein Proof of Concept ohne Abhängigkeiten in einer einzigen Datei sowie ein nur auf Loopback erreichbares Docker-Lab für die Rails-Active-Storage/libvips-Schwachstelle mit beliebigem Dateizugriff. Es demonstriert außerdem die bedingte Eskalation aus dem Advisory: von einem wiederhergestellten secret_key_base zu einer gefälschten Bildvariation und Befehlsausführung.
Primäre Referenzen: Rails-Advisory, Rails-Forensikanalyse, der technische Ethiack-Bericht und das 8.1.3.1-Release.
https://github.com/user-attachments/assets/fdcb5651-c1d1-4bc4-b322-8f1205b09635
kr2s.py enthält den vollständigen Client in einer Datei:
h5py oder numpy;Das Tool installiert keine Pakete, startet keinen Callback-Listener, benötigt kein curl auf dem Zielsystem und ist nicht von make abhängig. Die RCE-Stufe nutzt die eingebaute Active-Storage-Representation-Route und benötigt kein Marshal-Gadget.
Starten Sie das verwundbare Lab:
cd lab
RAILS_VERSION=8.1.3 docker compose up --build
Der Compose-Port ist an 127.0.0.1 gebunden, und der Container läuft als unprivilegierter Benutzer mit entfernten Linux-Capabilities.
In einem anderen Terminal:
# Intrusive: uploads a blob, then confirms /etc/hostname is readable.
python3 kr2s.py check http://127.0.0.1:3000
# Recover a fixed-size prefix. Binary output goes to stdout unless -o is used.
python3 kr2s.py read http://127.0.0.1:3000 /etc/passwd --size 4096
python3 kr2s.py read http://127.0.0.1:3000 /etc/passwd -o passwd.bin
# Recover selected environment secrets. Values are redacted by default.
python3 kr2s.py secrets http://127.0.0.1:3000
# Display complete matched environment values for authorized analysis.
python3 kr2s.py secrets http://127.0.0.1:3000 --show-full
# Passive preflight of one target or a file containing one target per line.
python3 kr2s.py scan http://127.0.0.1:3000
python3 kr2s.py scan targets.txt --threads 10 --json scan.json
# Intrusively confirm file read on every target in the list.
python3 kr2s.py scan targets.txt --active
# Probe selected libvips loaders.
python3 kr2s.py probe http://127.0.0.1:3000
# Conditional escalation. This executes the supplied command.
python3 kr2s.py rce http://127.0.0.1:3000 "id; uname -a"
Führen Sie python3 kr2s.py COMMAND --help aus, um alle Überschreibungen zu sehen. Häufige Steuerungsmöglichkeiten für reale Anwendungen umfassen --harvest-url, --show-path, --proxy, --insecure und --skb.
secrets --show-full gibt vollständige übereinstimmende Umgebungsvariablenwerte aus. Ohne diese Option druckt das Tool nur die ersten 12 Zeichen und eine Ellipse. Dateien, die mit --also-read angefordert werden, einschließlich der standardmäßigen Rails-Credential-Pfade, werden bei Lesbarkeit mit bis zu 600 Zeichen ausgegeben.
Passives scan meldet lediglich, ob die Seite eine erntbare Active-Storage-Representation bereitstellt; es kann den installierten Rails-Patchstand nicht ermitteln. scan --active lädt einen schädlichen Blob hoch und versucht den Canary-Read. Ein fehlgeschlagenes aktives Ergebnis wird als BLOCKED_OR_INCONCLUSIVE gekennzeichnet, nicht als SAFE, da WAFs, Authentifizierung, nicht unterstützte Variationen und der Rails-Fix von außerhalb der Anwendung identisch aussehen können.
Stoppen Sie das Lab mit:
cd lab
docker compose down
image/png deklarierten Active-Storage-Direktupload.matload; die Bytes der Zieldatei werden zu Bildpixeln und in einem generierten PNG zurückgegeben.Die Hybriddatei erfüllt gleichzeitig zwei Parser: Ihr Text beginnt mit MATLAB 5.0, während das Versionswort an Offset 124 den HDF5-gestützten MATLAB-7.3-Pfad auswählt. Der Fix von Rails blockiert als nicht vertrauenswürdig markierte libvips-Operationen, bevor eine vom Angreifer kontrollierte Datei matload erreichen kann.
rce liest zunächst SECRET_KEY_BASE aus /proc/self/environ, sofern nicht --skb angegeben wird. Es leitet den Active-Storage-Verifier-Schlüssel ab und signiert eine JSON-Variation, die eine instance_eval-Operation enthält. Auf dem betroffenen vips-Pfad erreicht die Operation Vips::Image.public_send. Das PoC sendet sie über die eingebaute Representation-Route, führt den angegebenen Befehl über /bin/sh aus und erfasst beide Ausgabeströme.
Diese zweite Stufe hängt davon ab, dass das Signing-Secret wiederhergestellt wird und das verwundbare vips-Transformationsverhalten erreicht wird, das in der Ethiack-Analyse von CVE-2025-24293 beschrieben wird. Der Patch für CVE-2026-66066 schließt den Dateizugriffs-Einstiegspunkt; er ist keine allgemeine Korrektur für zuvor geleakte Signing-Secrets. Rotieren Sie Secrets nach einem mutmaßlichen Leak, wie das Rails-Advisory empfiehlt.
Die Befehlsausgabe wird in eine zufällige Datei /tmp/.kr2s_* geschrieben, über dasselbe Dateizugriffs-Primitiv wiederhergestellt und anschließend mit einem zweiten signierten Payload entfernt.
Lesezugriffe geben den angeforderten Bereich fester Größe zurück. Ist die Quelle kürzer, folgen auf ihren Prefix Nullbytes. Verwenden Sie --offset für weitere Bereiche.
Die Standard-Lab-Variation konvertiert nur nach PNG, daher ist die Wiederherstellung bytegenau. Reale Anwendungen können Varianten in der Größe verändern. Der Modus mit geerntetem Schlüssel verwendet eine Ein-Pixel-Spalte, um horizontales Resampling zu vermeiden, aber eine Variation mit geringerer Höhe kann die Geometrie dennoch verändern. In diesem Fall schlägt der Client explizit fehl; verringern Sie --size oder ernten Sie eine Representation ohne Größenänderung.
Jeder Befehl ist intrusiv: Er erzeugt persistente Active-Storage-Blobs und kann verarbeitete Varianten erzeugen. rce führt zusätzlich den angegebenen Befehl aus.
Das Matrix-Skript baut jede Version, führt echte Read- und RCE-Prüfungen auf verwundbaren Versionen aus, stellt sicher, dass Lesezugriffe auf behobenen Versionen blockiert werden, und gibt bei jeder Abweichung einen Wert ungleich null zurück: