Открыть сервисСервис

Heap spray

Heap spray — это метод эксплуатации уязвимостей программного обеспечения, основанный на целенаправленном заполнении динамической области памяти (кучи, heap) большим количеством одинаковых или управляемых данных с целью предсказуемого размещения вредоносного кода или обфускации структур памяти. Техника относится к классу атак на память и часто используется в связке с другими уязвимостями, такими как переполнение буфера, повреждение кучи (heap corruption) или использование после освобождения (use-after-free). Основная цель heap spray — повысить вероятность успешной эксплуатации за счёт создания в памяти большого количества «зацепок» (gadgets) или копий shellcode, одна из которых с высокой вероятностью будет выполнена при нарушении потока управления.

История

Метод heap spray был впервые описан в начале 2000-х годов в контексте атак на веб-браузеры, особенно на Internet Explorer. Одним из первых публичных упоминаний считается работа исследователя безопасности «SkyLined» (псевдоним), который в 2004 году опубликовал технику эксплуатации уязвимости в Internet Explorer через JavaScript, заполняя кучу блоками с NOP-слайдами и шелл-кодом. Эта атака позволяла обойти механизмы защиты, такие как Data Execution Prevention (DEP) и Address Space Layout Randomization (ASLR) на ранних этапах их внедрения.

В последующие годы техника активно развивалась. В 2008 году исследователи Александр Сотников и Даунинг (Dowd) продемонстрировали heap spray для уязвимости в Adobe Flash Player. С появлением более совершенных защит, таких как ASLR и DEP, методы heap spray эволюционировали: вместо простого заполнения кучи стали использовать более сложные конструкции, например, ROP-цепочки (Return-Oriented Programming), которые обходят запрет на выполнение кода в куче.

В 2010-х годах heap spray оставался актуальным для эксплуатации уязвимостей в браузерах (Chrome, Firefox, Safari), а также в офисных приложениях и операционных системах. С развитием технологий изоляции процессов (sandboxing) и улучшенных механизмов управления памятью (например, PartitionAlloc в Chrome) эффективность классического heap spray снизилась, но он по-прежнему используется в комбинации с другими техниками.

Принцип работы

Heap spray основан на том, что динамическая память (куча) в современных операционных системах выделяется блоками фиксированного или переменного размера. Атакующий, используя интерпретируемый язык (JavaScript, ActionScript, VBScript) или другие средства, многократно выделяет память под строки, массивы или объекты, заполняя их управляемыми данными. В результате большая часть кучи оказывается заполнена идентичными или предсказуемыми структурами.

Основные этапы

  1. Выделение памяти: Атакующий создаёт множество объектов (например, строк длиной от 0x1000 до 0x100000 байт), которые заполняют кучу. Каждый объект содержит «полезную нагрузку» — последовательность байтов, включающую NOP-слайд (последовательность инструкций, не влияющих на выполнение, например, 0x90 на x86) и шелл-код (исполняемый код атакующего).
  2. Вызов уязвимости: После заполнения кучи атакующий инициирует срабатывание уязвимости (например, переполнение буфера или use-after-free), которая нарушает поток управления программы. В результате указатель на функцию или адрес возврата заменяется на адрес, указывающий на область кучи.
  3. Выполнение кода: Из-за массового заполнения кучи вероятность того, что нарушенный указатель попадёт на один из NOP-слайдов, очень высока. Процессор выполняет NOP-слайд, затем переходит к шелл-коду, что приводит к выполнению произвольного кода.

Пример для браузера

В атаке на Internet Explorer через JavaScript атакующий создавал массив строк, каждая из которых содержала 0x10000 байт, из которых первые 0x1000 байт были NOP-слайдом, а остальные — шелл-кодом. После выделения 50–100 таких строк куча браузера оказывалась плотно заполнена. При срабатывании уязвимости, например, при обработке HTML-тега с повреждённым указателем, управление передавалось на адрес, который с высокой вероятностью находился в заполненной области.

Классификация

Heap spray можно классифицировать по нескольким признакам:

По типу полезной нагрузки

  • Классический NOP-слайд: Использует последовательности инструкций NOP (0x90) или их эквиваленты (например, 0x0f 0x1f — multi-byte NOP). Прост в реализации, но легко детектируется антивирусами.
  • ROP-цепочки: Вместо исполняемого кода в куче размещаются адреса и данные, которые при выполнении образуют цепочку возвратов (Return-Oriented Programming). Это позволяет обойти DEP, так как код выполняется в разрешённых областях (например, в библиотеках).
  • Смешанный: Комбинация NOP-слайда и ROP-цепочек, где сначала выполняется ROP для отключения DEP, а затем — шелл-код.

По среде выполнения

  • Браузерный heap spray: Реализуется через JavaScript, ActionScript или WebAssembly. Наиболее распространённый тип из-за доступности и мощности скриптовых движков.
  • Прикладной heap spray: Используется в уязвимостях офисных приложений (Microsoft Office, Adobe Reader) или медиаплееров. Часто требует макросов или специальных форматов файлов.
  • Системный heap spray: Нацелен на уязвимости в ядре операционной системы или драйверах. Реализуется через системные вызовы или API.

