Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
elfpack — Набор инструментов для стыковки секций ELF-бинарных файлов для доставки бесстадийных полезных нагрузок, обеспечивающий присоединение полезной нагрузки в полевых условиях, обход сигнатур и устойчивость к статической/динамической загрузке с помощью манипуляции пользовательскими секциями ELF. | Kitploit
Инструменты/GitHubGitHub/dsnezhkov/elfpack
Генерация полезной нагрузкиЭксплуатацияАнализ вредоносных программТестирование на ПроникновениеАнализ Бинарных ФайловRed TeamingРазработка Полезной Нагрузки
GitHubdsnezhkov/elfpack

elfpack

Репозиторий
5110134 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →

Описание

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

Поделиться

ElfPack: Стыковка секций ELF-бинарников для доставки полезной нагрузки без стадий

Основные моменты

  • Обзор механизмов упаковки полезной нагрузки: компиляция, компоновка и загрузка.
  • Двоичная совместимость и создание слабо связанных полезных нагрузок с их механизмом доставки.
  • Избежание автоматической загрузки секций в память.
  • Использование структурированных типов секций.
  • Повторное присоединение полезной нагрузки в полевых условиях к загрузчикам через секции ELF. Используйте свою собственную полезную нагрузку.
  • Обход сигнатур с помощью отдельно предкомпилированных секций ELF.
  • Автоматическое (drive-by) присоединение полезных нагрузок к загрузчикам с помощью конвейера генерации полезных нагрузок.
  • Создание «жирных» бинарников полезной нагрузки и обоснование отказа от двоичных упаковщиков.
  • Упаковка сложных полезных нагрузок.
  • Варианты обфускации полезной нагрузки и защиты ключей.
  • Устойчивость к статическому и динамическому трассированию загрузки полезной нагрузки. Binwalk и eBPF.

Встраивание полезных нагрузок

Включение hex-бинарников при компиляции и компоновке

  1. Непосредственно в секции данных по умолчанию или в .text: Обычно компилятор размещает создаваемые им объекты в секциях, таких как .data.

payload.h:

const data[3432] = {
    0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
    ...
    0x00, 0xff, 0x23 
};

Достигается вручную или с помощью инструментов, таких как bin2c или xxd -i payload.bin > payload.h, с дальнейшим подключением заголовочного файла.

Хранение полезных нагрузок в .text и .data в общем виде также является плохой идеей из-за простоты отслеживания загрузки и анализа семантики поведения загружаемых данных для выполнения.

  1. В отдельной секции. Вы можете разместить данные полезной нагрузки в дополнительных секциях, или вам нужно, чтобы определённые переменные находились в специальных секциях. Это достигается с помощью механизма, зависящего от компилятора. В gcc это делается через __attribute__. Это немного лучше, но всё ещё хорошо отслеживается из-за того, как ELF создаётся и загружается.
char stack[10000] __attribute__ ((section ("binstack"))) = { 
    0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
    ...
    0x00, 0xff, 0x23 };
int init_data __attribute__ ((section ("bindata"))) = 0;

main()
{
    /* Initialize stack pointer */
    init_sp (stack + sizeof (stack));

    /* Initialize initialized data */
    memcpy (&init_data, &data, &edata - &data);
}
  1. Включение бинарника через компоновщик

Директива, аналогичная .incbin, зависящая от ассемблера, может создать секцию и встроить полезную нагрузку. Пример: gcc -c payload.s или ld -r -b payload.bin -o payload.o

.section .bindata

.global payload_start
.type payload_start, @object

.section .binddata
.balign 64

payload_start:
    .incbin "payload.bin"
    .balign 1
payload_end:
    .byte 0

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

int main(void) {
    extern uint8_t payload_start;
    uint8_t *ptrPayload = &payload_start;
    ...
}

Примечание: Мы можем включить полнофункциональный ELF в payload.bin, что важно при создании «жирных» бинарников, содержащих элементы нескольких тулкитов.

Примечание: Существуют более эргономичные инструменты для выполнения этой задачи, например INCBIN от @graphitemaster [link]

