Анализ уязвимости CVE-2024-38227 в Microsoft SharePoint

65a2e38634e0db3ef79e7702ab78b3e8.jpg

10 сентября компания Microsoft выпустила очередную подборку обновлений, устранив 79 уязвимостей в различных продуктах. Наше внимание привлекли патчи для Microsoft SharePoint — обширной системы с функциями управления сайтами (content management system, CMS). Из пяти уязвимостей, вошедших в сентябрьский выпуск, четыре позволяли исполнять сторонний код (remote code execution, RCE), одна — создавала угрозу DoS. Мы выбрали для анализа CVE-2024–38227 — RCE-уязвимость привилегированного пользователя. Для нас такое исследование — это возможность изучить сам Microsoft SharePoint и понять текущую теорию его эксплуатации (state-of-the-art).

Об исследуемом продукте

Microsoft SharePoint — CMS с широким спектром функциональности. Он позволяет создавать сайты,  от внутренних корпоративных сервисов до порталов документооборота. Помимо этого, архитектура Microsoft SharePoint подразумевает взаимодействие нескольких серверов в рамках одной «фермы». Все это предоставляет широкие возможности, но при этом сильно увеличивает поверхность атаки. Microsoft SharePoint написан на C#, использует в качестве веб-сервера IIS, а в качестве хранилища данных — MS SQL.

Начало исследования

Как и всегда, при анализе closed-source-ПО стояла задача понять, что конкретно было изменено при обновлении. Для этого мы выбрали классический метод сравнения и установили Microsoft SharePoint 2019 два раза: версии до и после патча.

Microsoft SharePoint содержит в себе около 700 исполняемых файлов, из них по меньшей мере 400 — это DLL на C#. Очевидно,  здесь нужна какая-то автоматизация. Первой реакцией в таких проектах обычно бывает желание декомпилировать все DLL через dnSpy или похожие декомпиляторы для C# и потом диффать уже текст, но такой подход дал очень много фолсов (да, мы все-таки его проверили). Чтобы провести сравнение более корректно, нужно анализировать по-настоящему — на уровне IR. Поэтому мы перешли на BinDiff с IDA, и вот как:

  1. Рекурсивно пробежали по старому и новому проектам и конвертировали все найденные исполняемые файлы в IDB.

  2. Конвертировали IDB в BinExport.

  3. Сравнили файлы BinExport через BinDiff, результат записали в общую базу.

После сравнения оказалось, что по-настоящему изменены только два файла:

c17e2c74c95d1dfdd82ee0bae035de3e.png

Среди списка измененных файлов нас, конечно, заинтересовал Microsoft.SharePoint.dll. В диффе отлично видны патчи, связанные с десериализацией. Был добавлен метод IsAllowedIDictionaryType в класс SPUtility, который проверяет тип, реализующий интерфейс IDictionary,  на присутствие в разрешенном списке проверенных типов.

c61159608f6a27a81bcb9102241c9c8d.png

Этот метод используется в классе SPAutoSerializingObject, уязвимость в котором, по данным ZDI,  приводит лишь к DoS.

Намного сильнее нас заинтересовали следующие изменения в классах RemoterService и LobSystemParser, которые, предположительно, соответствуют CVE-2024–38227 и CVE-2024–38228:

Изменения метода ReadXml класса LobSystemParser

Изменения метода ReadXml класса LobSystemParser

Изменения метода ExecuteBdcMethod класса RemoterService

Изменения метода ExecuteBdcMethod класса RemoterService

Судя по содержимому исключений, можно предположить, что Microsoft убрала возможность исполнения .NET assembly. Выглядит как RCE, не так ли?

Исследование уязвимости


Для дальнейшего анализа здесь нужно провести исследование изменения метода ExecuteBdcMethod класса RemoterService: для начала нужно понять, как его вызвать. Класс RemoterService — это реализация интерфейса IRemoteExecutionService. Это ServiceContract, в рамках которого определена операция ExecuteBdcMethod.

Класс RemoterService реализует IRemoteExecutionService

Класс RemoterService реализует IRemoteExecutionService

Интерфейс IRemoteExecutionService

Интерфейс IRemoteExecutionService

В этот момент мы просмотрели референсы на RemoterService и нашли файл BdcRemoteExecutionService.svc. Из конфигурации IIS следует, что к этому SVC-файлу можно обратиться по пути /_vti_bin/BdcRemoteExecutionService.svc.

efb9a8f9a21bc34e2eb74aeef8655621.png4e6dd72c6ce7e305b5dedd77a2448dab.png

Интересующий нас метод можно вызвать, обратившись к сервису с помощью WCF (Windows Communication Foundation).

Windows Communication Foundation (WCF) — «framework for building service-oriented applications». Этот фреймворк позволяет реализовать коммуникацию распределенных сервисов. Взаимодействие между сервисами выполнено в виде взаимодействия с сущностями ЯП как на стороне клиента, так и на стороне сервера.

Мы не смогли найти готовую информацию о том, как WCF работает на уровне сетевого взаимодействия. Сам WCF использует SOAP, однако не понятно, что использовать в качестве namespace и SOAPAction, если этого явно не указано в контракте. Поэтому для того, чтобы понять, что именно указывать, мы создали небольшой стенд с тестовым сервисом на C#, который использует WCF, и проанализировали трафик.

0115805ff0baa7c513bfb730dc740a0b.png

Как оказалось, если namespace не указан явно, то по умолчанию используется http[://]tempuri[.]org. В SOAPAction требуется указать namespace (в нашем случае http[://]tempuri[.]org), тип ServiceContract и тип OperationContract.

В нашем случае получается, что в качестве SOAPAction нужно указать http[://]tempuri[.]org/IRemoteExecutionService/ExecuteBdcMethod.

На основании полученной информации был составлен аналогичный запрос для вызова метода из BdcRemoteExecutionService.svc.

567670cfe92bf8c1aeb9a58d71b5cd4a.pngМетод успешно вызвался, но сработало исключение

Метод успешно вызвался, но сработало исключение

Мы вызвали интересующий нас метод. Теперь стоит понять, что это за сервис и что делает этот метод. Судя по названию класса, метода и его аргументов, мы можем вызывать методы некоего BDC.

BDC (Business Data Connectivity service) — сервис внутри Microsoft SharePoint, позволяющий создавать интеграцию с данными из внешних источников. BDC предоставляет возможность выполнять CRUDQ-операции над данными из внешних источников. Источниками данных могут быть SQL-соединение, .NET assembly, WCF-сервис.

С помощью легитимной функциональности, доступной привилегированному пользователю, мы импортируем BDC-модель c .NET assembly:

Затем остается лишь выполнить запрос для вызова ExecuteBdcMethod, предварительно заполнив параметры нужными значениями, чтобы получить произвольное исполнение кода.

Процесс win32calc.exe на хосте, где запущен SharePoint

Процесс win32calc.exe на хосте, где запущен SharePoint

Выводы

Когда мы решили исследовать CVE-2024–38227,  мы и представить не могли, насколько комплексным и замысловатым окажется Microsoft SharePoint.

Сложный дизайн и нагруженная архитектура серьезно усложняют анализ подобных проектов и создают настоящий челлендж в те моменты, когда нужно отследить потоки данных и кода. Однако в ходе таких исследований мы нарабатываем разнообразный тулинг и накапливаем знания, которые нужны в дальнейшем для применения в сервисах с похожим стеком.

Искренне надеемся, что вам был полезен этот ресерч. Stay tuned!

Автор статьи:

Елизар Батин, старший специалист по исследованию уязвимостей

© Habrahabr.ru