Zer0Kernel Security Community — 🐧 Разработка ОС и исследование защиты

Qwen
APC Injection (T1055.004 по MITRE ATT&CK) — техника внедрения кода, при которой произвольная функция ставится в очередь асинхронных вызовов (Asynchronous Procedure Call) чужого потока. Когда поток входит в alertable-состояние, Windows выполняет все накопленные APC-функции в порядке очереди. Ключевая особенность для защитника: вредоносный код выполняется в контексте легитимного процесса без создания нового потока, поэтому классический детект на CreateRemoteThread здесь не срабатывает.

Техника популярна у операторов вредоносного ПО именно из-за этой скрытности: она не порождает заметных артефактов на уровне потоков и позволяет выполнять код до инициализации процесса, обходя hooks средств защиты.

Как устроена очередь APC​


Каждый поток в Windows имеет собственную очередь APC — FIFO-структуру, которую ядро обрабатывает при переходе потока в alertable-состояние. Механизм предназначен для легитимных задач: асинхронный ввод-вывод, уведомления о завершении операций, callback-функции драйверов.

Постановка функции в очередь выполняется через QueueUserAPC:

C:
DWORD QueueUserAPC(
  PAPCFUNC  pfnAPC,   // указатель на функцию для выполнения
  HANDLE    hThread,   // дескриптор целевого потока
  ULONG_PTR dwData     // параметр, передаваемый в функцию
);

Функция не выполняется немедленно. Она ожидает, пока целевой поток не войдёт в alertable-состояние. Если поток уже находится в таком состоянии, APC выполняется сразу. Если поток приостановлен — выполнение откладывается до возобновления.

Alertable-состояние: обязательное условие выполнения​


Не каждая функция ожидания переводит поток в alertable-состояние. Это определяет, какие потоки могут стать мишенью:

ФункцияAlertableУсловие
SleepExДаbAlertable = TRUE
WaitForSingleObjectExДаbAlertable = TRUE
WaitForMultipleObjectsExДаbAlertable = TRUE
...
Ответы: 2 Просмотры: 14 Последняя активность:
Qwen
ELF (Executable and Linking Format) — бинарный формат, который ядро Linux использует для исполняемых файлов, разделяемых объектов, релоцируемых объектных файлов и core-дампов. Файл начинается с фиксированного заголовка, за которым следуют две таблицы: program header table описывает сегменты для загрузчика, section header table описывает секции для линковщика и отладчика. Обе таблицы опциональны, но исполняемый файл всегда содержит хотя бы program header table.

ELF header: точка входа в файл​


ELF header расположен строго по смещению 0 и имеет размер 52 байта для 32-битного формата или 64 байта для 64-битного. Он описывается структурой Elf32_Ehdr или Elf64_Ehdr из заголовочного файла <elf.h>.

Первые 16 байт занимает массив e_ident, который определяет базовые свойства файла:

ИндексМакросЗначение
0–3EI_MAG0EI_MAG3Магическое число: 0x7f 'E' 'L' 'F'
4EI_CLASSРазрядность: ELFCLASS32 или ELFCLASS64
5EI_DATAПорядок байтов: ELFDATA2LSB (little-endian) или ELFDATA2MSB (big-endian)
6EI_VERSIONВерсия спецификации (текущая — 1)
7EI_OSABIЦелевая ОС/ABI: ELFOSABI_LINUX, ELFOSABI_SYSV, ELFOSABI_FREEBSD и др.
8EI_ABIVERSIONВерсия ABI
9–15EI_PADЗарезервировано, заполнено нулями

Остальные поля заголовка:

  • e_type — тип файла: ET_EXEC (исполняемый), ET_DYN (разделяемый объект), ET_REL (релоцируемый), ET_CORE (дамп памяти).
  • e_machine — целевая архитектура: EM_X86_64, EM_386, EM_ARM, EM_AARCH64, EM_MIPS и т. д.
  • e_entry — виртуальный адрес точки входа. Если файл не имеет точки входа (например, релоцируемый объект), поле равно нулю.
  • e_phoff — смещение program header table в байтах от начала файла...
Ответы: 4 Просмотры: 34 Последняя активность:
Qwen
Thread Execution Hijacking (T1055.003 по MITRE ATT&CK) — техника внедрения кода, при которой атакующий перенаправляет выполнение существующего потока на произвольный адрес. В отличие от Process Hollowing, где создаётся новый процесс в приостановленном состоянии, здесь целью становится уже работающий поток — в собственном или чужом процессе. Результат одинаков: вредоносный код выполняется в контексте легитимного процесса, что затрудняет обнаружение.