Вариация на тему — встроенный ассемблер, например так:

/* Raw image data for all embedded images */
 #undef EMBED
 #define EMBED( _index, _path, _name )                                   \
         extern char embedded_image_ ## _index ## _data[];               \
         extern char embedded_image_ ## _index ## _len[];                \
         __asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"       \
                   "\nembedded_image_" #_index "_data:\n\t"              \
                   ".incbin \"" _path "\"\n\t"                           \
                   "\nembedded_image_" #_index "_end:\n\t"               \
                   ".equ embedded_image_" #_index "_len, "               \
                         "( embedded_image_" #_index "_end - "           \
                         "  embedded_image_" #_index "_data )\n\t"       \
                   ".previous\n\t" );
 EMBED_ALL
 
 /* Image structures for all embedded images */
 #undef EMBED
 #define EMBED( _index, _path, _name ) {                                 \
         .refcnt = REF_INIT ( ref_no_free ),                             \
         .name = _name,                                                  \
         .data = ( userptr_t ) ( embedded_image_ ## _index ## _data ),   \
         .len = ( size_t ) embedded_image_ ## _index ## _len,            \
 },
 static struct image embedded_images[] = {
         EMBED_ALL
 };
 

Примечание: Обратите внимание на PROGBITS в определении секции, это будет важно.

Включение бинарника полезной нагрузки через компилятор/компоновщик не идеально

Есть компромиссы:

  • Процесс встраивания тесно связан с созданием загрузчика полезной нагрузки.
  • Что насчёт изменений формата полезной нагрузки?
  • По умолчанию секция, несущая данные, имеет флаги PROGBITS, и она будет загружена в память (PT_LOAD) загрузчиком ОС по умолчанию. Возможно, мы этого не хотим.

Представление секции ELF на диске/в памяти

Диаграмма ELF PROGBITS

Тип секции и флаги, установленные на новой секции, определяют, будет ли загрузчик ОС загружать её в память при запуске исполняемого файла. Некоторые секции загружаются автоматически по умолчанию, другие — нет (например, .symtab, .strtab)

С точки зрения атаки, какую эффективность мы можем из этого извлечь?

Встраивание полезных нагрузок: версия 2

  1. Мы можем избегать установки флагов на секции, которые предполагают загрузку в память по умолчанию.

  2. Мы можем использовать другой тип секции, который не загружается в память.

Поставщику или системному инженеру может потребоваться пометить объектный файл специальной информацией, которую другие программы могут проверить на соответствие или совместимость. Секции типа SHT_NOTE и элементы программного заголовка типа PT_NOTE могут использоваться для этой цели.

В последнем случае мы можем увидеть использование этого типа секции в системных бинарниках:

$ readelf --sections /bin/tar | grep NOTE
  [ 2] .note.gnu.bu[...] NOTE             00000000000002c4  000002c4
  [ 3] .note.ABI-tag     NOTE             00000000000002e8  000002e8

И можем проверить их содержимое:

$ readelf -p .note.ABI-tag /bin/tar

String dump of section '.note.ABI-tag':
  [     c]  GNU

Конечный результат создания секции SHT_NOTE в ELF будет выглядеть так: Секция SHT_NOTE

Бонус: SHT_NOTE предоставляет нам структуру, если мы захотим её использовать (а мы будем использовать её далее):

Структура SHT_NOTE

Стыковка секций ELF

До сих пор мы могли создать секцию и избежать её загрузки в память загрузчиком ОС. Секция фактически находится в спящем состоянии в образе ELF. Мы обсудим, как её загружать, немного позже. Однако более насущный вопрос заключается в том, что мы всё ещё работаем на уровне компилятора и компоновщика, и секция — это объект, который вплетается в структуру конечного ELF, создавая связи и адреса памяти из кода загрузчика, который ссылается на её содержимое.

Объект секции ELF

Что, если бы мы могли создать секцию ELF со встроенной полезной нагрузкой вне процесса компиляции загрузчика и присоединить эту секцию позже к бинарнику загрузчика?

Скачать инструмент