Merge pull request #1310 from HackTricks-wiki/update_Marshal_madness__A_brief_history_of_Ruby_deseriali_20250820_063337

Marshal madness A brief history of Ruby deserialization expl...
This commit is contained in:
SirBroccoli 2025-08-20 16:01:52 +02:00 committed by GitHub
commit 0a9d007403

View File

@ -1082,7 +1082,60 @@ This payload is compiled into binary Ruby code and concatenated with a carefully
Using the arbitrary file write vulnerability, the attacker writes the crafted cache file to the computed location. Next, they trigger a server restart (by writing to tmp/restart.txt, which is monitored by Puma). During restart, when Rails requires the targeted file, the malicious cache file is loaded, resulting in remote code execution (RCE). Using the arbitrary file write vulnerability, the attacker writes the crafted cache file to the computed location. Next, they trigger a server restart (by writing to tmp/restart.txt, which is monitored by Puma). During restart, when Rails requires the targeted file, the malicious cache file is loaded, resulting in remote code execution (RCE).
### Ruby Marshal exploitation in practice (updated)
Treat any path where untrusted bytes reach `Marshal.load`/`marshal_load` as an RCE sink. Marshal reconstructs arbitrary object graphs and triggers library/gem callbacks during materialization.
- Minimal vulnerable Rails code path:
```ruby
class UserRestoreController < ApplicationController
def show
user_data = params[:data]
if user_data.present?
deserialized_user = Marshal.load(Base64.decode64(user_data))
render plain: "OK: #{deserialized_user.inspect}"
else
render plain: "No data", status: :bad_request
end
end
end
```
- Common gadget classes seen in real chains: `Gem::SpecFetcher`, `Gem::Version`, `Gem::RequestSet::Lockfile`, `Gem::Resolver::GitSpecification`, `Gem::Source::Git`.
- Typical side-effect marker embedded in payloads (executed during unmarshal):
```
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
```
Where it surfaces in real apps:
- Rails cache stores and session stores historically using Marshal
- Background job backends and file-backed object stores
- Any custom persistence or transport of binary object blobs
Industrialized gadget discovery:
- Grep for constructors, `hash`, `_load`, `init_with`, or side-effectful methods invoked during unmarshal
- Use CodeQLs Ruby unsafe deserialization queries to trace sources → sinks and surface gadgets
- Validate with public multi-format PoCs (JSON/XML/YAML/Marshal)
## References
- Trail of Bits Marshal madness: A brief history of Ruby deserialization exploits: https://blog.trailofbits.com/2025/08/20/marshal-madness-a-brief-history-of-ruby-deserialization-exploits/
- elttam Ruby 2.x Universal RCE Deserialization Gadget Chain: https://www.elttam.com/blog/ruby-deserialization/
- Phrack #69 Rails 3/4 Marshal chain: https://phrack.org/issues/69/12.html
- CVE-2019-5420 (Rails 5.2 insecure deserialization): https://nvd.nist.gov/vuln/detail/CVE-2019-5420
- ZDI RCE via Ruby on Rails Active Storage insecure deserialization: https://www.zerodayinitiative.com/blog/2019/6/20/remote-code-execution-via-ruby-on-rails-active-storage-insecure-deserialization
- Include Security Discovering gadget chains in Rubyland: https://blog.includesecurity.com/2024/03/discovering-deserialization-gadget-chains-in-rubyland/
- GitHub Security Lab Ruby unsafe deserialization (query help): https://codeql.github.com/codeql-query-help/ruby/rb-unsafe-deserialization/
- GitHub Security Lab PoCs repo: https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization
- Doyensec PR Ruby 3.4 gadget: https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization/pull/1
- Luke Jahnke Ruby 3.4 universal chain: https://nastystereo.com/security/ruby-3.4-deserialization.html
- Luke Jahnke Gem::SafeMarshal escape: https://nastystereo.com/security/ruby-safe-marshal-escape.html
- Ruby 3.4.0-rc1 release: https://github.com/ruby/ruby/releases/tag/v3_4_0_rc1
- Ruby fix PR #12444: https://github.com/ruby/ruby/pull/12444
- Trail of Bits Auditing RubyGems.org (Marshal findings): https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}