Безопасность Microsoft Office: форматы документов

Всем привет!
Этой статьей мы открываем цикл, посвященный исследованию безопасности компонентов Microsoft Office. Речь в материале пойдет о форматах данных, шифровании и получении символов.
Когда в компании Microsoft задумывался и разрабатывался масштабный пакет офисных программ Microsoft Office, вероятно, создатели надеялись на успех. Сложно сказать, могли ли они рассчитывать на его триумфальное шествие по миру впоследствии, на то, что продукт станет фактическим стандартом, а существование его растянется на десятилетия. Однако можно уверенно утверждать, что массивность приложений, количество человеко-часов, затраченных на создание, развитие, поддержку обратной совместимости компонентов продукта способствовали появлению «тяжелого наследия» в виде устаревшего, написанного десятилетия назад программного кода, составляющего ядро приложений даже в последних версиях пакета. Требования, которые предъявлялись к коду двадцать лет назад, изменились. Сегодня во главу угла ставится кроссплатформенность, масштабируемость и безопасность. При этом, расходы на значительные изменения в продукте таковы, что Microsoft предпочитает подход «не сломано — не трогай», и старательно обеспечивает обратную совместимость с самыми древними форматами документов. Не обходится и без определенного давления со стороны коммерческих и государственных структур, которые также медленно и неохотно обновляют свои технологические парки, предпочитая привычные средства в ущерб развитию и безопасности.
zyar5tvhczkffkd1ypmayy8y01a.jpeg
Покопавшись в дебрях обработчиков файлов Microsoft Office, мы готовы представить вам это небольшое исследование.

Component Object Model и хранение данных


Начать стоит издалека, а именно с Объектной Модели Компонентов. Как вы, должно быть, знаете, Microsoft обожает делать свои продукты на основе этой технологии, и Microsoft Office не стал исключением.
Объектная модель компонентов COM — это стандарт, позволяющий ПО пользоваться сервисами, предоставляемыми другим ПО, независимо от того, где это ПО расположено (внутри одного процесса, в разных процессах или на разных компьютерах) и чем представлено (исполняемые файлы, управляемый код, или даже скриптовые языки). При этом программе-клиенту, называемой контейнером, не нужно вдаваться в подробности реализации сервиса (или компонента), достаточно знать его идентификатор класса, и, если такой зарегистрирован, хитроумная система маршалинга обеспечит прозрачное, бесшовное и довольно надежное взаимойдействие.

l65vgylqejqynhgbxtffkatowx0.png
Так может выглядеть использование приложением-контейнером разнородных компонетов независимо от их местоположения

На практике обычно подразумевается не столько сам стандарт, сколько его реализация в ОС семейства Windows. Первые версии COM были разработаны еще для 16-разрядных Windows в качестве основания для OLE (оно же теперь ActiveX). Изначальной целью разработки этих подсистем была возможность создания (!) составных документов Word и Excel для Windows 3.x, и они были выпущено на свет около 1991 года (в разных источниках даты расходятся).

Представим приложение на C#, которое использует несколько элементов ActiveX (элементы ActiveX являются COM-компонентами, предназначенными для взаимодействия с пользователем; определение неточное, но точного, судя по всему, не существует). Приложение-контейнер загружает внутрипроцессный компонент, написанный на плоском C для отрисовки изображения, компонент внутри другого процесса на этом же компьютере для загрузки веб-страницы и форму ввода строковых данных, которую отрисовывает компонент, выпоняющийся на другом компьютере.

irt0hzowsf63oft5ljm5b5p8soy.png

Работая с приложением, пользователь изменяет изображение, содержимое окна браузера и строки в полях ввода. Само приложение взаимодействует с компонентами, вызывая их методы и устанавливая их свойства, иными словами, изменяя внутреннее состояние объектов, о внутреннем устройстве которых не имеет представления.

В один прекрасный момент пользователь решает сохранить проделанную работу и нажимает кнопку «Save». Перед нашим приложением стоит грандиозная задача — записать на диск набор данных в совершенно разных форматах, о большей части которых (и данных, и форматов) приложению ничего не известно, да и находятся они для него в недосягаемости! Именно для решения этой задачи специалисты Microsoft и разработали одновременно с COM и «родной» для Component Object Model формат файла Compound File Binary Format, а вместе с ним систему интерфейсов для взаимодействия с этим форматом и их реализаций, объединяемых под именем Structured Storage.