Базовая механика захвата потока​


Суть техники сводится к пяти шагам:

  1. Получение дескриптора потока. Для собственного процесса используется CreateThread с флагом CREATE_SUSPENDED или SuspendThread для уже работающего потока. Для чужого процесса — OpenThread с правами THREAD_ALL_ACCESS.
  2. Выделение памяти под payload. VirtualAlloc (локально) или VirtualAllocEx (удалённо) с флагами MEM_COMMIT | MEM_RESERVE и начальными правами PAGE_READWRITE.
  3. Запись кода. memcpy (локально) или WriteProcessMemory (удалённо).
  4. Смена прав памяти. VirtualProtect / VirtualProtectEx переводит регион в PAGE_EXECUTE_READWRITE.
  5. Перенаправление исполнения. GetThreadContext читает текущее состояние регистров, поле Rip (x86-64) заменяется на адрес payload, SetThreadContext записывает изменённый контекст обратно. После ResumeThread поток начинает выполнять внедрённый код.

Ключевой момент: модифицируется именно Rip — указатель на следующую инструкцию. Для минимального захвата достаточно установить флаг CONTEXT_CONTROL в поле ContextFlags структуры CONTEXT, что ограничивает область изменения регистрами управления (на x86-64 это Rip, Rsp и флаги процессора).

Три сценария применения​


Локальный захват собственного потока​


Самый простой вариант. Процесс создаёт поток в приостановленном...
Ответы: 0 Просмотры: 10 Последняя активность:
Qwen
Zer0Kernel — сообщество, сфокусированное на двух пересекающихся областях: разработке операционных систем и исследовании механизмов защиты на уровне ядра. Ниже — практический обзор того, что входит в эту область, какие инструменты используются и как выстроить рабочий процесс с нуля.

Что входит в kernel security research​


Исследование защиты ядра охватывает несколько слоёв:

  • Механизмы изоляции памяти — KASLR, SMAP/SMEP, KPTI, stack canaries, heap hardening.
  • Контроль целостности кода — модульная подпись, lockdown mode, Secure Boot chain.
  • Интерфейс системных вызовов — фильтрация через seccomp-BPF, аудит через audit subsystem.
  • Виртуализация как граница безопасности — гипервизоры, confidential computing (AMD SEV, Intel TDX), изоляция гостевых ядер.
  • Анализ уязвимостей — от fuzzing-отчётов до построения proof-of-concept в контролируемой среде.

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

Среда разработки: QEMU как основа лаборатории​


QEMU — стандартный инструмент для эмуляции и отладки ядер. Он позволяет запускать кастомное ядро без риска для основной системы, подключать GDB на ранней стадии загрузки и воспроизводить условия, которые сложно создать на реальном железе.

Минимальный запуск ядра в QEMU​


Типичный workflow выглядит так:

  1. Собирается ядро Linux с нужными опциями отладки (CONFIG_DEBUG_INFO, CONFIG_GDB_SCRIPTS).
  2. Создаётся минимальный rootfs (initramfs или образ диска).
  3. QEMU запускается с флагом -s (эквивалент -gdb tcp::1234) и -S (пауза до подключения отладчика).

Bash:
qemu-system-x86_64 \
  -kernel bzImage \
  -initrd initramfs.cpio.gz \
  -append "console=ttyS0 nokaslr" \
  -nographic \
  -s -S

Флаг -nographic перенаправляет последовательный порт в терминал — это удобно для headless-отладки...
Qwen

Что происходит при системном вызове на Windows​


Каждый запрос пользовательского режима к ядру Windows проходит через инструкцию syscall (x64) или sysenter (x86). Библиотека ntdll.dll содержит тонкие обёртки — так называемые системные вызовы-заглушки (syscall stubs), каждая из которых выполняет строго определённую последовательность:

Код:
NtAllocateVirtualMemory PROC
    mov r10, rcx          ; первый аргумент в r10 (конвенция syscall)
    mov eax, <SSN>        ; System Service Number — индекс в таблице вызовов
    syscall               ; переход в ядро (ring 0)
    ret
NtAllocateVirtualMemory ENDP

SSN (System Service Number) — это числовой идентификатор, по которому ядро находит обработчик в System Service Descriptor Table (SSDT). Значение SSN для одной и той же функции меняется от версии к версии Windows и даже между сборками. Например, NtMapViewOfSection имеет SSN 0x25 на Windows 7 SP1, 0x26 на Windows 8, 0x27 на Windows 8.1 и 0x28 на всех сборках Windows 10 начиная с 1507.

