Сделай сам: dll hijacking под MS Office для самых маленьких

    Прошло уже три дня с тех пор, как исследователь Parvez Anwar опубликовал информацию о множественных dll hijacking уязвимостях в продуктах Microsoft Office, а какой-либо реакции не наблюдается. Ни CVE, ни сообщений на специализированных ресурсах, Windows Update не качает свежих патчей. Что ж, может, так и нужно, может быть, это не уявимость, а особенность продукта?
    Между тем, эксплуатация этой особенности проста и доступна даже ребенку. И, раз уж производитель пока эту «фичу» не удалил, почему бы не написать о ней небольшую статью.

    Речь пойдет о Windows 7. Работает ли это на других версиях — мне на текущий момент неизвестно, нужно проверять. Принцип действия описываемого явления (как и многих других, впрочем) основан на старой доброй технологии COM/OLE/ActiveX.
    Технология COM призвана воплощать ООП и повторное использование кода, позволяя любым приложениям использовать однажды созданные кем-либо классы (или компоненты), если эти классы зарегистрированы в системе. Регистрация компонента по сути представляет собой соответствующие записи в реестре. Каждому классу при его создании назначается уникальный 16-байтовый идентификатор — CLSID, который будет однозначно определять этот компонент в любое время на любом
    компьютере. Глобальные идентификаторы всех зарегистрированных в системе классов содержит ветка реестра HKEY_CLASSES_ROOT\CLSID.



    Исполняемый код компонента должен быть оформлен в виде библиотеки .dll (на самом деле не всегда, но для данной задачи можно упростить). Ссылка на библиотеку содержится в подключе InprocServer32 ключа реестра, соответствующего компоненту.



    В случае, когда приложение хочет использовать функциональность, реализованную одним из компонентов, оно отправляет системе запрос на создание экземпляра класса (при этом передается CLSID этого класса). Если такой класс зарегистрирован, система читает реестр и подгружает нужную .dll в адресное пространство процесса, затем вызывает из этой библиотеки код, создающий нужный объект.

    А что же приложения MS Office? Кроме того, что они тоже под завязку нашпигованы технологией COM (и даже сами являются COM-объектами), они еще и позволяют создавать/читать документы, содержащие элементы ActiveX.
    Фактически такой документ представляет собой файл, содержащий (помимо текста, изображений, форматирования и т.п.) идентификатор компонента и некоторую информацию о свойствах встраиваемого объекта. Давайте посмотрим, как это выглядит на практике.

    Открываем MS Word. Если у вас не подключена вкладка «Developer»/«Разработчик», необходимо подключить ее в настройках: File->Options->Customize Ribbon, Файл->Параметры->Настроить ленту, Файл->Параметры Word->Показывать вкладку «Разработчик» на ленте и т.п., в зависимости от того, какая версия MS Office у вас установлена.



    Переходим во вкладку «Разработчик» и выбираем кнопку с молотком и гаечным ключом «Инструменты из предыдущих версий».



    Затем похожую кнопку «Другие элементы управления».



    В появившемся окне выберите ActiveX компонент по своему вкусу, мне нравится Microsoft Forms 2.0 Command Button.





    Если открыть реестр и поискать по имени компонента, можно обнаружить, что CLSID нашего контрола

    {D7053240-CE69-11CD-A777-00DD01143C57}, а библиотека, содержащая его исполняемый код — FM20.DLL.





    Что же будет представлять собой документ, который мы создали? Давайте сохраним его и посмотрим.
    Формат .docx это всем известный ZIP. Распаковываем любой подходящей утилитой.



    Архив содержит несколько папок с файлами. Нам нужен word\activeX\activeX1.xml
    Открываем его обычным текстовым редактором и видим примерно такое содержимое.

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <ax:ocx ax:classid="{D7053240-CE69-11CD-A777-00DD01143C57}" ax:persistence="persistStorage" r:id="rId1" xmlns:ax="http://schemas.microsoft.com/office/2006/activeX" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"/>


    Как видно, CLSID элемента управления присутствует и легко может быть заменен.

    Теперь нужно сказать пару слов о том, на что, собственно, его можно заменить, а также о том, что такое dll hijacking, и почему это все работает.

    Заменить CLSID можно на CLSID любого другого элемента управления, и не только элемента управления, но и любого ActiveX, и даже не только ActiveX, но и любого COM-класса, зарегистрированного в системе (можно и на любой случайный GUID, но это ни к каким интересным последствиям не приведет).

    Все дело в том, что, прочитав идентификатор из документа, MS Word передаст его системе, система прежде всего попытается подгрузить библиотеку в память процесса и вызвать из нее первые функции (DllMain, DllGetClassObject, IClassFactory::CreateInstance и т.д.). И только после этого приложение начнет выяснять, что это за библиотека, что за компонент, можно ли добавлять его в документ, и нужно это ему вообще. Запросто может оказаться, что компонент не подходит по каким-то критериям, но это выясняется уже после того, как его исполняемый код оказался в виртуальной памяти процесса и получил управление. Он не будет выгружен даже после того, как MS Word точно установил, что ему этот класс не нужен! Такое поведение приводит к целому ряду любопытных явлений, в том числе — к описываемому в данной заметке.

    Теперь о dll hijacking. «Угон динамической библиотеки» — обычное, изначальное и даже в чем-то логичное поведение приложения Windows, когда оно ищет необходимую ему библиотеку в той директории, которая является для него текущей, и только затем — в определяемых настройками ОС местах. Все бы было ничего, если бы злоумышленники довольно скоро (и довольно давно) не догадались, что можно положить рядом с документом или ярлыком собственную библиотеку с таким же названием, как и у
    библиотеки, которую ожидает найти приложение.
    Вообще-то этой технике уже много лет, Microsoft борется с ней давно, упорно, и, как можно видеть, до сих пор не вполне результативно.

    На этот раз исследователи обнаружили затерянные в недрах операционной системы Windows 7 несколько dll, которые подгружают другие dll, и ищут их — до сих пор! — в текущей директории процесса. Эти Microsoft'ом забытые оснастки для консоли управления, присадки для Oracle'а и что-то еще столь же известное и часто используемое — оказались еще и COM-классами. Которые, как вы уже догадались, мы можем встроить в обычный документ MS Office.

    Вернемся к нашему MS Word и поменяем CLSID в распакованном документе на любой удобный из отчета
    Parvez Anwar
    . Например, на первый — {394C052E-B830-11D0-9A86-00C04FD8DBF7}.

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <ax:ocx ax:classid="{394C052E-B830-11D0-9A86-00C04FD8DBF7}" ax:persistence="persistStorage" r:id="rId1" xmlns:ax="http://schemas.microsoft.com/office/2006/activeX" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"/>


    Запакуем документ (при необходимости переименуем его обратно в .docx).



    Теперь нам нужна собственная dll под именем elsext.dll. Неважно, на чем вы ее создадите, главное, чтобы она имела ту же разрядность, что и пакет MS Office, была способна к загрузке, и вы могли бы добавить свой код в DllMain или DllGetClassObject. Я возьму старый добрый VC6 — у меня 32хбитный офис.

    #include <windows.h>
    
    int __stdcall DllMain (HANDLE, DWORD, LPVOID)
    {
        MessageBox (0, "Hello Habrahabr!", 0, MB_ICONEXCLAMATION);
    
        return true;
    }


    Осталось положить нашу elsext.dll в одну директорию (можно в общей сетевой папке) с модифицированным документом и попросить пользователя этот документ открыть/прочитать.



    Еще один момент: с dll hijacking, как вы помните, Microsoft борется. Поэтому при запуске MS Word меняет текущую директорию на «Документы» текущего пользователя. К сожалению (или к счастью) при вызове приложения для открытия документа (например, двойным щелчком в explorer) MS Word сначала пытается открыть документ со всеми вытекающими последствиями, и только потом изменяет свою текущую директорию на «Документы». Отсюда вытекает тот факт, что наша dll будет подгружена только в том случае, если пользователь открыл документ двойным щелчком, и MS Word не был до этого запущен (иначе загрузится elsext.dll из system32).
    • +44
    • 28k
    • 5
    Digital Security
    214,00
    Безопасность как искусство
    Поделиться публикацией

    Комментарии 5

      –1
      Если удалось на компьютер жертвы «засунуть» грязный DLL, то в чем проблема была засунуть вместо него сразу вирусняк? Положить ведь нужно еще и в ту же папку…

      Хотелось увидеть пример использования какой-нибудь стандартной уже установленной в систему DLL и её эксплуатацию, типа через стандартную библиотеку отрисовки кнопки — произвести запись в произвольный файл произвольного текста, и последующий запуск через что-нибудь.
        +2
        Одно дело положить вирусняк, а другое дело — его исполнить. Более или менее осведомленный в области IT пользователь не станет запускать непонятный exe-шник, а вот docx файл на первый взгляд не кажется опасным. А если в сетевой папке 40+ файлов, то dll там запросто затеряется.
          0
          Хотелось увидеть пример использования какой-нибудь стандартной уже установленной в систему DLL и её эксплуатацию


          Можно посмотреть здесь, например.
          0
          То чувство, когда твой Word настолько старый, что не может открыть файл с уязвимостью без преобразования .docx в .doc.
            +1
            CLSID'ы ActiveX'ов в .doc отлично правятся в hex-редакторе. Нужно найти 16-байтовую последовательность идентификатора и заменить своей.

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

          Самое читаемое