Skip to content

Add Ruby on Rails Active Storage Vips RCE module for CVE-2026-66066 - #21733

Open
jburgess-r7 wants to merge 9 commits into
rapid7:masterfrom
jburgess-r7:rails-activestorage-vips-rce
Open

Add Ruby on Rails Active Storage Vips RCE module for CVE-2026-66066#21733
jburgess-r7 wants to merge 9 commits into
rapid7:masterfrom
jburgess-r7:rails-activestorage-vips-rce

Conversation

@jburgess-r7

@jburgess-r7 jburgess-r7 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds exploit/multi/http/rails_activestorage_vips_rce for CVE-2026-66066 / GHSA-xr9x-r78c-5hrm.

The module exploits the Active Storage / libvips untrusted-loader issue by creating a crafted direct-upload blob, recovering readable file content through an Active Storage representation response, deriving the Active Storage verifier key from recovered Rails signing material, and forging a signed ImageProcessing variation for command execution.

The module implements the concrete representation-based chain documented by the Rails forensic repository. It accepts a genuine signed Active Storage variation key directly through VARIATION_KEY, can reuse a full representation URL through REPRESENTATIONURI, or can fall back to extracting or creating a representation through the application workflow when required.

The module supports:

  • Secret recovery from /proc/self/environ, /proc/1/environ, local Rails secret files, encrypted credentials, and legacy secrets.yml paths
  • SHA-1, SHA-256, SHA-384, and SHA-512 key-generator / verifier combinations
  • JSON, Marshal, and MessagePack-compatible signed-message formats
  • Unix command, Linux fetch, and native Ruby targets
  • Modern redirect routes and Rails 6 legacy representation routes
  • Resize-tolerant exfiltration using multiple square HDF5 layouts and Vips sharpen inversion
  • Checked-in MAT/HDF5 data artifacts plus a generator under external/source/exploits/CVE-2026-66066/

This change is needed because the public issue affects Active Storage releases before 7.2.3.2 plus the vulnerable Rails 8.0 and 8.1 ranges when the Vips variant processor is in use, and there is currently no Metasploit module covering the full file-read-to-RCE workflow.

Breaking Changes

None

Reviewer Notes

The best starting points are:

  • modules/exploits/multi/http/rails_activestorage_vips_rce.rb
  • documentation/modules/exploit/multi/http/rails_activestorage_vips_rce.md
  • spec/modules/exploits/multi/http/rails_activestorage_vips_rce_spec.rb

The key implementation detail is that the module does not require a pre-existing full representation URL when the operator already has a genuine signed variation key. VARIATION_KEY lets the module construct the standard Active Storage representation route itself and avoids application-specific form submission.

The module intentionally does not ship the research-only /proc/self/mem verifier-key recovery path or optional MiniMagick / MiniSSL gadget branches. The released exploit path uses the native ImageProcessing send/spawn and send/eval primitives because they are simpler and more reliable.

The reporting researchers' final write-up also documents a MATLAB_empty dimension-encoding read path and an instance_eval RCE variation. This module intentionally does not implement MATLAB_empty: that path is a narrow metadata/log channel, while the representation-based PNG transport used here returns larger directly verifiable reads and is more suitable for reliable automated secret recovery. The module also keeps send/spawn and send/eval instead of instance_eval because they map directly onto Metasploit command and Ruby targets and do not require an output-file round trip.

The target-local payload defaults are intentional. The default Unix target uses cmd/unix/reverse_bash, the Linux fetch target uses cmd/linux/http/x64/meterpreter/reverse_tcp, and the Ruby target uses ruby/shell_reverse_tcp, all of which were validated against the lab.

Verification Steps

    • Build and start a vulnerable Rails target using Active Storage with config.active_storage.variant_processor = :vips, for example Rails 8.0.5 with image_processing 1.14.0 and libvips with MAT/HDF5 support.
    • Start msfconsole.
    • Run use exploit/multi/http/rails_activestorage_vips_rce.
    • Set RHOSTS, RPORT, TARGETURI, and LHOST.
    • Set VARIATION_KEY to a genuine signed Active Storage variation key from any rendered representation, or configure REPRESENTATIONURI.
    • Run check.
    • Confirm the module reports The target is vulnerable. Recovered /proc/version ....
    • Run exploit.
    • Confirm the module recovers Rails signing material, forges a signed variation, and opens a shell session.
    • Run sessions -i <session_id> -c id.
    • Confirm the session runs as the Rails process user.

Test Evidence

Static and unit checks:

ruby -c modules/exploits/multi/http/rails_activestorage_vips_rce.rb
Syntax OK

./tools/dev/msftidy.rb modules/exploits/multi/http/rails_activestorage_vips_rce.rb
1 file inspected, no offenses detected

./tools/dev/msftidy_docs.rb documentation/modules/exploit/multi/http/rails_activestorage_vips_rce.md

bundle exec rubocop modules/exploits/multi/http/rails_activestorage_vips_rce.rb spec/modules/exploits/multi/http/rails_activestorage_vips_rce_spec.rb
2 files inspected, no offenses detected

MSF_DATABASE_CONFIG=/tmp/msf_test_database.yml bundle exec rspec spec/modules/exploits/multi/http/rails_activestorage_vips_rce_spec.rb
56 examples, 0 failures

Live validation against Rails 8.0.5 with only VARIATION_KEY supplied and SUBMITURI set to an invalid path:

[*] Using configured payload cmd/unix/reverse_bash
[+] Selected the 256x256 raw text-read layout (32512 bytes per request)
[+] 127.0.0.1:3003 - The target is vulnerable. Recovered /proc/version with the 256x256 raw layout
[*] Reading up to 65536 bytes from /proc/self/environ
[+] Recovered SECRET_KEY_BASE from /proc/self/environ
[*] Triggering the ImageProcessing send/spawn variation using a verifier key derived from /proc/self/environ
[*] Command shell session 1 opened

uid=1000(rails) gid=1000(rails) groups=1000(rails)

Live validation against Rails 6.0.6.1 with only VARIATION_KEY supplied and SUBMITURI set to an invalid path:

[*] Using configured payload cmd/unix/reverse_bash
[+] Selected the 100x100 sharpened text-read layout (4900 bytes per request)
[+] 127.0.0.1:3013 - The target is vulnerable. Recovered /proc/version with the 100x100 sharpened layout
[*] Reading up to 65536 bytes from /proc/self/environ
[*] Detected SHA1 Active Support verifier signatures
[*] Detected the Active Support marshal message serializer
[*] Validated SHA1 key derivation against a signed blob ID
[+] Recovered SECRET_KEY_BASE from /proc/self/environ
[*] Triggering the ImageProcessing send/spawn variation using a verifier key derived from /proc/self/environ
[*] Command shell session 1 opened

uid=1000(rails) gid=1000(rails) groups=1000(rails)

Additional live validation completed:

  • Rails 6.0.6.1 vulnerable target with VARIATION_KEY, the legacy REPRESENTATIONURI route, and the default Unix command payload
  • Rails 6.1.7.10 vulnerable target with VARIATION_KEY, redirect and legacy REPRESENTATIONURI routes, and the default Unix command payload
  • Rails 8.0.5 vulnerable target with VARIATION_KEY
  • Rails 8.0.5 vulnerable target with REPRESENTATIONURI
  • Rails 8.0.5 vulnerable target using the safe-form fallback path
  • Rails 8.0.5 vulnerable target with the native Ruby target
  • Rails 8.0.5.1 patched target without SECRET_KEY_BASE returning only HTTP 500s from crafted reads
  • Rails 8.0.5.1 patched target with operator-supplied SECRET_KEY_BASE returning Detected without exercising arbitrary file read
  • Default Unix command payload
  • Linux fetch Meterpreter payload
  • Native Ruby payload

Environment

Field Details
Operating System Ubuntu 24.04.4 LTS x86_64
Target Software/Hardware Ruby on Rails 6.0.6.1, 6.1.7.10, 8.0.5, and 8.0.5.1, Active Storage with Vips variant processor, Ruby 3.2, image_processing 1.14.0, ruby-vips ~> 2.2, libvips 8.16.1 built with -Dmatio=enabled
Docker Image / Vagrant Setup Controlled Docker lab under target/docker/

AI Usage Disclosure

AI-assisted tools were used during implementation and review, including OpenAI Codex and Anthropic Claude. They were used for code generation, documentation drafting, review, and test iteration. All exploit behavior and verification claims above were manually validated against controlled lab targets.

@jburgess-r7
jburgess-r7 marked this pull request as ready for review July 31, 2026 11:16
@Crypto-Cat
Crypto-Cat force-pushed the rails-activestorage-vips-rce branch from 9710288 to 3e5c874 Compare July 31, 2026 19:29
@smcintyre-r7 smcintyre-r7 moved this from Todo to Ready in Metasploit Kanban Aug 4, 2026
@cdelafuente-r7 cdelafuente-r7 self-assigned this Aug 6, 2026
@cdelafuente-r7 cdelafuente-r7 moved this from Ready to In Progress in Metasploit Kanban Aug 6, 2026
@cdelafuente-r7 cdelafuente-r7 added the rn-modules release notes for new or majorly enhanced modules label Aug 6, 2026
@jburgess-r7
jburgess-r7 marked this pull request as draft August 6, 2026 10:04
@jburgess-r7
jburgess-r7 marked this pull request as ready for review August 6, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rn-modules release notes for new or majorly enhanced modules

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

4 participants