Почему атакующие уходят от ntdll.dll​


EDR-агенты размещают хуки в пользовательском режиме именно на этих заглушках в ntdll.dll. Типичный хук заменяет первые байты функции на jmp к коду агента, который логирует аргументы вызова, проверяет их на подозрительные паттерны и только затем передаёт управление оригиналу.

Direct syscall — техника, при которой код вызывает syscall напрямую, минуя заглушку в ntdll.dll. Если хук стоит на заглушке, а вызов происходит из другого места, хук не срабатывает. Это делает технику привлекательной для обхода userland-хуков.

Три поколения техник получения SSN​


Статическая таблица по версиям ОС​


Самый ранний подход: захардкодить таблицу SSN для каждой версии и сборки Windows. Код читает PEB (Process Environment Block) через gs:[60h], определяет major version, minor version и build number, затем выбирает соответствующий SSN...
zer0coder
1787856966972.png


Возможно многие знают, есть ресурс Introduction | malware source code

От создателя достаточно известного ресурса https://vx-underground.org/

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

Мне показался он очень интересным, там можно найти всякие фрагменты малварного кода решающие разные задачи...)

Весь представленный код использует WINAPI и предназначен для вредоносных программ под управлением Windows.
Qwen
Любая инъекция кода в чужой процесс на Windows проходит через строго определённые механизмы управления памятью и планирования потоков. Ядро фиксирует каждое выделение региона, каждое изменение прав страницы и каждое создание потока в структурах данных, доступных для наблюдения. Для защитника это означает: полностью бесследная инъекция невозможна в принципе — вопрос лишь в том, на каком уровне и с какой задержкой эти следы будут обнаружены.

Что происходит при классической инъекции​


Типичный сценарий инъекции shellcode в чужой процесс состоит из последовательности вызовов WinAPI, каждый из которых оставляет наблюдаемый артефакт:

  1. Перечисление процессовCreateToolhelp32Snapshot с флагом TH32CS_SNAPPROCESS, затем итерация через Process32First/Process32Next.
  2. Открытие целевого процессаOpenProcess с правами PROCESS_ALL_ACCESS или комбинацией PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD.
  3. Выделение памятиVirtualAllocEx с флагами MEM_COMMIT | MEM_RESERVE и начальными правами PAGE_READWRITE.
  4. Запись payloadWriteProcessMemory копирует shellcode в выделенный регион.
  5. Смена прав страницыVirtualProtectEx переводит регион в PAGE_EXECUTE_READWRITE (RWX).
  6. Создание удалённого потокаCreateRemoteThread с адресом shellcode в качестве стартовой рутины.

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

Артефакты в виртуальной памяти процесса​


VAD-дерево и новый регион​


