Ситуация знакома многим, кто работает с бинарниками: вы открываете файл, смотрите на структуру секций — всё выглядит чисто, но что-то не так. Размер файла больше, чем должен быть. Или антивирус странно реагирует. Или файл пришёл от кого-то, кому вы не доверяете на сто процентов. Вопрос простой: есть ли внутри что-то лишнее, спрятанное после последней секции?
Именно туда часто прячут вредоносный код — за пределами заголовков секций, в «мёртвой» зоне, которую стандартный парсер не читает. Разберёмся, как это обнаружить на практике.
- Почему payload прячут после секций
- Первый шаг: сравните размер файла с ожидаемым
- Инструменты, которые реально помогают
- Как проверить вручную на примере PE-файла
- Цифровая подпись или payload? Как не перепутать
- Автоматизация проверки на Python
- Энтропийный анализ: когда данные зашифрованы
- Частые ошибки при проверке
- Что делать, если payload найден
- Как выглядит чистый файл и как — заражённый
- Итог: алгоритм действий
Почему payload прячут после секций
Формат PE-файлов (Windows) и ELF (Linux) устроен так, что заголовки секций описывают логическую структуру: где код, где данные, где ресурсы. Но физически данные в файле могут занимать место и за пределами того, что описано в заголовках. Размер файла на диске определяется последней секцией плюс всё, что после неё накопилось.
Злоумышленники используют эту особенность по нескольким причинам:
- Дополнительные данные не видны в стандартных парсерах секций — инструмент просто не показывает их.
- Многие загрузчики ОС обращают внимание только на заголовки, а не на реальный размер файла.
- Данные после последней секции могут быть зашифрованы или обфусцированы, что усложняет статический анализ.
- Это один из самых простых способов встроить код без изменения структуры самого файла.
Первый шаг: сравните размер файла с ожидаемым
Самый быстрый способ понять, что что-то не так — сравнить реальный размер файла с тем, который должен быть. Для PE-файла расчёт идёт так:
Берёте адрес последней секции в заголовках, прибавляете её физический размер — это и есть ожидаемый конец файла. Если реальный размер больше, значит, после последней секции что-то есть.
На практике это выглядит примерно так:
- Открываете файл в PE-парсере (CFF Explorer, PE-bear, pefile на Python).
- Находите последнюю секцию в таблице секций.
- Считаете: PointerToRawData + SizeOfRawData = ожидаемый конец файла.
- Сравниваете с реальным размером файла на диске.
Разница даже в несколько сотен байт — уже повод присмотреться. Если разница — десятки килобайт или больше, это почти наверняка спрятанные данные.
Инструменты, которые реально помогают
Не нужно изобретать велосипед. Есть проверенные инструменты, которые делают эту работу за вас.
| Инструмент | Что умеет | Для какого формата | Уровень сложности |
|---|---|---|---|
| PE-bear | Показывает структуру секций, подсвечивает аномалии, визуализирует разрывы | PE (Windows) | Средний |
| CFF Explorer | Детальный разбор заголовков, расчёт размеров, сравнение | PE (Windows) | Средний |
| pefile (Python) | Скриптовый анализ, можно автоматизировать проверку | PE (Windows) | Продвинутый |
| readelf | Показывает секции и сегменты, можно сравнить размеры | ELF (Linux) | Продвинутый |
| objdump | Дамп заголовков и секций, удобен для быстрой проверки | ELF (Linux) | Средний |
| Detect It Easy (DIE) | Определяет упаковщики, крипторы, показывает подозрительные участки | PE и ELF | Начальный |
| binwalk | Ищет встроенные файлы и данные внутри бинарников | Любой формат | Средний |
Если вы только начинаете — начните с Detect It Easy. Он покажет упакованные участки и подозрительные зоны без необходимости разбираться в заголовках вручную. Если нужна автоматизация — pefile на Python ваш лучший друг.
Как проверить вручную на примере PE-файла
Допустим, у вас есть подозрительный .exe и вы хотите проверить его вручную. Вот пошаговый алгоритм:
-
Откройте файл в HEX-редакторе (HxD, 010 Editor). Сразу посмотрите на конец файла — если там идут повторяющиеся нули, скорее всего, это просто выравнивание. Если видите структурированные данные, похожие на другой файл (MZ-заголовок, ZIP-сигнатура, что-то читаемое) — это payload.
-
Найдите таблицу секций. В PE-файле она начинается после PE-сигнатуры. Каждая секция описана 40 байтами: имя, виртуальный размер, виртуальный адрес, размер сырых данных, указатель на сырые данные.
-
Вычислите конец последней секции. Берёте PointerToRawData последней секции, прибавляете SizeOfRawData. Запомните это смещение.
-
Посмотрите, что дальше. Перейдите в HEX-редакторе к этому смещению. Всё, что есть от этой точки до конца файла — данные за пределами секций.
-
Проверьте, что это. Это может быть цифровая подпись (Authenticode) — она легально располагается после секций. Может быть отладочная информация. А может быть и вредоносный код.
Цифровая подпись или payload? Как не перепутать
Это частая ловушка. Цифровые подписи (Authenticode) действительно хранятся после последней секции — это стандартное поведение Windows. Отличить подпись от реального payload несложно:
- Подпись начинается с характерной структуры WIN_CERTIFICATE, имеет фиксированный заголовок.
- Размер подписи указан в заголовке PE-файла (DataDirectory[4] — Security Directory).
- Если размер данных после последней секции совпадает с размером в Security Directory — это подпись, не трогайте.
- Если данных больше, чем указано в подписи — после подписи что-то ещё дописано. Вот это уже подозрительно.
Автоматизация проверки на Python
Если нужно проверять много файлов или встроить анализ в пайплайн, вот минимальный скрипт на pefile:
import pefile
import sys
def check_for_extra_data(filepath):
pe = pefile.PE(filepath)
# Находим последнюю секцию
last_section = pe.sections[-1]
end_of_sections = last_section.PointerToRawData + last_section.SizeOfRawData
# Реальный размер файла
actual_size = pe.OPTIONAL_HEADER.SizeOfImage
# Проверяем данные после последней секции
if actual_size > end_of_sections:
extra_size = actual_size - end_of_sections
print(f"Найдены данные после последней секции: {extra_size} байт")
# Читаем эти данные
pe.__data__[end_of_sections:end_of_sections+64]
# Покажем первые 64 байта для анализа
extra_data = pe.get_data(end_of_sections, min(extra_size, 64))
print(f"Первые байты: {extra_data.hex()}")
else:
print("Данных после последней секции не обнаружено")
check_for_extra_data(sys.argv[1])
Этот скрипт — отправная точка. В реальном анализе добавьте проверку на сигнатуры известных форматов (MZ, PK, ELF), поиск строк, энтропийный анализ.
Энтропийный анализ: когда данные зашифрованы
Если payload зашифрован или сжат, вы не увидите в HEX-редакторе ничего читаемого. Но зашифрованные данные имеют высокую энтропию — близкую к 8.0 (максимум для байтового распределения). Обычный код и данные имеют энтропию 4.0–6.5.
Как это использовать:
- Разбиваете файл на блоки по 256–512 байт.
- Считаете энтропию каждого блока.
- Смотрите, где после последней секции идёт резкий скачок энтропии к 7.5+.
- Это почти наверняка зашифрованный или сжатый payload.
Binwalk делает это автоматически. Запустите binwalk -E файл.exe — и увидите график энтропии по всему файлу.
Частые ошибки при проверке
Когда люди впервые начинают искать скрытый payload, они обычно наступают на одни и те же грабли:
-
Путают виртуальный размер с физическим. VirtualSize может быть меньше SizeOfRawData из-за выравнивания. Всегда работайте с PointerToRawData и SizeOfRawData — это физическое расположение в файле.
-
Забывают про цифровую подпись. Видят данные после последней секции и сразу кричат «вирус», хотя это легальная подпись. Сначала проверьте Security Directory.
-
Не учитывают выравнивание (alignment). PE-файлы выравнивают секции по границам секций диска (обычно 512 байт). Размер файла может быть чуть больше из-за добивания нулями — это не payload.
-
Полагаются только на один инструмент. Каждый парсер может по-разному интерпретировать повреждённые заголовки. Перепроверяйте в двух-трёх инструментах.
-
Игнорируют аномалии в самих заголовках секций. Если секция называется .rsrc, но внутри исполняемый код с высокой энтропией — это тоже маркер проблемы, даже если данных после секций нет.
Что делать, если payload найден
Итак, вы обнаружили данные после последней секции. Дальнейшие действия зависят от вашей ситуации:
Если вы анализируете подозрительный файл:
- Не запускайте его. Вообще.
- Извлеките данные после секций в отдельный файл для анализа.
- Проверьте их в VirusTotal.
- Проанализируйте энтропию — если высокая, скорее всего зашифрованный код.
- Попробуйте найти строки, URL, IP-адреса внутри извлечённых данных.
Если вы разработчик и проверяете свой файл:
- Убедитесь, что компилятор не добавляет лишнего. Некоторые линкеры встраивают отладочную информацию или ключи.
- Проверьте, не прицепился ли вирус к вашему бинарнику — бывает и такое.
- Удалите отладочные данные перед публикацией релиза.
Если вы в корпоративной среде и анализируете входящие файлы:
- Автоматизируйте проверку через pefile или YARA-правила.
- Настройте блокировку файлов с аномальными данными после секций.
- Логируйте все случаи для дальнейшего расследования.
Как выглядит чистый файл и как — заражённый
Для ориентира: в «чистом» файле разница между концом последней секции и размером файла обычно не превышает размера цифровой подписи (если она есть) или пары сотен байт на выравнивание. Если вы видите разницу в несколько килобайт и больше, при этом цифровой подписи нет или она не покрывает весь объём лишних данных — это тревожный сигнал.
В заражённом файле после последней секции может находиться:
- Дроппер — код, который при запуске извлекает основную полезную нагрузку.
- Зашифрованный основной payload с дешифратором в начале.
- Конфигурация для управления вредоносным кодом (C2-серверы, команды).
- Дополнительные DLL или исполняемые файлы, встроенные как ресурс вне официальной структуры.
Итог: алгоритм действий
Если запомнить минимум, вот что нужно делать каждый раз, когда есть подозрение на скрытый payload:
- Сравните размер. Конец последней секции против реального размера файла. Есть разница — идём дальше.
- Отключите цифровую подпись из уравнения. Вычтите размер подписи, если она есть.
- Посмотрите в HEX-редакторе. Что там: нули, читаемые данные, сигнатуры других форматов?
- Проверьте энтропию. Высокая — значит зашифровано или сжато.
- Извлеките и проанализируйте. Отдельный файл, VirusTotal, статический анализ.
Это базовый набор, который отнимает минуты, но может сэкономить часы расследования инцидента. Главное — не останавливаться на первом шаге, если что-то показалось подозрительным. Скрытый payload после последней секции — один из самых распространённых и одновременно самых недооценённых векторов атары. Проверяйте файлы целиком, а не только то, что показывают заголовки.