Структурированное Хранилище COM


Для универсального доступа приложений и компонентов к сложному, к тому же закрытому, формату CFBF, для прозрачной как для контейнера, так и для компонентов замены одного формата другим, были разработаны библиотечные интерфейсы IStorage и IStream и соответствующие API. Виртуальная структура данных, к которой получает доступ приложение посредством этих интерфейсов, представлена системой вложенных каталогов — Хранилищ (Storages), каждый из которых может содержать некоторое число последовательностей байтов — Потоков (Streams), в которых и хранятся данные.

v7v5v_puh2x2sfq0mejbqjhkscu.png
Виртуальное представление формата CFBF (StructuredStorage)

Информация в потоках может храниться в любом удобном виде, включая текст, изображение в любом формате, зашифрованные или сжатые данные, или даже другие файлы CFBF. Не составляет труда поместить в поток и исполняемый код (в т.ч. вредоносный).
Используя соответствующие API (см. Structured Storage Reference в MSDN), приложение может создать файл-хранилище и предоставить каждому компоненту хранилище второго (третьего и т.д.) уровня или поток (несколько потоков) для сохранения состояния в любом формате. Контейнеру нет необходимости знать, в каком виде компонент запишет свои данные, а о размещении информации в файле позаботится стандартная библиотека. Когда необходимо загрузить сохраненное состояние, контейнер открывает хранилище и предоставляет загруженным компонентам возможность считать потоки по мере надобности.

Создание технологии Структурированного Хранилища преследовало следующие задачи:

  • исключение необходимости для приложений сохранять многочисленные отдельные файлы для разных типов данных, в том числе, для экономии места на диске
  • создание унифицированного интерфейса для работы с данными, облегчающего создание приложений, и, в особенности, COM-компонентов, работающих с составными документами
  • возможность сохранять текущее состояние элемента данных в любой момент времени
  • ускорение доступа к данным

Последний пункт требует отдельного рассмотрения. Разработка Структурированного Хранилища велась на заре развития COM (начало 90х годов), когда существующие аппаратные ресурсы предъявляли повышенные требования к быстродействию сложных систем, в том числе при чтении и записи дисковых файлов. Поэтому система хранения данных должна была быть максимально оптимизирована для быстродействия. Это исключало использование, к примеру, текстовых форматов, требующих значительной предварительной обработки. Напротив, двоичные форматы, позволяющие копировать данные в память с минимальными модификациями, имели преимущество.

Результатом стала дисковая реализация Структурированного Хранилища — формат составных двоичных файлов Microsoft (Compound File Binary Format). Долгое время формат оставался закрытым, спецификации были опубликованы производителем в 2006 году.

Формат CFBF представляет собой «файловую систему внутри файла» и имеет таблицу размещения файлов (FAT), таблицу секторов, директории и «потоки» — аналог дисковых файлов.

ra0ibz1l5qaiaqotolzhi9recd0.png
Техническое представление формата CFBF

Существует несколько версий формата CFBF, все они должны поддерживаться последними версиями ОС в рамках обратной совместимости. Несмотря на то, что Структурированные Хранилища являются во многом «унаследованной» и морально устаревшей технологией, они представляют естественную встроенную систему хранения данных COM, а технология COM насквозь пронизывает «пользовательскую» часть ОС Windows. Значительный объем прикладных программ, в том числе Microsoft Office и многие встроенные приложения Windows, разрабатывались достаточно давно и содержат большой объем кода, требующего обратной совместимости, что затрудняет переход на современные универсальные открытые форматы. Как следствие, технология занимает прочное место и активно используется в современных версиях продуктов Microsoft.
В качестве примеров можно привести:

  • Ярлыки и списки быстрого доступа
  • Кэш изображений и результатов поиска
  • Файлы установки (msi и msp)
  • «Заметки» Windows

Формат Compound Binary File в приложениях пакета Microsoft Office


Формат документов, используемый Microsoft Office, изначально также представлял собой CFBF.

lycqz9vj0ozylfuda7pccoqfqxs.png
Документ Word, открытый утилитой для просмотра Structured Storage

Современные версии пакета в качестве основного используют открытый, основанный на XML, формат OfficeOpen XML, однако поддержка CFBF не прекращается с целью поддержания совместимости. Необходимо заметить, что значительная масса кода, отвечающего за работу со старыми форматами документов, была разработана давно (около 20 лет назад).

