Перейти к основному содержимому
  1. Блог/

Призрак в RAM: бесфайловая атака на основе memfd_create

·3 минут·

Злоумышленники, атакующие Linux-системы, часто используют “бесфайловое” выполнение, чтобы избежать загрузки вредоносного ПО на диск. Это помогает обойти традиционные системы детектирования и механизмы безопасности, а также оставляет значительно меньше следов для форензики.

Системный вызов memfd_create() играет важную роль в таких атаках. Этот механизм, появившийся в ядре Linux 3.17, предназначен для создания анонимных файлов, которые существуют только в оперативной памяти. Согласно руководству memfd_create(2), эти файлы ведут себя как обычные файлы — у них есть размер и отображение в памяти, их можно изменять — но они не сохраняются на физическом носителе. Вызов memfd_create() возвращает файловый дескриптор, который может быть использован вызовом fexecve(3) — это позволяет процессу выполнять бинарный файл через файловый дескриптор (FD), в отличие от вызова execve(2), где в качестве аргумента требуется путь в реальной файловой системе.

Типичная цепочка эксплуатации этого механизма состоит из трёх этапов:

  1. Загрузчик вызывает memfd_create(name, flags), этот вызов возвращает файловый дескриптор. Имя (name) здесь нужно только для отладки, оно не появляется в дереве каталогов.

  2. Загрузчик записывает вредоносную нагрузку (часто полученную по сети) в этот FD.

  3. Загрузчик вызывает fexecve(fd, argv, envp). Ядро заменяет текущий образ процесса бинарным файлом, хранящимся в анонимном сегменте памяти.

Такой подход гарантирует, что вредоносная нагрузка не попадает на диск, и таким образом она обходит:

— системы детектирования на основе сигнатур, которые сканируют диск; — запрет на выполнение: во многих системах каталоги с правами на запись для всех (такие, как /tmp или /dev/shm) монтируют с флагом noexec, поскольку такие каталоги часто используются злоумышленниками для выполнения вредоносного ПО.

Пример атаки:

Рассмотрим каталог, который смонтирован с флагом noexec. Попытка выполнить бинарный файл id из этой точки монтирования не сработает, даже если он запускается с высшими привилегиями и сам бинарный файл является исполняемым:

Пример блокировки исполнения

Это ограничение можно обойти, если бинарный файл загружен в оперативную память и выполнен напрямую из памяти. Для демонстрации мы создали веб-сервер, который хостит бинарный файл id (он может быть вредоносным в реальных атаках), и написали простой скрипт на Python, который скачивает этот бинарный файл, загружает его в память и выполняет его в памяти, обходя все защиты. Результат можно увидеть на скриншоте ниже. Обратите внимание, что системный вызов 319 — это и есть memfd_create().

Пример успешной атаки

Детектирование:

Хотя файла нет на диске, ядро Linux показывает метаданные о запущенных процессах. Нужно смотреть:

— Пути в файловой системе /proc. Даже анонимные файлы отслеживаются в таких метаданных. /proc/[PID]/exe обычно указывает на путь бинарного файла, такой как /usr/bin/python3. Процесс memfd будет указывать на виртуальный путь, часто помеченный как memfd: (deleted).

Поиск вредоноса в файловой системе

— Карты памяти (memory maps). Анализ /proc/[PID]/maps или smaps показывает следы атаки. Ищите сегменты памяти с правами на выполнение (r-xp), которые сопоставлены с объектом memfd, а не с общедоступной библиотекой или известным бинарным файлом на диске.

Поиск вредоноса на карте памяти

Related