• XSS.stack #1 – первый литературный журнал от юзеров форума

Fuzzing Год фаззинга шрифтов ядра Windows №1: результаты

yashechka

Генератор контента.Фанат Ильфака и Рикардо Нарвахи
Эксперт
Регистрация
24.11.2012
Сообщения
2 344
Реакции
3 563
Эта серия постов в блоге посвящена тому, как мы использовали масштабный фаззинг, чтобы обнаружить и сообщить о 16 уязвимостях в обработке шрифтов TrueType и OpenType в ядре Windows за последний год. В части № 1 здесь мы представляем общий обзор области безопасности шрифтов, за которым следует подробное объяснение предпринятых нами усилий по фаззингу, включая общие результаты и тематические исследования двух ошибок. В предстоящей части № 2 мы поделимся конкретными техническими деталями проекта и тем, как мы пытались максимально оптимизировать каждую часть процесса и выйти за рамки текущего состояния фаззинга шрифтов ядра Windows.

Описание

Для большинства читателей этого блога нет необходимости повторять тот факт, что шрифты являются очень важным вектором атаки. Активно используется несколько различных форматов файлов. Эти форматы чрезвычайно сложны как структурно, так и семантически. В результате их, соответственно, трудно правильно реализовать, что еще больше усугубляется тем фактом, что большинство используемых в настоящее время растеризаторов шрифтов относятся к (началу) 90-х годов и были написаны на родных языках, таких как C или C++. Файлы контролируемых шрифтов также доставляются по различным удаленным каналам — документам, веб-сайтам, буферным файлам и т. д. И последнее, но не менее важное: две мощные виртуальные машины, выполняющие программы, описывающие контуры глифов в форматах TrueType и OpenType, оказались чрезвычайно полезными для создания надежных цепочек эксплуатации благодаря возможности выполнять произвольные арифметические, побитовые и другие операции с данными в памяти. По всем этим причинам шрифты были привлекательным источником ошибок повреждения памяти.

Уязвимости обработки шрифтов использовались "в дикой природе"во многих случаях, начиная от эксплойта Duqu 0-day TTF для ядра Windows (и ряда других таких 0-day исправлений в экстренных исправлениях), джейлбрейка iOS от Comex через уязвимость FreeType Type 1 к успешным заявкам на участие в соревнованиях pwn2own (Joshua Drake — Java 7 SE — 2013, Keen Team — ядро Windows — 2015). Только Microsoft выпустила несколько десятков бюллетеней по безопасности для своего шрифтового движка за последнее десятилетие, и другие поставщики и проекты не намного лучше в этом отношении. На конференциях по безопасности часто обсуждались фаззеры шрифтов или подробности конкретных ошибок, обнаруженных исследователями. С точки зрения безопасности пользователей это действительно невыгодная ситуация. Если существует семейство программного обеспечения настолько хрупкого, но широко распространенного и доступного, что большинство специалистов по безопасности могут просто зайти и легко найти удобную ошибку нулевого дня и использовать ее в целевых атаках или массовых кампаниях, что-то явно не так.

Решение проблемы безопасности программного обеспечения шрифтов

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

