Cybersecurity-Projects/PROJECTS/beginner
CarterPerez-dev 21ecc0eece feat(rube): M5 vulnerable target - end-to-end RCE over HTTP, with the defense beside it
Sinatra on webrick in a container, storing session state as a base64 Marshal
blob in a cookie. Three endpoints: /render deserializes and compiles the
session template, /render/safe inspects the stream first, /canary reports
execution. Runs read-only, unprivileged, with a 1MB noexec tmpfs, on a high
configurable host port.

Gate proves three things and the third is what stops the defense being a brick:

  PASS  HTTP request achieved code execution through Marshal.load
  PASS  defended endpoint rejected the identical payload
  PASS  defended endpoint still serves a legitimate session

Two findings that change the defensive design.

Sink tags do not catch this chain. The working payload produces ZERO sink-tag
hits. ERB defines no marshal_load, so it serializes as a plain object with
instance variables and carries no u, U or d tag. The defended endpoint rejected
it on the class allowlist, and an application that allowlisted ERB as a
legitimate template class would have passed it through untouched. A gadget does
not need a marshal_load hook, it needs an object whose ivars the application
later feeds to a dangerous method. The dangerous call site lives in the
application, not in the serialized class. Any policy treating absence of sink
tags as safe is defeated by this exact public payload.

A legitimately initialized ERB cannot be serialized at all. @_init holds
self.class.singleton_class and Marshal raises TypeError: singleton class can't
be dumped. So the guard is not a flag an attacker might satisfy, it is anchored
to a value the serializer physically cannot reproduce. Any ERB an attacker can
serialize necessarily lacks a valid @_init. The generalized pattern for learn/:
do not validate the untrusted object, anchor trust to something unreachable
through the channel.

Also fixes a gate that skipped a control silently. The benign-session check
produced no output because POST with no body returns WEBrick LengthRequired,
and the script treated an empty result as nothing to test rather than as a
failure. It now fails loudly.

70 tests, 151 assertions, 0 failures. Target app excluded from the gem
manifest, verified at 0 files.
2026-07-26 10:17:23 -04:00
..
base64-tool Update DEMO.md 2026-04-28 18:01:21 -04:00
c2-beacon chore(deps): bump starlette in /PROJECTS/beginner/c2-beacon/backend 2026-06-04 17:25:29 +00:00
caesar-cipher chore: add demos for projects, update haskell-reverse-proxy modules, refresh siem assets 2026-04-26 23:12:48 -04:00
canary-token-generator style(canary): format config_test.go with golines (max-len 80) 2026-07-19 03:18:17 -04:00
deserialization-gadget-lab feat(rube): M5 vulnerable target - end-to-end RCE over HTTP, with the defense beside it 2026-07-26 10:17:23 -04:00
dns-lookup chore: add demos for projects, update haskell-reverse-proxy modules, refresh siem assets 2026-04-26 23:12:48 -04:00
firewall-rule-engine feat: sbom generator & vulnerability matcher + docstrings across 6 projects 2026-04-08 23:53:40 -04:00
hash-cracker cracked 2026-05-23 05:01:01 -04:00
keylogger Update README.md 2026-06-02 09:16:11 -04:00
linux-cis-hardening-auditor cracked 2026-05-23 05:01:01 -04:00
linux-ebpf-security-tracer add: AGPL 3.0 license files to hash-cracker, ebpf tracer, dlp scanner 2026-04-11 05:56:43 -04:00
metadata-scrubber-tool chore(deps): bump pypdf in /PROJECTS/beginner/metadata-scrubber-tool 2026-06-18 15:28:54 +00:00
network-traffic-analyzer ci(network-traffic-analyzer): drop ruff preview to keep lint green across versions 2026-07-19 03:18:03 -04:00
simple-port-scanner cracked 2026-05-23 05:01:01 -04:00
simple-vulnerability-scanner Delete PROJECTS/beginner/simple-vulnerability-scanner/hf_readme.gif 2026-07-19 23:26:24 -04:00
steganography-multi-tool docs(crypha): add learn/ track and surface the built project (M9) 2026-07-19 03:06:49 -04:00
systemd-persistence-scanner chore: add demos for projects, update haskell-reverse-proxy modules, refresh siem assets 2026-04-26 23:12:48 -04:00