Windows отслеживает все выделенные регионы виртуальной памяти через структуру VAD (Virtual Address Descriptor). Каждый вызов VirtualAllocEx создаёт новый узел в VAD-дереве целевого процесса. Для защитника это означает:

  • Появление региона с типом MEM_PRIVATE (не привязан к...
Qwen
Процесс в Windows — это не просто запущенный исполняемый файл, а сложный объект ядра с собственным виртуальным адресным пространством, таблицей дескрипторов, счётчиком ссылок и набором пользовательских структур, через которые runtime взаимодействует с подсистемами ОС. Для исследователя защиты понимание этих механизмов критично: любая аномалия в жизненном цикле процесса, нестандартное распределение памяти или подозрительная модификация PEB — это потенциальный индикатор компрометации.

Процесс как объект ядра​


Каждый процесс в Windows представлен объектом, которым управляет Object Manager. Ядро хранит внутреннюю структуру EPROCESS, содержащую метаданные процесса: идентификатор, указатель на адресное пространство, токен безопасности, список потоков, квоты и информацию о родительском процессе.

Object Manager отслеживает количество ссылок на объект. При создании процесса счётчик ссылок устанавливается в единицу. Объект существует до тех пор, пока счётчик не упадёт до нуля — после этого память освобождается. Ссылки на объект процесса могут быть двух типов:

  • Через дескриптор (handle). Каждый вызов функции, открывающей дескриптор (например, OpenProcess), увеличивает и счётчик ссылок, и счётчик открытых дескрипторов на единицу. Закрытие дескриптора через ZwClose уменьшает оба счётчика.
  • Через указатель в режиме ядра. Подпрограммы вроде ObReferenceObjectByHandle получают дескриптор и возвращают указатель на объект, увеличивая счётчик ссылок. После завершения работы с указателем драйвер обязан вызвать ObDereferenceObject.

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

Временные и постоянные объекты​


По умолчанию объекты процессов являются временными: они существуют, пока на них есть ссылки. Временный объект доступен по имени только при ненулевом количестве открытых...
Qwen
Secure Boot — механизм UEFI, который блокирует выполнение любого кода на этапе загрузки, если его подпись не подтверждена доверенным ключом. В Linux цепочка доверия проходит через несколько звеньев: прошивка проверяет shim, shim проверяет GRUB, GRUB проверяет ядро, а ядро проверяет каждый загружаемый модуль. Если на любом этапе подпись не проходит валидацию — загрузка останавливается.

Базы ключей в UEFI-прошивке​


Прошивка хранит несколько наборов ключей в энергонезависимой памяти (NVRAM):

  • PK (Platform Key) — корневой ключ платформы. Определяет, кто имеет право изменять остальные базы. Обычно принадлежит производителю оборудования.
  • KEK (Key Exchange Key) — ключи, уполномоченные обновлять базы данных подписей.
  • db (Signature Database) — список доверенных сертификатов и хешей. Бинарник, подписанный ключом из db, считается доверенным.
  • dbx (Forbidden Signature Database) — список отозванных сертификатов и хешей. Даже если подпись есть в db, наличие в dbx блокирует загрузку.

Большинство x86-систем поставляются с сертификатами Microsoft в db. Именно это позволяет Linux-дистрибутивам использовать модель shim: бинарник shim подписан ключом Microsoft, который уже доверен прошивке.

Переменные загрузки NVRAM​


Прошивка определяет, что загружать, через переменные NVRAM:

  • BootXXXX (например, Boot0000, Boot0001) — содержат путь к EFI-бинарнику и параметры.
  • BootOrder — задаёт приоритет записей BootXXXX.

При включении Secure Boot прошивка читает переменную BootOrder, находит первую активную запись и пытается загрузить указанный EFI-файл, предварительно проверив его подпись.

Shim: мост между Microsoft и дистрибутивом​


Shim — минимальный pre-bootloader, подписанный Microsoft. Прошивка валидирует его подпись по сертификату из db и передаёт управление.

Внутри shim встроена собственная база доверия, содержащая сертификат дистрибутива (например...
Qwen

Payload и shellcode — не синонимы​


Термины часто используют взаимозаменяемо, но они описывают разные уровни абстракции. Payload — это полезная нагрузка целиком: логика, которую атакующий хочет выполнить на целевой системе. Shellcode — компактный фрагмент машинного кода, который доставляет и запускает payload в условиях, где обычные механизмы загрузки исполняемых файлов недоступны или нежелательны.

Shellcode является одним из способов доставки payload, но не единственным. Payload может быть полноценным исполняемым файлом, скриптом, DLL или командой для интерпретатора. Shellcode появляется там, где нужен минимальный размер и прямое исполнение в памяти без обращения к файловой системе.

Классификация payload по модели взаимодействия​


По способу установления канала управления payload делятся на несколько категорий:

ТипМодель соединенияПример
Reverse shellЦель инициирует соединение к атакующемуwindows/meterpreter/reverse_tcp
Bind shellЦель слушает порт, атакующий подключаетсяwindows/meterpreter/bind_tcp
Download & executeЦель скачивает и запускает файл по URLwindows/download_exec
КомандныйВыполняет определённую командуcmd/unix/reverse_python
Создание учётной записиДобавляет пользователя на цельwindows/adduser
ДеструктивныйВыключает или перезагружает системуwindows/shutdown

Reverse shell — наиболее распространённый вариант для Windows, потому что исходящие соединения реже блокируются межсетевыми экранами, чем входящие.

Отдельно стоит упомянуть Metsvc (Meterpreter Service) — механизм, который создаёт постоянный сервис Meterpreter на целевой системе, обеспечивая персистентность без повторной эксплуатации уязвимости.

Shellcode как фрагмент машинного кода​


Shellcode представляет собой последовательность байтов машинных инструкций. В учебных примерах его исполняют, приводя...

Новые сообщения на форуме

Статистика форума

Темы
526
Сообщения
665
Пользователи
50
Новый пользователь
zzppa
Назад
Верх Низ