개요

  • (2018년 11월) Ruby 2.x Universal RCE Deserialization Gadget Chain: https://www.elttam.com/blog/ruby-deserialization/#content <– 여기를 읽고 있다.

내용 메모

  • 루비에서는 직렬화를 할 때 Marshal 클래스를 사용한다.
  • Marshal 클래스에는 dump 및 load 클래스가 있다.
  • 역직렬화 취약점은 개발자가 공격자가 직렬화된 객체가 바이너리 형식이기 때문에 볼 수 없거나 변조할 수 없다고 잘못 가정할 때 발생한다.
  • 전제 조건이 필요없는 개짓체인을 만드는 것이 목표(디폴트 라이브러리에서 찾는다)
  • 루비 2.5.3에서는 기본적으로 로드되는 클래스가 358개다. 이중 196개는 자체 인스턴스 메서드를 정의하지 않은 것이다.
  • 다른 라이브러리를 호출하는 가젯을 찾는 것이 require가 있는 코드를 찾는 것이다. 예를 들어 Gem 모듈에는 다음과 같이 zlib 라이브러리를 require하는 부분이 있다. 이 부분이 실행되면 Zlib 라이브러리가 로드된다.
module Gem
...
  def self.deflate(data)
    require 'zlib'
    Zlib::Deflate.deflate data
  end
...
end
  • 루비의 표준 라이브러리에서 타사의 라이브러리를 호출하는 경우도 하나 있었다고 한다. SortedSet 클래스는 타사의 rbtree 라이브러리를 로드한다.
...
class SortedSet < Set
...
  class << self
...
    def setup
...
          require 'rbtree'

더 유용한 가젯은 공격자가 컨트롤가능한 파라메터를 require에 전달하는 가젯이다. 이런 가젯은 파일시스템 상의 임의의 파일을 로딩할 수 있게 하므로, 스탠다드 라이브러리에 있는 어떤 가젯이던 사용할 수 있게 해준다. 여기에는 Charlie Somerville’s의 가젯체인에서 사용되는 ERB 가젯도 포함된다. 이런 가젯은 찾을 수 없었지만 require에 대해 일부 컨트롤을 제공해주는 가젯을 발견했다.

module Digest
  def self.const_missing(name) # :nodoc:
    case name
    when :SHA256, :SHA384, :SHA512
      lib = 'digest/sha2.so'
    else
      lib = File.join('digest', name.to_s.downcase)
    end

    begin
      require lib
...

참고 URL

  • https://www.elttam.com/blog/ruby-deserialization/#content
  • PHP wii 프레임워크의 개짓체인에 대한 이야기: https://blog.redteam-pentesting.de/2021/deserialization-gadget-chain/
  • 쉽게 설명한 개짓체인: https://medium.com/@dub-flow/deserialization-what-the-heck-actually-is-a-gadget-chain-1ea35e32df69
  • 그 뒤에 읽으면 좋은 야모리의 취약점 설명: https://yamory.io/blog/about-insecure-deserialization <– 이거 Sink부분이 이해가 안된다. 직접 Eclipse에서 실행해보면 이해가 될 것 같기도 하다.