Word .doc Legacy Word document;
Microsoft Office refers to them as «Microsoft Word 97 2003 Document»
.dot Legacy Word templates;
officially designated «Microsoft Word 97 2003 Template»
.wbk Legacy Word document backup;
referred as «Microsoft Word Backup Document»
Excel .xls Legacy Excel worksheets;
officially designated «Microsoft Excel 97–2003 Worksheet»
.xlt Legacy Excel templates;
officially designated «Microsoft Excel 97–2003 Template»
.xlm Legacy Excel macro
PowerPoint .ppt Legacy PowerPoint presentation
.pot Legacy PowerPoint template
.pps Legacy PowerPoint slideshow
Publisher .pub Microsoft Publisher publication


Примеры устаревших, по-прежнему поддерживаемых форматов Office

Простой поиск по сайтам государственных структур и предприятий РФ (госзакупки, сайты административных единиц) обнаруживает обескураживающе большое количество официальной документации, выложенной в CFBF, зачастую созданной в древних версиях Office, например, 2003 года. Предоставим читателю провести этот опыт самостоятельно.

Применение CFBF в приложениях Microsoft Office не ограничивается поддержкой унаследованных форматов документов, имеющих современные XML-аналоги. Приложение Microsoft Publisher все еще использует только документы формата CFBF. К CFBF относятся формат .msg сообщений Outlook.
Если документ формата Office Open XML включает элементы OLE, их текущее состояние может сохраняться в файлах CFBF. В этом случае документ будет содержать включения в виде двоичных Compound-файлов.

feb37c9rddrto1wvmhmfhrmfe_e.png
двоичный файл формата CFBF внутри документа OfficeOpenXML

Несмотря на то, что документы различных приложений Office основаны на CFBF, каждое хранилище состояний элементов OLE/ActiveX будет иметь свой собственный дополнительный формат. Нужно иметь ввиду, что они во многом сложились исторически и были оптимизированы для максимального быстродействия на слабых компьютерах.


Некоторые опубликованные спецификации форматов Office, основанных на Структурированном Хранилище

Поддержка Хранилищ OLE форматом RTF


Rich Text Format в целом считается довольно безопасным XML-подобным форматом. Однако, в свою реализацию специалисты Microsoft не могли не включить поддержку OLE/ActiveX. Документы RTF в приложениях Microsoft могут содержать и отображать встроенные элементы OLE и должны иметь возможность сохранять их текущее состояние. Для этого к формату были добавлены такие управляющие слова, как '\obj', '\objclass', '\objdata'. Это позволяет дополнять RTF-документы зарегистрированными в системе элементами ActiveX. Работу с форматом для компонента обеспечивает подсистема OLE, исполняемый код ActiveX прозрачно для себя использует стандартные интерфейсы IStorage и IStream. Обеспечение безопасности документов ложится на приложение-контейнер, которое может использовать устаревший унаследованный код и не учитывать всех современных нюансов работы с ActiveX.

OLE-компонент отображения формул Microsoft EQUATION


Примером уязвимости, связанной с технологией COM Structured Storage, может служить CVE-2017–11882.

xz9zcmentukhgauj-ibcyfucg2m.png

Уязвимость была обнаружена в компоненте Microsoft Office настолько древнем, что производителем были утрачены исходные коды компонента.
Для сохранения состояния элементы Редактора Формул (Microsoft Equation Editor) использовали потоки структурированного хранилища. Нарушение целостности данных в потоках приводило к многочисленным уязвимостям, первой обнаруженной из которых была CVE-2017–11882, найденная специалистами Embedi.

yhsraqr_cxpoj_p7kcgeckmocxe.png
Поток структурированного хранилища элемента EquationEditor

Несмотря на то, что компонент по умолчанию запрещен к загрузке для документов .doc и .docx, из .rtf элемент загружался успешно, позволяя атакующему выполнить вредоносный код.
После безуспешных попыток вручную исправить уязвимости в исполняемом коде в отсутствие исходного кода, в Microsoft были вынуждены исключить компонент Редактора Формул из пакета Office.

Некоторые другие унаследованные двоичные форматы, используемые в пакете Microsoft Office

Графический фильтр EPS


Графический фильтр EPS представляет собой компонент Office, который отвечает за редактирование EPS-изображений. Они являются векторными и строятся при помощи интерпретации внутреннего языка Encapsulated PostScript (версия обычного PostScript с некоторыми ограничениями).

В силу своих особенностей этот язык поддерживает самые разнообразные конструкции и возможности. Благодаря чему уязвимости повреждения памяти в графическом фильтре EPS эксплуатируются достаточно легко. Богатство языка делает возможным использование техник HeapSpray (например, возможность использования циклов) и HeapFengShui (предсказуемость выделения памяти интерпретатором). Даже несмотря на то, что рендеринг изображения происходит на виртуальном принтере, а само исполнение программы «EPS» происходит в рамках изолированного интерпретатора, наличие благоприятных возможностей эксплуатации уязвимостей и старая кодовая база сделали EPS едва ли не самым распространенным вектором атаки офисных приложений.

Ввиду того, что модуль был изначально разработан компанией Access Softek, а затем передан компании Microsoft, в этом компоненте найдено и успешно эксплуатируется существенное число «неизвестных» уязвимостей. Например, в апреле 2017 года компанией FireEye Inc. были найдены уязвимости CVE-2017–0261 и CVE-2017–0262. Эти две уязвимости повреждения памяти позволили злоумышленникам построить READ/WRITE-примитивы, с помощью которых они и добились выполнения своего кода за пределами изолированного процесса («песочницы») интерпретатора PostScript. Злоумышленники могут читать и записывать произвольные участки памяти в адресном пространстве уязвимого процесса, а также могут выполнить, например, поиск необходимых ROP гаджетов для построения ROP-цепочки, делающей остальной шелл-код исполняемым.

В обоих случаях атакующие добивались исполнения произвольного кода похожим образом: создавали объект в памяти с контролируемым содержимым (это было возможно сделать при помощи R/W примитивов) и вызывали один из его методов при помощи функции PostScript.

Данные уязвимости в графическом фильтре «EPS» стали популярным вектором атаки. Причем настолько, что компания Microsoft в апреле 2017 разработала обновление, которое полностью отключает графический фильтр. Однако, патч применим только для версии MsOffice 2010 SP2 и выше.

Базы данных Access


Система управления БД Microsoft Access представляет собой мощный инструмент управления сравнительно небольшим объемом данных, например, реестром оборудования какой-либо организации. Access позволяет легко создавать отчеты на основе информации в базе данных. Также приложение можно использовать как front-end для управления другими СУБД, включая Microsoft SQL Server (при помощи ODBC-драйверов).
Приложение и формат БД разрабатывались очень давно и обладают рядом архитектурных недостатков:

  • использование макросов VBA в качестве некоторых триггеров и хранимых процедур;
  • возможность использования ссылок на другие базы данных;
  • закрытость формата БД препятствует использованию существующих баз в других окружениях.

Первый недостаток весьма серьезный, поскольку VBA-макросы по своим возможностям равносильны обычным исполняемым файлам. По этой причине использование Access может стать проблемой для безопасности.
Пользователь должен доверять БД, с которой работает, и быть уверенным, что в ней не содержится вредоносный код, внесенный злоумышленником. В противном случае запрет исполнения макросов существенно сокращает функциональность приложения для работы с данными в таблицах и представлениями.

Файлы Личных Папок Outlook


Почтовый клиент пакета Microsoft Office использует собственный формат файла-хранилища для сообщений, пользовательской структуры папок, вложений, адресной книги и т.п. Это многоуровневый формат, тесно связанный с подсистемой MAPI, предоставляющей доступ к файлам личных папок посредством собственных интерфейсов.

Спецификация Outlook Personal Folders (.pst) была опубликована производителем: https://msdn.microsoft.com/en-us/library/ff385210.aspx.

Спецификация .ost не была опубликована, и формально доступ к файлу Offline Storage Table может осуществляться только посредством MAPI. На деле эти форматы очень схожи и редактирование .ost также возможно. Необходимо иметь ввиду, что синхронизация отредактированного содержимого файла Offline Storage Table с данными на сервере Exchange может привести к необратимой порче данных и утере значимой информации.

Файл владельца/OwnerFile


Проблема совместной работы над документами Office, расположенными в сетевых хранилищах, была когда-то решена при помощи временных файлов простого формата, так называемых OwnerFile. Если файл в данный момент заблокирован для редактирования, приложение ищет в той же директории файл с коротким именем формата »~$name.doc». Файл содержит имя пользователя, открывшего документ в ASCII и Unicode форматах, в обоих случаях под имя отведен фиксированный размер массива. При создании файла неиспользуемые байты массива заполняются мусорными значениями из памяти приложения, что потенциально может привести к раскрытию чувствительной информации (в целом, из-за размера файла вероятность этого невелика). Имя пользователя в файле владельца также легко подделывается.

4sypkhpcuhu6xqx1dgaln-a9f-o.png
сообщение MicrosoftWord при попытке открытия заблокированного документа

Механизм шифрования офисных документов


Механизм парольной защиты документов впервые появился в пакете Office 95. В то время стойкости используемых алгоритмов шифрования уделялось мало внимания, как следствие, применялись алгоритмы, на которые существовали практически применимые атаки. Этот факт стал толчком к изменению механизма в последующих версиях офисных пакетов.
В таблице приведены в хронологическом порядке наиболее распространенные в данное время офисные пакеты и используемые в них по умолчанию алгоритмы шифрования.

Версия Хеширование Шифрование
Office 2003 None RC4
Office 2007 SHA-1×50.000 AES-128
Office 2010 SHA-1×100.000 AES-128
Office 2013 SHA-512×100.000 AES-128
Office 2016 SHA-512×100.000 AES-128


Несмотря на использование стойких алгоритмов шифрования, само шифрование документа производится не сразу после установки пароля на документ, а только после следующего сохранения документа. Учитывая количество атак, основанных на невнимательности пользователей офисного пакета, это довольно важный нюанс.
Также нельзя забывать, что реализация криптоалгоритмов является трудоемкой задачей даже для высококвалифицированных разработчиков, поэтому наличие ошибок в них исключать нельзя. Ярким примером такой ошибки, повлиявшей на защиту Excel документов является уязвимость в генерации ключей, исправленная патчем MS15–110.

Несколько слов об источниках информации для исследователя


Если вы решили всерьез заглянуть «под капот» Office, нелишней будет любая дополнительная информация, позволяющая понять назначение структур данных.

  1. Весьма полезны в этом плане уже упоминавшиеся спецификации форматов, любезно (хотя и под некоторым давлением) выложенные Microsoft. С ними можно ознакомиться на сайте MSDN:
    https://msdn.microsoft.com/en-us/library/cc313105.aspx
    Необходимо отметить, что эта документация содержит пробелы и неточности, так что ориентируясь исключительно на нее написать парсер документов довольно сложно. Зато из нее можно почерпнуть сведения о многих загадочных структурах и идентификаторах, выяснить их название.
  2. VisualStudio 2010 SDK
    Среди набора заголовочных файлов есть комплект для Microsoft Office, содержащий информацию об интерфейсах, типах, перечислениях и форматах вызова процедур: https://www.microsoft.com/en-us/download/details.aspx? id=2680 (требуется установленная VS2010).
    Ознакомиться можно (например) здесь
  3. Office 97
    В исполняемых файлах современных версий пакета разделяемые библиотечные процедуры импортируются по ординалам. В ранних версиях Office они имеют внятные названия, по которым можно составить представление об их назначении. Номера ординалов в основном соответствуют современным (есть и различия!).
  4. Office 2010
    В исполняемых файлах Office 2010 содержится информация для динамической идентификации классов (RTTI), позволяющая установить имена классов и виртуальные таблицы интерфейсов. Для этого можно воспользоваться инструментами вроде Class Informer. Начиная с Office 2013, эта информация зашифрована.
  5. offparser.dll
    Компонент 64-разрядного Server 2003, содержащий упрощенные варианты реализаций классов и интерфейсов. В отличие от Office, символьная информация (.pdb) для этого модуля доступна для скачивания с сервера Microsoft. Позволяет получить имена методов, внутреннее строение экземпляров классов и названия CLSID и GUID.
  6. OutlookExpress/Microsoft Mail
    Почтовый клиент и почтовая подсистема, входящие в состав оперционной системы. Содержат упрощенный вариант MAPI (почтовая подсистема Outlook). Как и для других компонентов Windows, символьная информация доступна для скачивания. Часть кода этих компонентов содержится в опубликованных исходных кодах Windows.

© Habrahabr.ru