По цели

  • Обход ASLR: Заполнение кучи большим количеством блоков позволяет атакующему предсказать адрес, по которому будет расположена полезная нагрузка, несмотря на рандомизацию адресного пространства.
  • Обход DEP: Использование ROP-цепочек или вызовов API (например, VirtualProtect) для разрешения выполнения кода в куче.
  • Повышение надёжности: Увеличение вероятности попадания на полезную нагрузку за счёт плотного заполнения памяти.

Методы защиты

Современные операционные системы и приложения внедряют несколько механизмов для противодействия heap spray:

Address Space Layout Randomization (ASLR)

ASLR рандомизирует базовые адреса загружаемых модулей и областей памяти, что затрудняет предсказание адреса, по которому будет расположен NOP-слайд. Однако heap spray может частично обойти ASLR, если атакующий заполняет память настолько плотно, что вероятность попадания на полезную нагрузку остаётся высокой.

Data Execution Prevention (DEP)

DEP запрещает выполнение кода в областях памяти, помеченных как неисполняемые (например, куча и стек). Для обхода DEP атакующие используют ROP-цепочки, которые выполняют код в разрешённых областях (например, в библиотеках), или вызывают системные функции для изменения атрибутов страниц памяти.

Изоляция процессов (sandboxing)

Современные браузеры (Chrome, Firefox, Edge) изолируют процессы рендеринга, ограничивая их доступ к системным ресурсам. Даже при успешном heap spray атакующий не может напрямую выполнить код за пределами песочницы.

Управление памятью

  • PartitionAlloc (Chrome): Разделяет кучу на отдельные пулы для разных типов объектов, что затрудняет создание однородного заполнения.
  • Heap hardening: Внедрение случайных канареечных значений (canaries) и проверок целостности структур кучи (например, в Windows через механизм Heap Security Features).

Антивирусные и поведенческие детекторы

Современные антивирусные системы анализируют поведение процессов на предмет массового выделения памяти или выполнения кода из необычных областей. Например, эвристические алгоритмы могут выявлять подозрительные последовательности, такие как длинные NOP-слайды.

Примеры известных атак

  • CVE-2010-0249 (Internet Explorer 6/7): Уязвимость use-after-free в обработчике событий, эксплуатировавшаяся через heap spray на JavaScript. Использовалась в атаках на правительственные и корпоративные сети в 2010 году.
  • CVE-2015-5119 (Adobe Flash Player): Уязвимость в обработке ActionScript, позволявшая выполнять heap spray для обхода ASLR и DEP. Активно использовалась в атаках группы APT (Advanced Persistent Threat) в 2015 году.
  • CVE-2018-8174 (Microsoft Internet Explorer): Уязвимость в компоненте VBScript, эксплуатировавшаяся через heap spray с ROP-цепочками. Применялась для распространения вредоносного ПО, в том числе шифровальщиков.

Современное состояние

На 2025 год heap spray остаётся актуальной техникой, но его эффективность значительно снижена благодаря многоуровневой защите. Основные сложности для атакующих:

  • Улучшенная рандомизация адресов (ASLR с 64-битными адресами).
  • Изоляция процессов и sandboxing.
  • Специализированные аллокаторы памяти, предотвращающие однородное заполнение.
  • Поведенческий анализ и машинное обучение в антивирусных продуктах.

Тем не менее, heap spray продолжает использоваться в атаках на уязвимости нулевого дня (zero-day), особенно в комбинации с другими техниками, такими как JIT-spray (заполнение кучи через JIT-компиляцию) или использование утечек информации для определения адресов.

Критика и ограничения

Основным ограничением heap spray является его зависимость от архитектуры и версии операционной системы. Например, на 64-битных системах с большим адресным пространством (до 16 экзабайт) вероятность попадания на полезную нагрузку снижается, если атакующий не может заполнить значительную часть памяти. Кроме того, современные браузеры ограничивают объём выделяемой памяти через JavaScript (например, ограничение в 4 ГБ для 32-битных процессов), что уменьшает плотность заполнения.

Критики метода также отмечают, что heap spray легко детектируется по характерным паттернам: массовое выделение строк одинакового размера, большое количество одинаковых байтов (NOP-слайды) и подозрительные последовательности в куче. Это делает технику менее привлекательной для скрытых атак.

Источники

  • SkyLined, «Internet Explorer IFRAME vulnerability», 2004.
  • Alexander Sotirov, «Heap Feng Shui in JavaScript», Black Hat Europe, 2007.
  • Mark Dowd, «Application-Specific Attacks», 2008.
  • Microsoft Security Response Center, «Mitigating Heap Spray Attacks», 2010.
  • Google Chrome Security Team, «PartitionAlloc: Design and Implementation», 2020.
  • CVE-2010-0249, CVE-2015-5119, CVE-2018-8174 — National Vulnerability Database.
Заметили ошибку или не согласны с информацией в статье? Напишите нам support@bfometr.ru