В наших силах, однако, значительно поднять планку обнаружения ошибок безопасности в соответствующем коде, тем самым увеличивая стоимость таких операций и полностью исключая некоторых действующих лиц из уравнения. С начала 2012 года мы использовали внутреннюю инфраструктуру фаззинга и доступные ресурсы для масштабного фаззинг-тестирования проекта FreeType. На сегодняшний день это привело к более чем 50 сообщениям об ошибках, многие из которых, вероятно, были уязвимостями повреждения памяти (см. списки в трекерах ошибок Savannah (http://savannah.nongnu.org/search/?...ly_group_id=7246&exact=1&max_rows=100#options) и Project Zero( https://bugs.chromium.org/p/project-zero/issues/list?can=1&q=status%3Afixed+product%3Afreetype&colspec=ID+Type+Status+Priority+Milestone+Owner+Summary&cells=ids)). Некоторый ручной аудит кода также был задействован для обнаружения некоторых проблем. Мы надеемся, что благодаря нашим усилиям были устранены большинство уязвимостей.

Однако в контексте поиска уязвимостей FreeType является относительно легкой мишенью — его природа с открытым исходным кодом обеспечивает очень удобный ручной аудит исходного кода с полным пониманием базовой логики, позволяет использовать алгоритмы статического анализа и позволяет нам компилировать в любом инструменте в окончательный двоичный файл с низкими накладными расходами во время выполнения (по сравнению с DBI). Например, мы широко использовали инструменты AddressSanitizer, MemorySanitizer и SanitizerCoverage, которые значительно улучшили коэффициент обнаружения ошибок и предоставили нам информацию о покрытии кода, которую можно использовать для фаззинга на основе покрытия.

И наоборот, ядро Windows и его реализацию шрифтов можно считать более сложной задачей, чем обычно. Исходный код недоступен, а символы отладки общедоступны только для частей движка (обработка растровых изображений и TTF в win32k.sys, но не обработка Type 1 и OTF в ATMFD.DLL). Это уже делает любую ручную работу более требовательной, так как она должна включать реверс, что может оказаться особенно трудным для частей кода, работающих с данными шрифта косвенным образом (в отличие от кода, который отображает 1:1 части спецификации, например, виртуальная машина с контуром глифа). Кроме того, код выполняется в ядре, в одном модуле, совместно используемом с остальной частью графической подсистемы, что делает любое взаимодействие (например, инструментирование) нетривиальным, если не сказать больше. Конечно, существуют механизмы для улучшения обнаружения ошибок (например, специальные пулы), но есть и препятствия, стоящие на пути, такие как общая обработка исключений, потенциально маскирующая некоторые индикаторы ошибок.

В начале 2015 года мы начали с того, что вручную разобрали виртуальную машину Type 1/CFF в ATMFD, которая оказалась идеальной целью для аудита. Полностью автономный, достаточно сложный, но разумно ограниченный по размеру, полный устаревшего кода и, по-видимому, не прошедший должной проверки в прошлом — смесь, которую нельзя недооценивать. В результате аудита Microsoft сообщила о 8 уязвимостях в ядре Windows, некоторые из них чрезвычайно опасны. Подробный отчет об этом исследовании и самой интересной уязвимости BLEND см. в серии сообщений в блоге "Одна уязвимость в шрифтах, которая справится со всеми", начиная с части №1 (http://googleprojectzero.blogspot.com/2015/07/one-font-vulnerability-to-rule-them-all.html).

Реализация CharString действительно может быть эффективно проверена в целом, но та же стратегия не может быть применена ко всему коду, связанному со шрифтами win32k.sys и ATMFD.DLL. Объем кода и различные состояния программы не позволяют понять их все, не говоря уже о том, чтобы держать в голове общую картину и думать обо всех возможных отклонениях в поведении и крайних случаях. Другим вариантом был, конечно, фаззинг — метод, который не дает такой уверенности в результатах и охвате состояния кода/программы, но очень хорошо масштабируется, требует времени только для первоначальной настройки и доказал свою высокую эффективность в прошлом. На самом деле, наша оценка, основанная на общедоступных данных, заключается в том, что исторически более 90% ошибок шрифтов (аналогично всем проблемам безопасности) были обнаружены с помощью фаззинга. Это имеет дополнительное преимущество, заключающееся в том, что сообщение об обнаруженных ошибках соответствует цели поднять планку для других охотников за ошибками, поскольку они используют аналогичные методы и больше не смогут найти устраненные ошибки.

Помня об этом, в мае 2015 года мы начали фаззинг шрифтов ядра Windows, пытаясь взять то, что было известно ранее по этому вопросу, и продвинуть каждую часть процесса немного вперед, оптимизируя их или пытаясь достичь максимальной эффективности. По прошествии примерно года и множества бюллетеней, выпущенных с тех пор, ядро теперь полностью очищено от методов, которые мы использовали, и, поскольку мы считаем, что и результаты, и методы могут быть интересны для более широкой аудитории, эта серия постов должна завершиться и подвести итоги инициативы.

Полученные результаты

Без лишних слов ниже приведен список всех уязвимостей, обнаруженных при фаззинге ядра Windows за последний год:

1651140892573.png


Связанные записи об ошибках включают краткие описания сбоев, примеры журналов сбоев из Windows 7 x86 с включенными специальными пулами и обязательные файлы подтверждения концепции. Чтобы воспроизвести некоторые сбои, также может потребоваться использование специальной программы загрузки шрифтов, которая была предоставлена Microsoft в частном порядке (но также подробно обсуждается в следующем посте).

Как показано в таблице, о сбоях сообщалось в трех итерациях: первая, очевидно, заключала в себе большую часть проблем, поскольку фаззер с самого начала сталкивался с множеством различных состояний и путей кода. Вторая и третья итерации выполнялись в течение более длительного времени, чтобы избавиться от любых сбоев, которые могли быть замаскированы другими, более частыми ошибками. Периоды времени между каждым запуском (3–4 месяца) — это время, необходимое Microsoft для выпуска исправлений для обнаруженных ошибок, и они связаны с 90-дневным крайним сроком раскрытия Project Zero (который Microsoft соблюдала во всех случаях). В одном случае (№ 684) было обновлено время отчета, так как нам пришлось выяснять с Microsoft системные настройки, необходимые для воспроизведения системного сбоя.

Недостатки представляли собой множество ошибок программирования при обработке файлов TTF и OTF в коде, отвечающем за обработку различных таблиц SFNT. Подавляющее большинство проблем может быть использовано для локального повышения привилегий (побег из песочницы и т. д.) и даже для удаленного выполнения кода (для приложений, которые передают файлы, контролируемые пользователем, непосредственно в GDI), что согласуется с "критической" оценкой Microsoft этих ошибок. Несмотря на то, что фаззинг выполнялся в Windows 7, почти все обнаруженные ошибки по-прежнему присутствовали в более новых версиях системы. Также стоит отметить, что хотя сценарий повышения привилегий в Windows 10 смягчается за счет архитектурного перехода к выполнению растеризации шрифтов в процессе пользовательского режима с ограниченными привилегиями, RCE в контексте этого процесса по-прежнему является жизнеспособным вариантом (хотя многое более ограниченным, чем прямая компрометация контекста безопасности кольца 0).

Коллизии

Нет лучшего подтверждения ценности любых конкретных защитных усилий по поиску ошибок, чем наблюдение за обнаруженными вами ошибками, сталкивающимися с вооруженными эксплойтами, используемыми в дикой природе (бонусные баллы за зеро дэй, используемые для причинения вреда пользователям). Несмотря на обширный послужной список таких ошибок и их использования в прошлом, вопрос о том, будут ли какие-либо новые открытия сталкиваться с эксплойтами, все еще циркулирующими в 2015 году, еще предстоит ответить.

Нам не пришлось долго ждать. Как оказалось, ровно две первые ошибки, которые мы зарегистрировали в трекере (issues #368 (https://bugs.chromium.org/p/project-zero/issues/detail?id=368) и #369 (https://bugs.chromium.org/p/project-zero/issues/detail?id=369)), очень быстро оказались такими же, как TTF-уязвимость, использованная Keen Team для повышения привилегий во время pwn2own 2015, и OTF-уязвимость. Уязвимость, обнаруженная в утечке данных Hacking Team в июле 2015 года (с полностью вооруженным эксплойтом), впоследствии исправлена Microsoft в экстренном бюллетене.

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

The HackingTeam 0-day bug collision​


Сообщив Microsoft о первой партии крашев в мае 2015 года (7 ошибок OpenType и 4 ошибки TrueType), мы терпеливо ждали, когда поставщик выпустит соответствующие исправления. Очень скоро нам сообщили, что им удалось воспроизвести все проблемы, и они запланировали исправления на августовский вторник. Однако 20 июля, в разгар отпуска, я заметил, что в этот день был выпущен важный бюллетень безопасности MS15-078 (https://technet.microsoft.com/en-us/library/security/ms15-078.aspx):

1651140923297.png


Что еще более интересно, я был одним из трех человек, упомянутых в разделе "Благодарности":

1651140939192.png


Как вскоре выяснилось, произошла коллизиция одного из зарегистрированных нами сбоев (issue #369 (https://bugs.chromium.org/p/project-zero/issues/detail?id=369)) с вооруженным эксплойтом, обнаруженным двумя независимыми исследователями в утечке Hacking Team. Напомним, что 5 июля 2015 года в их (взломанной) учетной записи Twitter была оставлена ссылка на файл .torrent, содержащий гигабайты данных частной компании Hacking Team. Большая часть индустрии безопасности бросилась исследовать внезапно появившиеся ресурсы, обнаружив не только исходный код продуктов для наблюдения и противоречивую информацию о бизнес-операциях, но и множественные эксплойты для нулевых уязвимостей в таких программах, как Flash Player (4 эксплойта), Windows ядро (2 эксплойта), Internet Explorer, SELinux и так далее. Однако до 20 июля не было общедоступных сведений о существовании CVE-2015-2426, что указывает на то, что об ошибке было сообщено в Microsoft в частном порядке.

Эксплойт воспользовался уязвимостью для повышения привилегий кода в системе на платформах Windows до версии 8.1. Подробный анализ основной причины ошибки и методов эксплуатации можно найти в сообщении блога 360 Vulcan Team( http://blogs.360.cn/blog/hacking-team-part5-atmfd-0day-2/) (на китайском языке), но по сути это было вызвано неверным предположением, сделанным в драйвере ATMFD.DLL OpenType, как показано на рисунке. в псевдокоде ниже:

LPVOID lpBuffer = EngAllocMem(8 + GPOS.Class1Count * 0x20);
if (lpBuffer != NULL) {
// Copy the first element.
memcpy(lpBuffer + 8, ..., 0x20);

// Copy the remaining Class1Count - 1 elements.
}


Здесь код предполагал, что Class1Count (16-битное поле в таблице GPOS) всегда будет ненулевым, и копировал первый элемент таблицы независимо от фактического значения. В результате, если поле было равно 0x0000, динамически выделяемый буфер переполнялся на 32 (0x20) байта. При правильном обращении с пулами ядра можно было поместить объект CHwndTargetProp win32k.sys непосредственно после перезаписанной области памяти и повредить его виртуальную таблицу адресом пользовательского режима. Оттуда оставалось только слить базовый адрес модуля win32k.sys и построить цепочку ROP для отключения SMEP и выполнения шелл-кода повышения привилегий.

Важным моментом является то, что для запуска ошибки через фаззинг достаточно было установить всего два последовательных байта в определенном месте в файле (соответствующем полю Class1Count) в 0. Другими словами, его было легко обнаружить с помощью тупого фаззера, и удивительно, что такая ошибка вообще дожила до 2015 года, когда так много работы якобы было вложено в безопасность обработки шрифтов.

Любопытно, что оригинальный эксплойт HT был позже портирован на 64-разрядную версию Windows 8.1 Седриком Халбронном из NCC Group (см. эту статью (https://www.nccgroup.trust/uk/about...w-i-ported-it-to-a-recent-windows-8.1-64-bit/)).

The pwn2own bug collision​


Спустя три недели, 11 августа 2015 года, как и планировалось, были выпущены исправления для остальных крашев из первой партии. Тем не менее, я снова был удивлен разделом "Благодарности", в котором также была отмечена заслуга в сообщении об одной из уязвимостей другим исследователям:

1651140971016.png


На этот раз, Keen Team! Если вы посмотрите CVE-2015-2455, одним из результатов будет ZDI-15-388 ( http://zerodayinitiative.com/advisories/ZDI-15-388/), в котором ошибка упоминается как " (Pwn2Own) " в заголовке и упоминается, что она связана с "IUP" TrueType. Да, это именно выпуск №368 (https://bugs.chromium.org/p/project-zero/issues/detail?id=368). Уязвимость действительно использовалась для выхода из песочницы и полной компрометации системы в одной из категорий "Adobe Reader" или "Adobe Flash Player" (это неясно, так как во время соревнования использовались две разные ошибки TTF), во время pwn2own. Конкурс, который проходил 19-20 марта 2015 года. Для любопытных, использование другого недостатка TTF Team Keen было объяснено во время выступления "На этот раз шрифт выследит вас в 4 байтах" (http://www.slideshare.net/PeterHlav...ation-this-time-font-hunt-you-down-in-4-bytes) на REcon 2015. Примечательно, что Microsoft потребовалось почти 5 месяцев, чтобы исправить ошибки, так как о них сообщили через ZDI, но все же уложились в 90-дневный крайний срок раскрытия Project Zero (поскольку дата начала была 21 мая).

Что касается технических деталей, то ошибка существовала в реализации инструкции "IUP", которая транслируется в Interpolate Untouched Points через схему в спецификации набора инструкций TrueType (https://www.microsoft.com/typography/otspec/ttinst.htm):

1651140981121.png


Если присмотреться, в конце описания есть важное примечание: Применение IUP к зоне 0 — ошибка. Да, как вы уже догадались, это была ошибка. В обработчике инструкций на win32k!itrp_IUP отсутствовала проверка того, что текущая зона не является зоной 0, и поэтому он работал с зоной 0, как если бы она была зоной 1, что в конечном итоге приводило к переполнению буфера на основе пула с в значительной степени контролируемым содержимым и длиной. Трех приведенных ниже инструкций TrueType было достаточно, чтобы вызвать сбой:

PUSH[ ] /* 1 value pushed */
0
SZP2[ ] /* SetZonePointer2 */
IUP[0] /* InterpolateUntPts */

Что еще более важно, сбой также был очень простым при мутации легитимных шрифтов — достаточно было одного бита, чтобы изменить аргумент инструкции SZP2 / SZPS с 1 на 0. Соответственно, это был первый краш в первой части моего тупого фаззинга. Когда позже я добавил в микс генератор программ TrueType, проблема также проявлялась при загрузке каждого второго тестового примера, что вынуждало нас учитывать это в генераторе и избегать конкретной конструкции, пока ошибка не будет исправлена.

Кстати говоря, этот кейс — отличный пример того, как простое внимательное прочтение официальной спецификации может привести к обнаружению критической уязвимости с минимальными усилиями и без какого-либо аудита или фаззинга. :)

Заключительные мысли

По крайней мере, усилия и их результаты свидетельствуют о том, что фаззинг, если он выполняется правильно, по-прежнему является очень эффективным подходом к поиску уязвимостей, даже с теоретически "зрелыми" и тщательно протестированными кодовыми базами. Кроме того, две коллизии ошибок доказывают, что ошибки шрифтов ядра Windows все еще живы и работают, или, по крайней мере, активно использовались в дикой природе в 2015 году. Во втором посте мы обсудим содержательные части исследования.

Между тем, буквально на прошлой неделе (после вторника исправлений Microsoft на прошлой неделе) мы открыли проблему № 785 (https://bugs.chromium.org/p/project-zero/issues/detail?id=785) в трекере Project Zero, в которой обсуждаются подробности уязвимости повреждения пула ATMFD.DLL в поверхности атаки "NamedEscape", то же самое, что Второе ядро Windows 0-day от Hacking Team (CVE-2015-2387 (http://blog.trendmicro.com/trendlab...ger-vulnerability-from-the-hacking-team-leak/)). Приятного чтения!

Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://googleprojectzero.blogspot.com/2016/06/a-year-of-windows-kernel-font-fuzzing-1_27.html
 
Не знаю, там ли я задаю вопрос, если что скажите где надо.
Сколько лет нужно потратить чтобы понимать как раскрутить такую уязвимость и знать внутренности windows?
Тема мне нравится, но сутками сидеть за отладчиком быстро надоедает.
Кроме снятия диалога в винраре и еще подобных мелких кряков ничего не делал.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Не знаю, там ли я задаю вопрос, если что скажите где надо.
Сколько лет нужно потратить чтобы понимать как раскрутить такую уязвимость и знать внутренности windows?
Тема мне нравится, но сутками сидеть за отладчиком быстро надоедает.
Кроме снятия диалога в винраре и еще подобных мелких кряков ничего не делал.
Чтобы раскручивать все уязвимости надо много играть в CTF категории PWN.

Сейчас в этой категории можно встреть такие задачки, как взлом веб-браузера, так и взлом ядра.

Для того, чтобы "знать внутренности windows" достаточно прочитать пару книг или записаться на тренинг. Раз тебе интересна платформа Windows, то соответственно и WinAPI знать надо неговоря уже про C\C++ и ассемблер.

По поводу инструментов

анализ уязвимости это всегда работа с дизассемблером и декомпилятором
а вот эксплуатация это всегда отладчик

Если тебя напрягает пользоваться отладчиком, то возможно это не твое. И лучше выбрать что-то другое..

p.s. Но, если ты один из тех, кто сможет бросить себе вызов, то вот тебе полезные ресурсы
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх