New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 1 user
Status: Fixed
Owner:
Closed: Jul 17
Cc:

Blocking:
issue 1096
issue 1100



Sign in to add a comment
Cisco: WebEx Various GPC Sanitization bypasses permit Arbitrary Remote Command Execution
Project Member Reported by taviso@google.com, Jul 6 Back to list
In   issue 1096   and   issue 1100   I described various flaws in the way the Cisco WebEx extension worked, permitting remote command execution. Earlier this week a former colleague from Chrome Security, Cris Neckar from Divergent Security, pointed out that there had been some changes to the way atgpcext worked, and it looked like there may be some new problems.

I see several problems with the way sanitization works, and have produced a remote code execution exploit to demonstrate them. This extension has over 20M active Chrome users alone, FireFox and other browsers are likely to be affected as well.

1. JSON parsing discrepancies.

WebEx filters various critical JSON properties in the extension code, here is an example:

...
                   var c = e.GpcExtName;
                    if (c && (c = c.trim(),
                    "atgpcext" != c.toLowerCase() && "atgpcext" != atob(c).toLowerCase().trim()))
                        return !1;
                    var d = e.GpcUnpackName;
                    if (d && (d = d.trim(),
                    "atgpcdec" != d.toLowerCase() && "atgpcdec" != atob(d).toLowerCase().trim()))
                        return !1;
                    var f = e.GpcInitCall;
                    if (f && !a.verifyScriptCall(atob(f.trim())))
...

Unfortunately, The atgpcext library uses it's own native JSON parser to process messages from the client, which handles property names differently. Therefore, you can create a JSON object like this:

object={ "foo": 1, "foo\0": 2 }

Chrome will see object.foo = 1, atgpcext will see object.foo = 2. This difference in JSON parsing effectively defeats all sanitization and filtering in the WebEx extension.

2. GpcScript verification Regex is incomplete.

WebEx includes a scripting language that allows WebEx messages to interact with native components, this scripting language must pass through this verification function:

    a.verifyScriptCall = function(a) {
        var b = /^(WebEx_|A[sT][ADEPSN]|conDll|RA[AM])|^(Ex|In)it|^(FinishC|Is[NS]|JoinM|[NM][BCS][JRUC]|Set|Name|Noti|Trans|Update)|^(td|SCSP)$/;
        if (10240 < a.length)
            return !1;
        a = a.split(";");
        for (var c = 0; c < a.length; c++) {
            var d = a[c].trim()
              , f = ""
              , g = d.indexOf("=");
            0 <= g && (d = d.substring(g + 1).trim());
            g = d.indexOf("(");
            0 <= g && (f = d.substring(g + 1),
            d = d.substring(0, g).trim());
            g = f.split(",");
            if (1024 < f.length || 20 < g.length || 0 < d.length && !d.match(b))
                return !1
        }
        return !0
    }


This is incomplete, because the left hand side of assignments are not validated, but can include function calls in Cisco's language.

e.g., the following GpcInitCall is accepted, and works:

"_wsystem(Calc)=WebEx_Exploit;"

This allows you to call any exported routine from any library, and results in arbitrary remote code execution.

3. Whitelisted Function Calls are not necessarily safe to call.

If we assume for a moment that the Verification Regex worked, many whitelisted exported routines from WebEx modules accept object Parameters, for example atmccli!WebEx_AutoLaunch, which is permitted but the first parameter is an attacker controlled object. The routine immediately makes a virtual call, so the following call would result in arbitrary code execution:

{
   ObjectAddress: "1094795585",
   GpcInitCall: "WebEx_AutoLaunch(ObjectAddress, ObjectAddress, ObjectAddress);"
}

Note that the webexlauncher catches the access violation exception, but this is irrelevant to exploitation.

4. No prevention against downgrade attacks.

You can simply set a custom GpcExtVersion and GpcUrlRoot and roll back to an older version. The signature is verified, but as old versions were signed at one point they are permitted and loaded.

This means fixing any vulnerabilities in native components is pointless, because an attacker can just roll you back to a vulnerable version without any user interaction.


Here is a working demo: https://lock.cmpxchg8b.com/JauChal3/webex.html

CREDIT

These vulnerabilities were found by Tavis Ormandy from Google Project Zero and Cris Neckar of Divergent Security.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available, the bug report will become
visible to the public.

 
Windows 7-2017-07-06-12-32-02.png
91.3 KB View Download
Project Member Comment 1 by taviso@google.com, Jul 6
Labels: -Reported-2017Jul-6 Reported-2017-Jul-6
Response from Cisco:

Hello Tavis,
 
