
Анализ уязвимости CVE‑2024‑38227 в Microsoft SharePoint
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, и вот как:
- Рекурсивно пробежали по старому и новому проектам и конвертировали все найденные исполняемые файлы в IDB.
- Конвертировали IDB в BinExport.
- Сравнили файлы BinExport через BinDiff, результат записали в общую базу.
После сравнения оказалось, что по‑настоящему изменены только два файла:

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

Этот метод используется в классе SPAutoSerializingObject
, уязвимость в котором, по данным ZDI, приводит лишь к DoS.
Намного сильнее нас заинтересовали следующие изменения в классах RemoterService
и LobSystemParser
, которые, предположительно, соответствуют CVE‑2024‑38227 и CVE‑2024‑38228:

ReadXml
класса LobSystemParser

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

RemoterService
реализует IRemoteExecutionService

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


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

Как оказалось, если namespace
не указан явно, то по умолчанию используется http[://]tempuri[.]org
. В SOAPAction
требуется указать namespace
(в нашем случае http[://]tempuri[.]org
), тип ServiceContract
и тип OperationContract
.
В нашем случае получается, что в качестве SOAPAction
нужно указать http[://]tempuri[.]org/IRemoteExecutionService/ExecuteBdcMethod
.
На основании полученной информации был составлен аналогичный запрос для вызова метода из BdcRemoteExecutionService.svc
.


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

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

win32calc.exe
на хосте, где запущен SharePoint
Когда мы решили исследовать CVE‑2024‑38227, мы и представить не могли, насколько комплексным и замысловатым окажется Microsoft SharePoint.
Сложный дизайн и нагруженная архитектура серьезно усложняют анализ подобных проектов и создают настоящий челлендж в те моменты, когда нужно отследить потоки данных и кода. Однако в ходе таких исследований мы нарабатываем разнообразный тулинг и накапливаем знания, которые нужны в дальнейшем для применения в сервисах с похожим стеком.