Thank you for taking the time to provide this detailed report to Cisco. I have opened PSIRT-1498247176 to track this on our end and have engaged the WebEx team. I have taken ownership of the issue and may reach out with additional questions from engineering as they arise.
 
Please feel free to reach out should you discover anything else as we work to resolve these issues.

Project Member Comment 2 by taviso@google.com, Jul 6
I asked Cisco the following, lets see what they say:

Thanks, I'm wondering if it isn't possible to make the GpcInitCall blobs signed by Cisco? Do you know if the WebEx team really lets third parties write their own scripts?

I really think it's going to be hard to write a good quality sanitization routine here.
Project Member Comment 3 by taviso@google.com, Jul 6
I notified the CWS team who have their own process for managing vulnerabilities in extensions.

Project Member Comment 4 by taviso@google.com, Jul 6
Cc: cdn@chromium.org
Project Member Comment 5 by taviso@google.com, Jul 6
Cc: -cdn@chromium.org cnec...@divergentsecurity.com
Project Member Comment 6 by taviso@google.com, Jul 6
Description: Show this description
Project Member Comment 7 by taviso@google.com, Jul 7
I updated the testcase to work on Firefox, the changes required were minimal.
Project Member Comment 8 by taviso@google.com, Jul 7
I pinged mozilla security team to let them know that they may need to prioritize an upcoming addon review (Mozilla manually approve all addons).

I don't know how webex works in IE and Edge, but dealing with Microsoft is such a huge pain that I'm just going to plead ignorance and let them figure it out themselves.

 
Project Member Comment 9 by taviso@google.com, Jul 7
Update from Cisco:

The WebEx team is actively investigating your reports. As they work, there may be some changes to the sites. The changes will be incremental, but we will notify you when we are ready to disclose the complete fix. I’ll keep you posted as we progress through the updates.
Comment 10 Deleted
Project Member Comment 11 by taviso@google.com, Jul 10
It looks like Cisco have released a new version of the NativeModuleHost over the weekend, I asked Cisco if this was a fix for the issues I reported.

Cisco replied that it does fix the downgrade attack I reported, a necessary change before they can fix the other issues.

Project Member Comment 12 by taviso@google.com, Jul 12
Cisco sent me a draft version of a new extension to look at to fix some of the parsing problems.

1. They've added a whitelist of acceptable Gpc scripts. This is excellent, it now has to match a hardcoded sha256.
2. They proposed a change to filter objects for nul bytes, which we believe is the only case that isn't handled. I ran it past some experts here at Google and we came up with some cases where it wouldn't work, and I sent the details to Cisco.

Thanks to David Ross, Aleksandr Dobkin and Max Justicz from Google security for the consult.


Project Member Comment 13 by taviso@google.com, Jul 12
Cc: fbr...@mozilla.com
For future reference, the fix Cisco proposed for the nul padding problem was to do this before JSON.parse():

if (message.includes('\\u0000'))
 return false;

I checked with some experts here and they believe this will work, but only if message is guaranteed to be a String object. That is not enforced in the content script, so a malicious website could dispatchEvent an Array, and Array.includes() does something different than String.includes().

> x = ['{"foo\\u0000": "bar"}']
> x.includes('\\u0000')
false
> JSON.stringify(JSON.parse(x))
"{"foo\u0000":"bar"}"

This defeats the whole check. Cisco are going making a new version that enforces the message type.
Project Member Comment 14 by taviso@google.com, Jul 12
That was quick, Cisco sent me a draft of version 1.0.12 that verifies the object is a String.

I believe we're just waiting for them to push the fixes to the binary components, upload the final new extension version, and then we can consider this resolved.
Do you know if they are resolving the regression of the origin check in the same patch?
Project Member Comment 16 by taviso@google.com, Jul 12
I *think* they want to move the origin check into the binary, I'm not 100% sure how this will work though...

I'd be happier if there was at least a prompt, but i'm guessing they're not gonna like that idea.
Yeah, given the history it feels like always prompting (even from webex.com) is the safest thing to do. One extra click doesn't seem like too much of a barrier for someone who is trying to join a meeting through an external app. 
Project Member Comment 18 by taviso@google.com, Jul 13
It sounds like we're on track for a binary release and extension update later today, and Cisco have an advisory ready to go when the rollout is finished.

Project Member Comment 19 by taviso@google.com, Jul 13
I had a conference call with Cisco, rolling out fixes to all WebEx customers is apparently quite challenging due to some unusual deployments.

It sounds like Monday is now the plan.
Project Member Comment 20 by taviso@google.com, Jul 17
Sign in to add a comment