База сильного Red Team: exploitation, Windows/AD, Linux, reversing и инструменты

Курс систематизирует фундаментальные знания для offensive security: от мышления exploit-разработчика и внутренних механизмов ОС до атак на Active Directory и разработки собственных инструментов. Программа опирается на ключевые книги из списка и выстраивает рекомендуемый порядок освоения базы перед продвинутыми темами.

1. Мышление exploit-разработчика: память, C, отладка и базовый exploitation

Мышление exploit-разработчика: память, C, отладка и базовый exploitation

Зачем это нужно в Red Team

Exploitation для Red Team — это не «умение писать эксплойты на все случаи», а способ мышления:

  • Быстро понимать, почему программа сломалась.
  • Уметь превратить «краш» в понятную модель: где данные, где контроль потока, какие ограничения.
  • Разговаривать на одном языке с реверсом, Windows/AD и Linux-модулями курса.
  • Эта статья задаёт фундамент: память, базовый C, отладка, типовые классы ошибок и то, как exploit-разработчик их анализирует. В следующих статьях курса этот фундамент будет применяться к Linux/Windows внутренностям, AD-атакам, reversing и инструментам.

    > Важно: всё ниже — для легальной работы в лаборатории, CTF и авторизованных тестов. Не применяйте знания к системам без явного разрешения.

    Что отличает exploit-мышление

    Exploit-разработчик смотрит на любую программу через несколько вопросов:

  • Где лежат данные? (stack/heap/global, сегменты памяти)
  • Кто и как ими управляет? (код, аллокатор, ABI/соглашения вызова)
  • Что будет, если данные «не такие»? (переполнение, выход за границы, use-after-free)
  • Можно ли из ошибки получить контроль? (контроль данных, затем контроль потока)
  • Какие есть ограничения среды? (ASLR, NX/DEP, canary, CFG, sandbox)
  • Ключевой переход: вы перестаёте воспринимать «уязвимость» как магию и начинаете воспринимать её как ошибку в модели памяти и доверии к данным.

    Минимальная модель памяти процесса

    Процесс в ОС обычно имеет виртуальное адресное пространство: программе кажется, что у неё есть «свой» непрерывный диапазон адресов, хотя физически память может быть разбросана.

    Типичные области:

  • Code (text): исполняемые инструкции.
  • Data/BSS: глобальные и статические переменные.
  • Heap: динамические выделения (malloc/new).
  • Stack: локальные переменные и контекст вызовов функций.
  • Memory-mapped regions: библиотеки, файлы, анонимные маппинги.
  • !Общая карта областей памяти процесса и направления роста стека и кучи

    Адреса, указатели и размерность

    В C/C++ указатель — это число, интерпретируемое как адрес. Важно помнить:

  • На 64-битных системах указатель обычно 8 байт, на 32-битных — 4 байта.
  • Один и тот же байтовый набор можно трактовать по-разному в зависимости от типа.
  • Ошибки возникают, когда программа думает, что работает с одним объектом, а фактически обращается к другому месту памяти.
  • Endianness (порядок байт)

    На большинстве современных x86/x64 систем порядок байт little-endian: младший байт числа хранится по меньшему адресу. Это важно при чтении дампов памяти и работе с отладчиком.

    Стек: вызовы функций как «цепочка кадров»

    Стек — это структура данных, используемая для:

  • хранения адреса возврата,
  • сохранения регистров/контекста,
  • локальных переменных,
  • передачи части аргументов (зависит от ABI).
  • Стековый кадр (stack frame)

    Упрощённо, при вызове функции формируется кадр стека: «контейнер» для её выполнения.

    !Как устроен типичный кадр стека и где обычно находятся локальные буферы и адрес возврата

    Что важно для мышления exploit-разработчика:

  • Любая запись «мимо» локального массива потенциально может затронуть соседние данные.
  • Соседними могут быть как обычные переменные, так и критичные значения управления (например, адрес возврата), но современные защиты часто мешают прямому захвату контроля.
  • Куча: динамическая память и аллокатор

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

    Ключевые понятия:

  • allocation: выделение блока (объекта) на куче.
  • free: освобождение блока.
  • metadata аллокатора: служебные данные, которые аллокатор хранит рядом/вокруг блоков.
  • Типичные классы ошибок в куче:

  • Use-after-free: использование объекта после освобождения.
  • Double free: повторное освобождение.
  • Heap overflow: выход за границы блока.
  • Для Red Team важен навык: по симптомам (краш, странные значения, нестабильность) распознать, что проблема в времени жизни объекта или в границах.

    C как язык, где легко ошибиться (и почему он нужен)

    C остаётся базой exploitation, потому что:

  • он близок к памяти и не скрывает указатели;
  • множество системного кода и библиотек написаны на C/C++;
  • многие уязвимости — прямое следствие отсутствия встроенных проверок границ.
  • Строки в C: массив байт + \0

    Строка в C — это массив char, заканчивающийся нулевым байтом \0. Ошибки возникают, когда:

  • забыли добавить \0,
  • неверно посчитали длину,
  • использовали небезопасные функции работы со строками.
  • Пример учебной программы с ошибкой границ, которая может приводить к крашу (пример нужен, чтобы учиться находить корень проблемы в отладчике, а не чтобы «эксплуатировать»):

    Что должен заметить exploit-разработчик:

  • buf имеет фиксированный размер 8.
  • strcpy копирует до \0 без проверки длины.
  • Длинный ввод перезапишет соседнюю память → поведение не определено.
  • Undefined Behavior (неопределённое поведение)

    Многие ошибки памяти в C формально относятся к неопределённому поведению: стандарт языка не гарантирует, что произойдёт. Для практики это значит:

  • баг может «исчезать» при добавлении printf;
  • баг может проявляться по-разному на разных сборках/оптимизациях;
  • отладка должна опираться на факты: дампы, регистры, трассировку.
  • Целочисленные переполнения

    Даже без «записи мимо буфера» уязвимости возникают, когда размер вычисляется неверно.

    Примеры рисков:

  • вычислили длину в 32-битном типе, получили переполнение, выделили меньше памяти, чем нужно;
  • использовали знаковый тип там, где ожидали беззнаковый.
  • Базовые классы уязвимостей и «что в них ищут»

    Ниже — не «как атаковать», а как классифицировать баги и что они означают для контроля.

    Переполнение буфера (buffer overflow)

    Суть: запись за пределы массива.

    Мышление:

  • определить границу массива и источник данных;
  • понять, что рядом в памяти и что может быть затронуто;
  • оценить влияние защит компилятора/ОС.
  • Format string

    Суть: использование пользовательской строки как форматной для printf-подобных функций.

    Мышление:

  • пользователь контролирует интерпретацию аргументов;
  • возможны утечки данных и запись через специальные спецификаторы в некоторых реализациях;
  • часто это путь к информационным утечкам, помогающим обходить ASLR.
  • Use-after-free

    Суть: ссылка на объект остаётся и используется после free.

    Мышление:

  • найти, где объект освобождается и кто ещё хранит на него указатель;
  • проверить, возможно ли «переприсвоить» память другим объектом (re-allocation);
  • оценить детерминированность воспроизведения.
  • Защиты, которые нужно знать с первого дня

    Современный exploitation почти всегда начинается с вопроса: какие защиты включены.

  • ASLR: рандомизация адресов (сложнее предсказать расположение кода/библиотек).
  • NX/DEP: запрет исполнения данных (например, стек/куча не исполняемы).
  • Stack canary: детектор перезаписи стека перед возвратом из функции.
  • PIE: позиционно-независимые бинарники (усиливает ASLR для основного модуля).
  • CFG (Windows): контроль допустимых переходов косвенных вызовов.
  • Вывод для мышления:

  • часто первым шагом становится понимание утечек и ориентирование в адресном пространстве;
  • «классический» сценарий с прямым перезаписыванием адреса возврата может быть невозможен без дополнительных условий.
  • Отладка как основной инструмент

    Exploit-разработчик почти всегда работает в связке:

  • отладчик (смотреть регистры, стек, память, точки останова),
  • инструменты диагностики памяти (санитайзеры, Valgrind),
  • символы/карта кода (если есть),
  • минимальный воспроизводимый пример.
  • Базовый отладочный цикл

    Практический рабочий подход:

  • Воспроизвести проблему стабильно (одинаковый ввод, окружение, версия бинарника).
  • Зафиксировать симптом (сигнал/исключение, адрес падения, тип доступа).
  • Найти точку, где данные стали некорректными (watchpoint, трассировка записи).
  • Свести до минимального кейса.
  • Сделать вывод: это баг логики, баг памяти, гонка, неверное предположение о длине.
  • Что смотреть при краше

    Минимальный набор наблюдений:

  • адрес и тип исключения (например, чтение/запись по неверному адресу);
  • текущая инструкция (где упало);
  • значения регистров;
  • кусок стека вокруг текущего указателя стека;
  • где находится «подозрительный» буфер и чем он перезаписан.
  • Пример типичного вывода отладчика при падении (упрощённо, без привязки к конкретной ОС):

    Как это интерпретировать:

  • SIGSEGV означает ошибку доступа к памяти.
  • адрес 0x0 часто указывает на разыменование NULL.
  • RIP (на x64) указывает на инструкцию, где произошла ошибка.
  • RSP — вершина стека в момент падения.
  • Инструменты, которые стоит освоить

    По платформам:

  • Linux: gdb, lldb, AddressSanitizer.
  • Windows: WinDbg, x64dbg, Application Verifier.
  • По практике Red Team полезнее не «знать все команды», а уметь:

  • ставить breakpoints и смотреть контекст;
  • искать место записи, которое портит данные;
  • делать дампы памяти и сопоставлять их с исходным кодом/дизассемблированным кодом.
  • Как безопасно прокачиваться в лаборатории

    Чтобы учиться быстро и без «магии», настройте учебную среду:

  • Отдельная VM для Linux и отдельная для Windows.
  • Репозиторий с маленькими программами-мишенями, написанными вами.
  • Сборка с диагностикой:
  • - sanitizers для ловли выходов за границы и use-after-free; - предупреждения компилятора (максимально строгие) как часть привычки.

    Цель лаборатории на этом этапе: не эксплойт, а уверенное умение объяснить:

  • что именно сломалось;
  • какие данные были повреждены;
  • какая строка/инструкция стала источником повреждения.
  • Что читать по теме (из списка курса)

    Основные книги, которые хорошо ложатся на эту статью:

  • Hacking: The Art of Exploitation (No Starch Press) — фундаментальная связка C, память, отладка, мышление.
  • The Shellcoder’s Handbook (Wiley) — подход к уязвимостям и анализу ограничений.
  • The Linux Programming Interface (No Starch Press) — процессы, память, syscalls как база для понимания Linux-багов.
  • Документация инструментов:

  • GDB: The GNU Project Debugger — официальный сайт и документация.
  • WinDbg documentation (Microsoft Learn) — официальная документация по отладке в Windows.
  • Итог

    Мышление exploit-разработчика строится на трёх опорах:

  • Понимание модели памяти (stack/heap/segments, указатели, время жизни объектов).
  • Практический C: строки, массивы, целочисленные типы и источники UB.
  • Системная отладка: воспроизведение, локализация, доказательства, минимизация.
  • Если вы уверенно делаете разбор краша и можете словами объяснить «какая память была повреждена и почему», вы уже на траектории сильного exploitation. Дальше в курсе мы будем накладывать на эту базу особенности Linux и Windows, а также применять это мышление в AD/Red Team сценариях и reversing.

    2. Windows Internals I: процессы, токены, security model и примитивы атак

    Windows Internals I: процессы, токены, security model и примитивы атак

    Зачем это нужно в Red Team

    В предыдущей статье мы разобрали мышление exploit-разработчика: память, контроль данных и потока, отладку и то, как превращать краш в модель. В Windows-части курса мы переносим тот же подход на уровень ОС: вместо где в памяти лежит буфер мы начинаем думать какой объект ОС защищён, каким токеном, какими правами и какой проверкой доступа.

    Для Red Team это даёт практическую базу:

  • Понимать, почему один и тот же приём (инжект, дамп LSASS, доступ к SCM) на одной машине работает, а на другой нет.
  • Быстро находить примитив: что можно прочитать, куда можно записать, что можно запустить, что можно выдать за себя.
  • Уверенно читать логику инструментов (Sysinternals, C2, post-exploitation), потому что они опираются на те же внутренности Windows.
  • > Все примеры и обсуждение примитивов рассчитаны на легальную лабораторию и авторизованные тесты.

    Картина Windows: объекты, процессы, потоки, дескрипторы

    Windows можно понимать как систему, где почти всё важное представлено объектами ядра: процесс, поток, файл, ключ реестра, секция памяти, токен, событие и так далее.

    Процесс и поток

  • Процесс в Windows — контейнер ресурсов: виртуальная память, таблица дескрипторов, токен безопасности, параметры окружения.
  • Поток — единица выполнения: регистры, стек, планирование CPU. Потоки живут внутри процесса.
  • Практический вывод для атак и защиты:

  • Многие действия выполняются в контексте процесса (например, права на открытие чужого процесса).
  • Многие техники исполнения кода опираются на создание или модификацию потока (например, создание удалённого потока), но ключевой барьер почти всегда — права доступа.
  • !Как процесс объединяет потоки, дескрипторы, память и токен

    Дескриптор (handle) как “пропуск” к объекту

    Handle — это значение, через которое процесс обращается к объекту. Важно, что handle существует в таблице дескрипторов конкретного процесса.

    Каждый handle связан с:

  • объектом (например, чужой процесс);
  • маской доступа (какие операции разрешены: читать, писать, завершать, создавать поток и так далее).
  • Практический вывод:

  • Атака редко “магическая”: обычно она сводится к тому, что вы смогли получить handle к объекту с нужной маской доступа.
  • Если handle получен с малой маской доступа, техника “не сработает” даже при наличии кода.
  • Справка по модели процессов и потоков:

  • Processes and Threads (Microsoft Learn)
  • Security model Windows: кто вы, что вы можете, и как Windows это решает

    Ключевой вопрос Windows Security Model: когда код пытается открыть объект, ОС должна решить разрешить или запретить.

    Субъект, объект и проверка доступа

  • Субъект — тот, кто просит доступ (обычно поток/процесс с определённым токеном).
  • Объект — то, к чему просят доступ (файл, процесс, сервис, ключ реестра и так далее).
  • Проверка доступа — сравнение желаемых прав с тем, что разрешено политиками и ACL.
  • !Упрощённая логика Access Check в Windows

    Справка по общей модели:

  • Security Model (Microsoft Learn)
  • SID: идентичности пользователей и групп

    SID (Security Identifier) — уникальный идентификатор субъекта: пользователя, группы, компьютера. Windows опирается на SID, а не на “имя”.

    Практический вывод:

  • Разрешения в ACL почти всегда привязаны к SID.
  • Переименование пользователя не “сбрасывает” его права: права привязаны к SID.
  • Справка:

  • Security Identifiers (Microsoft Learn)
  • Security Descriptor, DACL и SACL

    У объекта есть Security Descriptor — структура, где лежит политика доступа.

  • Owner — владелец объекта (часто может менять DACL).
  • DACL (Discretionary ACL) — кто и что может делать. Это основной механизм “Allow/Deny”.
  • SACL (System ACL) — что логировать (аудит). Это не про разрешение, а про журналирование.
  • Практический вывод:

  • Большая часть “конфиг-уязвимостей” в Windows — это ошибки DACL на сервисах, задачах планировщика, папках, ключах реестра.
  • Справка:

  • Security Descriptors (Microsoft Learn)
  • Access Control Lists (Microsoft Learn)
  • Токен доступа: главная сущность для Red Team

    Access Token — это “паспорт” безопасности, который Windows использует при проверке доступа.

    В токене обычно есть:

  • SID пользователя;
  • SID групп;
  • список привилегий (privileges);
  • уровень целостности (Integrity Level);
  • тип токена (primary/impersonation);
  • идентификатор сеанса входа.
  • Справка:

  • Access Tokens (Microsoft Learn)
  • !Из чего состоит токен доступа

    Primary token и impersonation token

  • Primary token привязан к процессу и определяет, “кем является” процесс.
  • Impersonation token позволяет потоку временно действовать от имени другого субъекта при обращении к объектам.
  • Зачем это Red Team:

  • Многие примитивы повышения привилегий и lateral movement упираются в способность получить или “примерить” другой токен.
  • Некоторые классы атак строятся на том, что сервис (высокие привилегии) умеет импёрсонировать клиента, а дальше появляется окно для злоупотребления.
  • Справка:

  • Impersonation (Microsoft Learn)
  • Привилегии: не то же самое, что “быть админом”

    Privileges — это специальные разрешения в токене, которые дают право выполнять системные операции.

    Примеры (концептуально):

  • привилегии для отладки и доступа к памяти других процессов;
  • привилегии для управления службами и драйверами;
  • привилегии для резервного копирования, которые обходят часть проверок на файлы.
  • Важная мысль:

  • “Администратор” — это в первую очередь членство в группах и политика UAC.
  • Привилегии — отдельный слой. Иногда субъект не “локальный админ”, но имеет опасную привилегию, и это меняет модель угроз.
  • Справка:

  • Privileges (Microsoft Learn)
  • Integrity Levels и UAC

    Integrity Level (IL) — механизм обязательного контроля целостности (MIC): условно “насколько доверенный” процесс.

    Типичные уровни:

  • Low (например, сильно ограниченные процессы)
  • Medium (обычно стандартные приложения пользователя)
  • High (повышенные права администратора)
  • System (системные службы)
  • UAC часто приводит к тому, что пользователь из группы администраторов запускает обычные программы с неповышенным токеном (не High), пока не выполнит повышение.

    Зачем это Red Team:

  • “Я в группе Administrators” не означает, что текущий процесс уже обладает тем же уровнем доступа.
  • Разница Medium vs High влияет на то, что можно открыть, изменить и куда записать.
  • Справка:

  • Mandatory Integrity Control (Microsoft Learn)
  • Где в системе живут “самые важные” секреты и почему

    Для начинающего Red Team важно понимать не “какую команду вводить”, а какой процесс/компонент является центром доверия.

    LSASS и LSA

    LSASS (Local Security Authority Subsystem Service) — процесс, в котором работают компоненты аутентификации и политики безопасности.

    Почему это важно:

  • Он участвует в проверке учётных данных и управляет контекстом входа.
  • Доступ к памяти LSASS часто критичен: он становится целью пост-эксплуатации, а защитные механизмы (например, PPL) усложняют доступ.
  • Справка:

  • LSASS (Wikipedia)
  • SAM и реестр

    SAM (Security Account Manager) хранит локальные учётные записи и связанные данные. На практике это тесно связано с реестром и системными файлами.

    Почему это важно:

  • Ошибки прав доступа к чувствительным веткам/файлам могут приводить к утечкам.
  • В доменной среде локальные учётки часто становятся “ступенькой” при неправильной политике.
  • Справка:

  • Security Account Manager (Wikipedia)
  • SCM и службы

    SCM (Service Control Manager) управляет службами. Службы часто работают с высокими правами и запускают бинарники с диска.

    Почему это важно:

  • Неправильные DACL на службе или на пути к её бинарнику — типичный путь к повышению привилегий.
  • Справка:

  • Service Control Manager (Microsoft Learn)
  • Примитивы атак: как мыслить “по-взрослому”

    Ниже — безопасная рамка: не “инструкция по взлому”, а карта примитивов, которые вы будете встречать в инструментах и отчётах.

    Примитив “получить handle с нужными правами”

    Многие техники сводятся к одному:

  • открыть объект (процесс/токен/сервис/файл) с правами, достаточными для целевого действия;
  • выполнить действие через API.
  • Что проверять в голове:

  • какой объект нужен;
  • какая маска доступа требуется;
  • что мешает (DACL, IL, отсутствие привилегии, PPL, EDR policy).
  • Примитив “украсть или создать полезный токен”

    Частые сценарии:

  • найти процесс с более сильным токеном и получить доступ к его токену;
  • использовать импёрсонирование там, где сервис доверяет клиенту;
  • найти токен с нужной привилегией (или где она может быть включена).
  • Ключевая идея:

  • токен — это ваш рычаг для доступа к объектам, а не абстрактная “роль”.
  • Примитив “выполнить код в другом контексте”

    На концептуальном уровне это:

  • заставить код исполняться в другом процессе;
  • или запустить новый процесс с другим токеном;
  • или выполнить действие через доверенный системный компонент.
  • Связь с прошлой статьёй:

  • exploitation-часть объясняла, как получается контроль выполнения на уровне памяти;
  • Windows Internals добавляет слой: даже имея контроль выполнения в процессе, вы можете быть ограничены токеном и проверками доступа.
  • Примитив “конфигурационная ошибка как уязвимость”

    В Windows огромное количество “уязвимостей” в реальных сетях — это не баги памяти, а ошибки доступа:

  • пользователю разрешили менять конфиг сервиса;
  • группе разрешили записывать в каталог с исполняемым файлом службы;
  • неверно выставили права на задачу планировщика;
  • дали право управлять чувствительными объектами.
  • Это напрямую завязано на:

  • DACL объектов;
  • членство в группах;
  • текущий IL и UAC.
  • Инструменты для изучения внутренностей Windows (легально и полезно)

    Чтобы закреплять материал, используйте инструменты, которые показывают те же сущности, о которых мы говорили.

  • Sysinternals Process Explorer: просмотр процессов, токенов, привилегий и открытых handle.
  • Sysinternals AccessChk: проверка эффективных прав доступа к объектам.
  • Ссылки:

  • Process Explorer (Microsoft Learn)
  • AccessChk (Microsoft Learn)
  • Как практиковаться в лаборатории безопасно

    Фокус практики на этом этапе: не “сделать эксплойт”, а научиться объяснять ограничения и возможности.

    Подход:

  • Поднимите Windows VM (лучше Pro/Enterprise), создайте обычного пользователя и пользователя-админа.
  • Сравните токены процессов, запущенных “обычно” и “с повышением”.
  • Выберите 2–3 объекта (файл, ключ реестра, служба) и разберите:
  • - кто владелец; - какая DACL; - какой токен у процесса, который просит доступ; - почему доступ есть или почему его нет.

    Что читать по теме (из списка курса)

    Эта статья опирается на главы и идеи из:

  • Windows Internals, Part 1 (Microsoft Press)
  • А официальные ссылки выше полезны как точные определения терминов и структур.

    Итог

    Если свести Windows Internals I к нескольким “опорным” мыслям:

  • Windows — это мир объектов, а handle с маской доступа часто важнее “самого факта, что объект существует”.
  • Security model строится вокруг токена (SID, группы, привилегии, IL) и Security Descriptor (DACL/SACL).
  • Большинство практических примитивов Red Team в Windows — это вариации:
  • - получить нужный handle, - получить более сильный токен, - использовать слабую DACL или доверие в импёрсонировании, - выполнить код в нужном контексте.

    Дальше по курсу эта база станет фундаментом для Active Directory атак (Kerberos, delegation, ACL в AD) и для Linux/Windows exploitation и reversing, где понимание токенов, прав и контекста выполнения критично для реального результата.

    3. Active Directory Red Team: Kerberos, delegation, ACL и типовые цепочки компрометации

    Active Directory Red Team: Kerberos, delegation, ACL и типовые цепочки компрометации

    Зачем это нужно в Red Team

    В прошлой статье про Windows Internals мы разобрали, что практическая сила атак в Windows почти всегда сводится к двум вопросам:

  • Кто вы в текущем контексте? Это описывает токен: SID, группы, привилегии, Integrity Level.
  • К чему вы реально имеете доступ? Это определяют security descriptors и ACL у объектов.
  • Active Directory добавляет к этой модели распределённый слой:

  • идентичности и группы становятся доменными и живут в каталоге;
  • аутентификация опирается на Kerberos и доменные ключи;
  • права на изменение объектов AD задаются ACL, и это часто важнее, чем “локальный админ”.
  • Цель статьи: собрать в одну понятную картину Kerberos, delegation и ACL в AD так, чтобы вы могли разбирать реальные цепочки компрометации как набор примитивов: какой объект, какое право, какой билет, какая проверка доступа.

    > Всё ниже применяйте только в лаборатории, CTF и в рамках письменного разрешения на тестирование.

    Минимальная модель AD: что именно мы атакуем

    Active Directory Domain Services это каталожная база данных и набор протоколов, обеспечивающих централизованные учётные записи и политики.

    Ключевые сущности:

  • Домен: административная граница с общими политиками и базой объектов.
  • Контроллер домена (DC): сервер, который хранит копию базы AD и выполняет роль KDC для Kerberos.
  • Объекты каталога: пользователи, компьютеры, группы, OU, GPO и сервисные объекты.
  • Атрибуты объектов: поля вроде member, servicePrincipalName, msDS-AllowedToActOnBehalfOfOtherIdentity.
  • Справка:

  • Active Directory Domain Services overview
  • Почему AD-компрометация часто выглядит как “граф прав”

    В Windows мы думали “получить handle с нужной маской доступа”. В AD аналогично, только объектами становятся записи каталога, а доступ определяется ACL на них.

    Практический вывод:

  • доменная эскалация очень часто делается не через memory exploitation, а через ошибки делегирования прав и ошибки ACL;
  • даже имея обычного пользователя, вы можете иметь право изменить критичный объект, если DACL настроен нестрого.
  • !Визуализация идеи, что AD-атаки часто сводятся к поиску пути по правам (ACL)

    Kerberos в AD: билеты как механизм доверия

    Kerberos в домене это основной протокол аутентификации, где доступ к сервису подтверждается билетами.

    Термины, без которых дальше будет непонятно

  • KDC: компонент на DC, который выдаёт билеты.
  • TGT: билет “на вход” в Kerberos, подтверждает, что пользователь уже аутентифицирован.
  • TGS (service ticket): билет на конкретный сервис.
  • SPN: идентификатор сервиса в AD, к которому выпускается сервисный билет.
  • PAC: данные в билете, в которых отражаются группы и часть авторизационного контекста в домене.
  • Справка:

  • Kerberos authentication technical reference
  • Базовый поток Kerberos: что происходит в реальности

    Упрощённая логика выглядит так:

  • Клиент доказывает KDC свою личность и получает TGT.
  • С TGT клиент запрашивает у KDC TGS для конкретного сервиса (по SPN).
  • Клиент предъявляет TGS сервису, и сервис принимает решение, пускать или нет.
  • !Наглядный цикл получения TGT и TGS и обращения к сервису

    Где Kerberos связывается с Windows токенами

    Kerberos сам по себе выдаёт билеты, но приложения и ОС работают с токеном доступа.

    Логическая связка:

  • билет Kerberos подтверждает, кто вы и какие у вас доменные группы;
  • Windows создаёт логон-сессию и формирует токен, который уже участвует в access check к локальным объектам.
  • Именно поэтому в AD-атаках важно одновременно понимать:

  • протокол Kerberos и его артефакты;
  • Windows security model: SID, группы, привилегии и проверки доступа.
  • Delegation: когда сервису разрешают “быть вами”

    Delegation в AD появляется из реальной бизнес-потребности: фронтенд-сервис принимает пользователя и должен сходить от его имени в бэкенд.

    С точки зрения Red Team delegation это класс конфигураций, где сервисная учётка или компьютер получает право делать запросы от имени пользователя в пределах определённых ограничений.

    Справка:

  • Kerberos constrained delegation overview
  • Виды delegation и чем они отличаются

  • Unconstrained delegation
  • - сервису разрешают делегировать пользователя “куда угодно”. - риск: если такой хост или сервисная учётка скомпрометированы, атакующий получает сильный примитив для дальнейшего продвижения.

  • Constrained delegation
  • - сервису разрешают делегировать только к конкретным сервисам (ограничение по SPN). - риск: ошибка в выборе разрешённых сервисов или компрометация учётки всё равно может дать путь к критичным целям.

  • Resource-based constrained delegation (RBCD)
  • - право делегирования задаётся на стороне целевого ресурса: целевой компьютер или сервис хранит список, кому разрешено действовать “от имени пользователей”. - риск: если у вас есть право менять соответствующий атрибут у целевого объекта, вы можете создать очень опасную связку доверия.

    !Интуитивная разница между unconstrained, constrained и RBCD

    Как мыслить про delegation как про примитив

    Полезная модель для анализа:

  • Кто является делегирующим субъектом? Обычно сервисная учётка или компьютер.
  • Кому можно делегировать? Никому, конкретным SPN, или “по факту записи на целевом ресурсе”.
  • Что даёт компрометация делегирующего субъекта? Возможность обращаться к разрешённым сервисам в контексте пользователей.
  • Для Red Team важно не запоминать названия, а уметь отвечать на вопрос:

  • какая настройка делегирования в организации превращается в “переходник” между вашим текущим доступом и целевым ресурсом?
  • ACL в Active Directory: главный двигатель доменных эскалаций

    В AD практически каждый объект защищён security descriptor, у которого есть DACL и SACL, как и у объектов Windows.

  • DACL определяет, кому что разрешено.
  • SACL определяет, что аудировать.
  • Справка:

  • Security descriptors
  • Access control lists
  • Почему AD ACL сложнее “файловых прав”

    Причины:

  • много типов объектов и много типов операций;
  • есть наследование прав в OU;
  • есть “расширенные права” на отдельные атрибуты;
  • группы могут быть вложенными, и итоговые эффективные права неочевидны.
  • Практический вывод:

  • AD-компрометация часто начинается с поиска того, где у вашего субъекта есть неожиданно сильные права на чужие объекты.
  • Типовые опасные права и какие примитивы они дают

    Таблица ниже описывает не “эксплойт”, а логику: какое право в DACL превращается в какой класс возможностей.

    | Право (пример) | Что означает в модели доступа | Какой примитив для Red Team | Типичный результат при ошибочной выдаче | |---|---|---|---| | GenericAll | полный контроль над объектом | можно менять ключевые атрибуты и права | полный захват объекта, включая выдачу себе прав | | WriteDACL | право менять DACL объекта | можно легально “дописать” себе разрешения | устойчивое закрепление и эскалация | | WriteOwner | право менять владельца | владелец часто может менять DACL | обход исходных ограничений через смену owner | | GenericWrite | право писать часть свойств объекта | зависит от конкретных атрибутов | от слабых изменений до критичных, если затронуты чувствительные атрибуты | | AddMember на группу | право добавлять участников | расширение своих групп | быстрый переход к административным правам при ошибочной группе | | Право на сброс пароля | возможность сменить пароль цели | захват учётки без знания старого пароля | компрометация пользователя или сервисной учётки |

    Важно: в AD один и тот же “GenericWrite” может быть безопасным или критичным в зависимости от того, какие атрибуты реально доступны для изменения.

    Объекты AD, которые чаще всего становятся “поворотными точками”

  • Группы: особенно те, что ведут к административным возможностям.
  • Сервисные учётки и компьютеры: из-за SPN, delegation и их роли в инфраструктуре.
  • OU: потому что права могут наследоваться на десятки и сотни объектов.
  • GPO: потому что изменение политики может менять конфигурацию и поведение множества машин.
  • Типовые цепочки компрометации: как собирать из примитивов

    Ниже приведены распространённые шаблоны цепочек. Они описаны намеренно на уровне логики и проверок, чтобы вы учились строить модель угроз, а не заучивать “команды”.

    Цепочка: слабые права в AD ACL → управление группой → доменная эскалация

    Логика:

  • Есть обычный доменный пользователь с некоторыми группами.
  • У этого субъекта есть неожиданные права на важный объект, например на группу или OU.
  • Через эти права субъект получает членство или права, которые ведут к административным возможностям.
  • Что проверять в голове:

  • какой конкретно объект является “ступенькой”;
  • какое именно право в DACL даёт возможность изменить состав группы или DACL;
  • является ли изменение устойчивым и заметным (аудит, SACL, процессы согласования).
  • Цепочка: Kerberos как источник артефактов → офлайн-атаки на секреты

    Kerberos порождает артефакты, которые иногда можно использовать для офлайн-проверок стойкости секретов.

    Мышление Red Team здесь такое:

  • какие учётки в домене выступают как сервисные? Обычно у них есть SPN.
  • что будет, если их секрет слабый? Слабый секрет может быть проверяемым офлайн по данным, связанным с Kerberos.
  • что даст захват сервисной учётки? Часто это доступ к критичным сервисам, а иногда и шаг к delegation или администрированию.
  • Важно отделять:

  • факт наличия протокольного механизма;
  • практическую реализуемость, которая зависит от политики паролей, типа учётки, мониторинга и сегментации.
  • Цепочка: delegation → доступ к чувствительным сервисам от имени пользователей

    Логика:

  • В инфраструктуре есть сервисы с настроенным delegation.
  • Скомпрометирован сервис или хост, который может делегировать.
  • Делегирование позволяет обращаться к выбранным сервисам в контексте пользователей.
  • Что важно понимать:

  • delegation это не “магия”; это формализованное доверие, и ваша задача как атакующего или аудитора понять границы доверия;
  • constrained и RBCD часто выглядят “безопаснее”, но ошибка в том, кому и к чему разрешили делегировать, делает их критичными.
  • Цепочка: GPO и OU → влияние на множество машин

    Логика:

  • У субъекта есть право изменять GPO или привязку GPO к OU.
  • Изменение политики влияет на множество компьютеров и пользователей.
  • Мышление:

  • GPO это “мультипликатор”: одно право может затронуть десятки хостов;
  • поэтому права на управление GPO и OU должны быть особенно ограничены и тщательно аудированы.
  • Справка:

  • Group Policy overview
  • Как практиковаться в лаборатории без вредных “рецептов”

    Фокус лаборатории на этом этапе: научиться объяснять, почему цепочка возможна.

    Рекомендуемый формат стенда:

  • Один DC.
  • Один сервер-участник домена.
  • Одна рабочая станция.
  • Несколько тестовых учёток: обычная, сервисная, админ.
  • Что именно тренировать:

  • Читать объектную модель AD.
  • Объяснять Kerberos-поток и где появляются TGT и TGS.
  • Находить и интерпретировать ACL на объектах AD.
  • Строить граф: учётка → право → объект → новый доступ.
  • Что читать по теме (из списка курса и официальных источников)

    Из списка курса основной фундамент здесь даёт книга Red Teaming Active Directory, а для точных определений полезнее всего официальные спецификации и документация.

    Официальные источники:

  • Kerberos authentication technical reference
  • Kerberos constrained delegation overview
  • Security descriptors
  • Access control lists
  • Итог

    AD для Red Team это объединение трёх слоёв:

  • Kerberos как фабрика билетов и доменного доверия.
  • Delegation как формализованная возможность сервисов действовать от имени пользователей.
  • ACL в AD как главный источник “неожиданно сильных” прав, из которых собираются реальные цепочки компрометации.
  • Если вы после этой статьи умеете словами разложить сценарий в формате субъект → право/билет → объект → результат, то у вас есть правильная основа для следующего уровня: разбор конкретных AD-цепочек в реальных средах, анализ следов и переход к инструментальному мышлению (графы, инвентаризация прав, моделирование путей).

    4. Linux/Unix Internals: процессы, syscalls, память и основы exploitation на Linux

    Linux/Unix Internals: процессы, syscalls, память и основы exploitation на Linux

    Зачем это нужно в Red Team

    В первых статьях курса мы построили фундаментальное мышление:

  • В exploitation-модуле вы научились смотреть на сбой как на модель памяти и доверия к данным.
  • В Windows Internals вы перенесли это на уровень ОС: объекты, права, контекст выполнения.
  • В AD-части добавился распределённый слой идентичностей, ACL и доверий.
  • Linux/Unix слой нужен, чтобы вы так же уверенно объясняли:

  • какой контекст безопасности у процесса (UID/GID, capabilities, namespaces),
  • как именно программа разговаривает с ядром (syscalls),
  • как устроена память процесса на Linux (ELF, mmap, страницы, ASLR, NX),
  • почему краш происходит именно так и что это означает для анализа уязвимостей.
  • Цель статьи: дать практическую внутреннюю картину Linux/Unix, на которой позже строятся темы Linux privilege escalation, контейнеры, post-exploitation и reversing.

    > Всё ниже используйте только в лаборатории, CTF и на авторизованных тестах.

    Модель Unix: процессы, идентичности и права

    Unix-подобные системы (Linux, *BSD, macOS) традиционно строятся вокруг простой идеи:

  • есть процессы,
  • процессы имеют идентичность (пользователь и группы),
  • доступ к объектам (файлам, сокетам, устройствам) определяется правами и политиками.
  • Процесс как контейнер выполнения

    Процесс в Linux включает:

  • виртуальное адресное пространство (память),
  • таблицу файловых дескрипторов,
  • контекст безопасности (UID/GID, capabilities, SELinux/AppArmor при наличии),
  • один или несколько потоков выполнения.
  • UID/GID и эффективные права

    В Linux важно различать реальные и эффективные идентичности.

  • ruid и rgid описывают, кто запустил процесс.
  • euid и egid описывают, какие права реально используются при проверках доступа.
  • Это критично для Red Team, потому что многие реальные эскалации (особенно локальные) упираются не в “есть ли root”, а в то, в какой момент процесс получает эффективные права.

    Справка:

  • getuid(2) — Linux manual page
  • setuid(2) — Linux manual page
  • Setuid/setgid как механизм доверия

    Файлы могут иметь биты setuid и setgid: при запуске такой программы её euid или egid становится равным владельцу файла.

    Практический смысл:

  • это легитимный способ “дать пользователю выполнить ограниченную операцию с повышенными правами”,
  • но это также высокорисковая зона: баги памяти и баги логики внутри setuid-программ обычно намного опаснее.
  • Справка:

  • chmod(1) — Linux manual page
  • credentials(7) — Linux manual page
  • Linux capabilities: “root, но по частям”

    Capabilities дробят “всемогущество root” на отдельные привилегии (например, право менять сетевые настройки или трассировать процессы).

    Модель мышления:

  • вместо вопроса “root или не root” вы задаёте вопрос “какие конкретно привилегии у процесса”.
  • Справка:

  • capabilities(7) — Linux manual page
  • Syscalls: граница между пользовательским кодом и ядром

    В Linux почти все “настоящие” действия ОС делаются через системные вызовы:

  • открыть файл,
  • создать процесс,
  • выделить память,
  • отправить данные по сети,
  • изменить права.
  • Почему syscalls важны для exploitation

    Exploitation-мышление из первой статьи применимо напрямую:

  • пользовательский код работает с памятью и может ошибаться,
  • но результат часто выражается через syscalls (например, чтение данных, запись файла, запуск процесса),
  • а наблюдаемость и следы (логи, аудит) часто видны именно на уровне syscalls.
  • !Граница user space/kernel space и роль syscalls

    libc и “настоящий” syscall

    Часто вы вызываете не syscall напрямую, а функцию стандартной библиотеки (glibc), которая внутри делает syscall.

    Пример: open() в коде пользователя обычно превращается в один из современных syscall-вариантов вроде openat.

    Справка:

  • syscalls(2) — Linux manual page
  • open(2) — Linux manual page
  • Наблюдение syscalls через strace

    strace полезен для ответа на вопрос: что программа реально делает в системе.

    Пример безопасной диагностики:

    Что вы обычно ищете:

  • какие файлы открываются,
  • какие ошибки возвращает ядро (например, EACCES, ENOENT),
  • какие дочерние процессы запускаются,
  • какие сетевые подключения происходят.
  • Справка:

  • strace(1) — Linux manual page
  • Процессы и потоки: fork/exec, copy-on-write и наблюдаемость

    Linux-процессы традиционно создаются связкой fork() и execve().

    fork: “почти копия” процесса

    fork() создаёт дочерний процесс, который стартует как копия родителя.

    Ключевой механизм эффективности: copy-on-write.

  • Память не копируется сразу.
  • Страницы разделяются до первой записи.
  • При записи создаётся копия страницы.
  • Справка:

  • fork(2) — Linux manual page
  • execve: “замена” программы

    execve() не создаёт новый процесс. Он заменяет образ процесса: загружает новый ELF, настраивает память, подхватывает аргументы и окружение.

    Справка:

  • execve(2) — Linux manual page
  • Потоки: это тоже процессы (почти)

    В Linux потоки реализованы через clone(). Важная практическая мысль:

  • многие “потоковые” сущности видны как отдельные задачи в ядре,
  • диагностика и безопасность часто оперируют именно этим уровнем.
  • Справка:

  • clone(2) — Linux manual page
  • /proc: интерфейс к внутренностям процесса

    /proc позволяет наблюдать:

  • командную строку процесса,
  • текущие открытые файловые дескрипторы,
  • карту памяти,
  • статус и идентичности.
  • На практике особенно полезны:

  • /proc/<pid>/status (UID/GID, контекст),
  • /proc/<pid>/fd/ (какие файлы и сокеты открыты),
  • /proc/<pid>/maps (карта памяти),
  • /proc/<pid>/exe (какой бинарник запущен).
  • Справка:

  • proc(5) — Linux manual page
  • Память процесса на Linux: страницы, mmap и карта адресов

    Exploitation всегда упирается в память, поэтому Linux-часть должна собрать в голове “карту” того, что вы видите в отладчике и в /proc/<pid>/maps.

    Страницы памяти и права

    Виртуальная память разбита на страницы. Для каждой области памяти ядро хранит права:

  • r чтение,
  • w запись,
  • x исполнение.
  • Это напрямую связано с защитой NX: данные не должны быть исполняемыми.

    Справка:

  • mmap(2) — Linux manual page
  • mprotect(2) — Linux manual page
  • Где берётся память: brk и mmap

    Исторически куча росла через brk, а для больших/особых аллокаций используется mmap.

    Практический вывод для анализа уязвимостей:

  • адреса “кучи” и “mmap-областей” могут выглядеть по-разному,
  • многие аллокаторы используют mmap для крупных блоков,
  • карта памяти процесса объясняет, почему один и тот же баг может быть стабильным или нестабильным.
  • Справка:

  • brk(2) — Linux manual page
  • /proc/<pid>/maps: что вы там увидите

    В maps вы увидите строки вида “адреса, права, смещение, файл”. Это помогает понять:

  • где лежит основной бинарник,
  • где подключены библиотеки,
  • где стек,
  • где heap,
  • где анонимные mmap.
  • !Типичная карта виртуальной памяти процесса Linux по данным /proc/<pid>/maps

    ELF и динамический линкер: как запускается бинарник

    Большинство Linux-бинарников имеют формат ELF. Для Red Team это важно по двум причинам:

  • вы понимаете, откуда берутся адреса кода и библиотек,
  • вы понимаете, какие защиты включены на уровне сборки и линковки.
  • Справка:

  • elf(5) — Linux manual page
  • ld.so(8) — Linux manual page
  • PIE и ASLR: почему адреса “плавают”

    Две связанные идеи:

  • ASLR рандомизирует размещение областей памяти.
  • PIE делает так, что даже основной исполняемый модуль можно загрузить по случайному адресу.
  • Модель мышления exploitation-разработчика здесь такая:

  • без утечек адресов (или других примитивов) предсказуемость расположения кода снижается,
  • многие техники превращаются в задачу сначала получить информацию, а уже потом воздействовать.
  • Справка:

  • randomize_va_space — Linux kernel documentation
  • Базовые защиты на Linux и что они означают для анализа багов

    Ниже не “как обойти”, а как интерпретировать среду, когда вы расследуете уязвимость.

    NX (DEP)

    Если область памяти без x, то даже контролируемые данные не исполнятся как код.

    Следствие для анализа:

  • чаще появляется фокус на перепрыгивание по уже существующему коду (внутри бинарника и библиотек) и на утечки.
  • Stack canary

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

    Следствие:

  • “прямые” стековые переполнения часто превращаются в простой аварийный выход,
  • но всё равно полезны как сигнал ошибки границ.
  • RELRO

    RELRO усложняет некоторые классы перезаписи структур динамической линковки.

    Следствие:

  • при анализе бинарника важно понимать, какие области будут read-only после инициализации.
  • Справка по проверке параметров сборки:

  • readelf(1) — Linux manual page
  • Отладка и диагностика: как превращать краш в модель

    Здесь вы применяете цикл из первой статьи курса (воспроизведение → симптом → локализация → минимизация → вывод), но с Linux-инструментами.

    gdb и core dumps

    gdb нужен, чтобы видеть:

  • где произошло падение,
  • какие регистры и стек в момент падения,
  • какая инструкция выполнялась,
  • какие данные попали в память.
  • Core dump фиксирует память процесса на момент падения, что полезно для повторяемого анализа.

    Справка:

  • GDB documentation
  • core(5) — Linux manual page
  • Пример рабочего потока (в лаборатории):

    Санитайзеры: быстрый способ ловить классы ошибок

    AddressSanitizer помогает поймать:

  • выход за границы,
  • use-after-free,
  • double free.
  • Это полезно именно для обучения мышлению: вы быстрее связываете “симптом” и “класс ошибки”.

    Справка:

  • AddressSanitizer — Clang documentation
  • Минимальный учебный пример ошибки границ

    Пример нужен не для “эксплуатации”, а чтобы увидеть, как crash проявляется и как его читать.

    Что вы тренируете:

  • находить источник неконтролируемого копирования,
  • проверять размер буфера,
  • видеть, что “рядом” в стеке может быть повреждено.
  • Справка:

  • strcpy(3) — Linux manual page
  • Syscalls как поверхность атаки и как источник следов

    В реальной работе Red Team важно помнить двустороннюю природу syscalls:

  • для атакующего это “кнопки”, через которые достигается эффект,
  • для защитника и расследования это места, где остаются наблюдаемые следы.
  • Примеры того, что вы можете объяснять после этой статьи:

  • почему попытка чтения чужой памяти упирается в права и в ограничения ядра,
  • почему один и тот же бинарник по-разному ведёт себя при разных настройках ASLR,
  • почему контейнеризация меняет “границы” процесса и что это значит для привилегий.
  • Seccomp и sandboxing: когда процессу запрещают syscalls

    Seccomp позволяет ограничить, какие syscalls может делать процесс.

    Модель:

  • если процесс изначально запущен в “песочнице”, то даже при получении контроля выполнения вы можете быть ограничены тем, что ядро просто не даст вызвать нужные syscalls.
  • Справка:

  • seccomp(2) — Linux manual page
  • prctl(2) — Linux manual page
  • Namespaces: почему “root в контейнере” не всегда root

    Namespaces изолируют части системы (процессы, сеть, файловые точки монтирования и так далее). Это основа контейнеров.

    Практическое мышление:

  • контекст “root” может быть ограничен пространством имён,
  • а значит важен вопрос: в какой именно изоляции находится процесс.
  • Справка:

  • namespaces(7) — Linux manual page
  • Как связать это с предыдущими модулями курса

    Эта статья намеренно соединяет три линии курса в одну:

  • Из exploitation-части вы берёте модель памяти, классы ошибок и дисциплину отладки.
  • Из Windows Internals вы берёте привычку мыслить контекстом безопасности и проверками доступа.
  • Из AD-части вы берёте идею “графа прав и доверий”, которая на Linux проявляется через UID/GID, группы, capabilities, namespaces и политики.
  • Дальше по курсу на этой базе проще:

  • разбирать Linux LPE не как набор трюков, а как комбинацию контекста, поверхности syscalls, ошибок конфигурации и ошибок памяти,
  • читать отчёты и код эксплойтов осмысленно: понимать, какие части про память, а какие про ограничения ядра.
  • Что читать по теме (из списка курса)

    База по теме на уровне системного понимания:

  • The Linux Programming Interface (No Starch Press)
  • Полезные первоисточники определений:

  • Linux manual pages (man7.org)
  • Итог

    Если свести Linux/Unix internals к нескольким опорам для Red Team:

  • Процесс это память, файловые дескрипторы, контекст безопасности и потоки.
  • Syscalls это граница с ядром: источник возможностей и одновременно источник следов.
  • Карта памяти (/proc/<pid>/maps) и механика mmap объясняют поведение багов памяти.
  • ELF, динамический линкер и флаги сборки определяют многие практические ограничения exploitation.
  • Защиты (ASLR, NX, canary, RELRO) меняют не “возможность атаковать”, а первый вопрос, который вы задаёте: “какой примитив здесь реалистичен?”.
  • 5. Shellcoding и эксплуатация уязвимостей: техники, payloads и reliability

    Shellcoding и эксплуатация уязвимостей: техники, payloads и reliability

    Зачем это нужно в Red Team

    В предыдущих частях курса мы построили основу:

  • В exploitation-модуле вы научились мыслить памятью, границами и контролем потока.
  • В Windows Internals разобрали, что результат атаки упирается в токен, привилегии и проверки доступа.
  • В AD-части увидели, что многие «победы» — это не баги памяти, а граф прав.
  • В Linux Internals закрепили, что реальный эффект в системе выражается через syscalls, а поведение зависит от ASLR/NX/PIE.
  • Эта статья соединяет всё это в практическую рамку: что такое payload, почему «контроль RIP/EIP» ещё не означает «готовый результат», какие бывают техники доставки кода/действий, и как думать про reliability (повторяемость) в эксплуатации.

    > Материал предназначен для легальных лабораторий, CTF и авторизованных тестов. Цель — научиться анализировать и проектировать надёжные цепочки, а не выдавать пошаговые рецепты против реальных систем.

    Термины: что именно мы называем shellcode и payload

    Важно не путать слова.

  • Payload — то, что вы хотите выполнить или получить как результат: от безобидного маркера «я тут был» в лаборатории до управления процессом.
  • Shellcode — исторически это компактный машинный код, который выполняется в скомпрометированном процессе. Сегодня payload часто не «чистый shellcode», а комбинация техник.
  • Stager — маленькая первая стадия, которая готовит почву и подтягивает следующую (например, больший модуль).
  • Stage — следующая стадия, обычно более функциональная.
  • Exploit chain — цепочка от входа (уязвимость) до результата (payload), включая обход защит.
  • Ключевая мысль для Red Team: payload — это часть цепочки. Самое сложное в реальной среде часто не «выполнить код», а сделать это повторяемо в условиях защит и ограничений контекста.

    !Диаграмма показывает, что payload — поздний этап и зависит от примитивов и защит

    Модель «примитивов»: как превращать баг в управляемое действие

    Из первой статьи курса вы уже знаете, что баги памяти бывают разными. Для проектирования payload важнее формализовать не «класс бага», а какой примитив вы получили.

    Типовые примитивы

  • Контроль потока: вы влияете на то, куда перейдёт выполнение (например, через адрес возврата или указатель функции).
  • Запись в память: вы можете записать контролируемые данные в контролируемое место (полностью или частично).
  • Чтение памяти (утечка): вы можете прочитать адреса/содержимое, чтобы стабилизировать обход ASLR и понять окружение.
  • Логический примитив: вы не ломаете память, но добиваетесь опасного действия из-за ошибки логики или прав.
  • Практический вывод: выбор техники payload определяется тем, какой примитив у вас есть и какие ограничения накладывает среда.

    Ограничения payload: почему «маленький код» до сих пор актуален

    Современная эксплуатация редко выглядит как «прыжок на стек и выполнение большого кода». Часто вам мешают ограничения.

    Ограничение по размеру

    Иногда место для полезной нагрузки очень маленькое (десятки байт) или данные проходят через преобразования.

    «Плохие байты» и преобразования

    Некоторые каналы ввода ломают определённые байты:

  • строковые функции обрывают ввод на \0;
  • фильтры выкидывают \n, \r, кавычки;
  • протокол/парсер может декодировать или нормализовать данные.
  • Это приводит к инженерному требованию: payload должен быть либо байт-совместимым, либо иметь декодер, либо уходить в «не-shellcode» техники (например, reuse существующего кода).

    Ограничения на права памяти (NX/DEP)

    Если область памяти не исполняема, то даже полностью контролируемые байты не выполнятся как инструкции.

  • Для Linux важны mmap(2) и mprotect(2) как базовые механизмы прав страниц: mmap(2), mprotect(2).
  • Для Windows полезно знать модель DEP: Data Execution Prevention.
  • Рандомизация адресов (ASLR/PIE)

    Даже если у вас есть контроль потока, «куда прыгать» может быть непредсказуемо без утечки адресов.

  • Для Linux: randomize_va_space.
  • Для Windows: Address Space Layout Randomization.
  • Техники выполнения: от «инъекции кода» к «reuse кода»

    Техники удобно классифицировать по тому, исполняете ли вы свои инструкции или переиспользуете уже существующие.

    Исполнение своих инструкций

    Это ближе к классическому shellcode, но требует, чтобы где-то была исполняемая память.

    Типичные подходы на уровне идей:

  • разместить код в уже исполняемой области (редко возможно в современных сборках);
  • добиться смены прав страницы на исполняемые (зависит от среды и политик);
  • использовать JIT-подобные сценарии в рамках разрешённого поведения приложения (это уже ближе к логическим уязвимостям, но модель та же: есть «примитив»).
  • Reuse: ret2libc, ROP и «цепочки гаджетов»

    Когда NX запрещает выполнение данных, эксплуатация часто переходит в reuse:

  • ret2libc: идея в том, чтобы вызвать уже существующую функцию в библиотеке/модуле.
  • ROP: идея в том, чтобы собрать цепочку коротких фрагментов кода, заканчивающихся возвратом, и тем самым выполнить последовательность действий.
  • Важно для мышления:

  • Вам почти всегда нужны адреса (или способ сделать их предсказуемыми) — это связывает reuse с утечками и ASLR.
  • Вам нужны корректные соглашения вызова и состояние стека/регистров — это связывает reuse с темой ABI и отладки.
  • На Windows дополнительные ограничения могут накладывать механизмы вроде CFG: Control Flow Guard.
  • Payload-дизайн: stager против «монолита»

    В Red Team полезно мыслить payload как продукт инженерных компромиссов.

    Stageless payload

    Одна «большая» полезная нагрузка.

    Плюсы:

  • меньше зависимостей от сети и среды;
  • проще модель отказов.
  • Минусы:

  • размер может не поместиться;
  • сложнее сделать байт-совместимой для плохих символов;
  • выше риск детектирования по статическим признакам.
  • Staged payload

    Первая стадия маленькая, затем подтягивается функциональность.

    Плюсы:

  • маленькая первая стадия легче проходит ограничения;
  • основная логика может быть гибкой и модульной.
  • Минусы:

  • появляются сетевые/временные зависимости;
  • больше точек, где можно «сломаться» (и больше следов).
  • Ключевой вывод: staged подход обычно повышает проходимость ограничений, но часто снижает операционную надёжность и увеличивает наблюдаемость.

    Reliability: как делать эксплуатацию повторяемой

    Надёжность — это не «эксплойт работает у меня». Надёжность — это вероятность успеха при повторении в тех же условиях.

    Что влияет на надёжность

    Таблица — удобный чеклист для проектирования.

    | Фактор | Как проявляется | Что делать в мышлении Red Team | |---|---|---| | ASLR/PIE | адреса меняются между запусками | искать утечки и делать этап «инфо → действие» | | NX/DEP | данные не исполняются | выбирать reuse или легитимные пути исполнения | | Различия версий | смещения структур и кода отличаются | привязка к версии, детект окружения, отказоустойчивость | | Тайминги и гонки | «иногда получается» | минимизировать конкуренцию, стабилизировать воспроизведение | | Ограничения ввода | плохие байты, длина, кодировка | проектировать кодирование/декодирование или менять технику | | Привилегии контекста | процесс не имеет прав на нужное действие | связывать payload с Windows токеном или Linux UID/capabilities |

    Метрика надёжности в лаборатории

    Полезно мыслить вероятностно, но без усложнений. Если вы запускаете тест раз и успехов , то эмпирическая оценка успеха — .

  • — число повторов при одинаковых вводах и окружении.
  • — число успешных завершений цепочки до ожидаемого результата.
  • Смысл метрики: сравнивать изменения. Например, «добавили проверку окружения» или «заменили технику на reuse» и посмотрели, стало ли стабильнее.

    Типовые причины «флапа» (нестабильности)

  • Неправильные предположения о макете памяти (особенно на куче).
  • Неучтённые проверки и исключения, которые меняют поток выполнения.
  • Упирание в контекст прав: payload пытается сделать действие, запрещённое текущему пользователю.
  • Различия между debug/release и включёнными защитами компилятора.
  • Контекст выполнения: связь payload с Windows и Linux security model

    Один из самых частых провалов начинающих: думать, что payload «сам по себе даёт права». На практике он наследует права процесса.

    Windows: токен определяет границы

    Если payload выполняется в процессе с Medium IL и без нужных привилегий, то действия могут быть невозможны даже при полном контроле кода.

    Что проверять:

  • какой Integrity Level у процесса;
  • какие privileges есть в токене и включены ли они;
  • есть ли ограничения вроде PPL для чувствительных процессов.
  • Ссылка для контекста токенов: Access Tokens.

    Linux: UID/GID и capabilities важнее «ощущений»

    В Linux payload почти всегда упрётся в эффективные учётные данные процесса.

    Что проверять:

  • euid/egid процесса;
  • наличие опасных capabilities;
  • наличие sandbox (seccomp), который может запрещать критичные syscalls.
  • Ссылки: credentials(7), capabilities(7), seccomp(2).

    Payload как «набор системных действий»: syscalls и API

    В Linux реальный эффект почти всегда выражается через syscalls, даже если вы их не вызываете напрямую.

  • Базовый источник истины о запуске процессов: execve(2).
  • Диагностика поведения через системные вызовы: strace(1).
  • В Windows аналогом являются WinAPI и системные вызовы, но для мышления достаточно помнить:

  • payload вызывает операции ОС через API;
  • успех зависит от токена и проверок доступа;
  • на современных системах дополнительные политики могут блокировать даже корректные вызовы.
  • Наблюдаемость и следы: payload всегда оставляет артефакты

    Для сильного Red Team важно думать как человек, который потом сам же должен объяснить результат.

    Типовые места, где появляются следы:

  • системные журналы (в Windows и Linux по-разному);
  • создание процессов и сетевые соединения;
  • доступы к файлам и конфигурации;
  • нетипичные падения процессов и core dumps (в Linux): core(5).
  • Это напрямую связывает данную тему с будущими модулями про форензику и «мышление по следам».

    Как безопасно практиковаться в лаборатории

    Цель практики по этой статье — не «написать боевой payload», а научиться принимать инженерные решения и повышать repeatability.

    Рекомендуемый формат:

  • Возьмите учебный уязвимый бинарник из своего репозитория (как в предыдущих статьях) и добейтесь стабильного краша.
  • Сформулируйте примитив: контроль потока, запись, утечка.
  • Опишите ограничения окружения: ASLR, NX, canary, права процесса.
  • Спроектируйте нейтральный payload для лаборатории: например, корректное завершение процесса, вывод маркера в лог приложения или запись в заранее разрешённый временный файл.
  • Измерьте надёжность повторениями и сравните 2 варианта цепочки.
  • Что читать по теме (из списка курса и первоисточников)

    Книга из списка курса, которая лучше всего ложится на тему техники и мышления вокруг payload:

  • The Shellcoder’s Handbook (Wiley)
  • Первоисточники, которые полезно держать под рукой:

  • mmap(2)
  • mprotect(2)
  • execve(2)
  • seccomp(2)
  • Access Tokens
  • Data Execution Prevention
  • Address Space Layout Randomization
  • Control Flow Guard
  • Итог

    Shellcoding и payloads в современном exploitation — это не «набор байтов», а инженерная часть exploit chain.

  • Начинайте с формализации примитива: контроль потока, запись, утечка или логический рычаг.
  • Всегда учитывайте ограничения среды: ASLR, NX/DEP, входные фильтры, политики.
  • Выбирайте технику исполнения: свои инструкции или reuse существующего кода.
  • Проектируйте payload под контекст прав: Windows токен или Linux учётные данные и capabilities.
  • Измеряйте reliability повторениями и улучшайте цепочку как систему.
  • На следующем уровне (reversing и продвинутый exploitation) вы будете делать это точнее: анализировать бинарники, искать стабильные примитивы, понимать компоновку модулей и строить цепочки, которые выдерживают реальные условия.

    6. Reverse Engineering: чтение бинарников, анализ, паттерны и практика

    Reverse Engineering: чтение бинарников, анализ, паттерны и практика

    Зачем reverse engineering нужен в Red Team

    Reverse engineering (RE) в сильном Red Team нужен не как «умение разбирать любой malware», а как универсальный навык понимать то, что у вас нет в исходниках:

  • Вы находите, что именно делает бинарник (а не что «должен делать» по документации).
  • Вы связываете наблюдаемое поведение с внутренними примитивами ОС: Windows токены/ACL, Linux UID/capabilities, syscalls.
  • Вы быстрее превращаете краш, странное поведение или подозрительную сетевую активность в модель причин.
  • Связь с предыдущими модулями курса:

  • Из статьи про exploitation вы приносите привычку формализовать примитив (чтение, запись, контроль потока) и искать, где он появляется.
  • Из Windows Internals вы приносите мышление объектами, handle и токенами: в RE это превращается в анализ вызовов WinAPI и проверок доступа.
  • Из Linux Internals вы приносите syscalls, /proc, strace: в RE это превращается в понимание «что реально делает процесс в системе».
  • Из темы про payload и reliability вы приносите дисциплину: гипотеза → проверка → повторяемость.
  • > Все практики ниже предназначены для лаборатории, CTF и авторизованных тестов. Не анализируйте и не модифицируйте ПО без права на это.

    Что такое reverse engineering на практике

    RE обычно делят на два режима, и в реальной работе они почти всегда смешиваются.

  • Статический анализ: вы изучаете файл без запуска (структура, секции, строки, импорты, дизассемблирование, декомпиляция).
  • Динамический анализ: вы запускаете и наблюдаете (отладчик, трассировка, точки останова, логирование, системные вызовы, API).
  • Цели RE в Red Team чаще всего такие:

  • Понять архитектуру и поверхность: входы, парсеры, протоколы, плагины, конфиги.
  • Найти места, где решается безопасность: аутентификация, авторизация, проверки прав, валидация данных.
  • Найти причины краша или нестабильности: где данные становятся некорректными.
  • Подготовить качественное описание риска: что можно сделать, с какими условиями и ограничениями.
  • !Общая схема рабочего процесса RE: от первого взгляда на файл до подтверждённых выводов

    Форматы и «контейнеры»: что вы вообще анализируете

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

    ELF на Linux

    ELF обычно описывает:

  • сегменты, которые маппятся в память при запуске;
  • секции для линкера и анализа;
  • таблицы символов (если не удалены);
  • зависимости от динамических библиотек.
  • Полезные первоисточники:

  • elf(5) — Linux manual page
  • readelf(1) — Linux manual page
  • objdump(1) — Linux manual page
  • PE на Windows

    PE (Portable Executable) описывает:

  • секции (код, данные, ресурсы);
  • таблицы импортов и экспортов;
  • entry point;
  • метаданные, важные для загрузчика.
  • Надёжный первоисточник:

  • PE format — Microsoft Learn
  • Практическая мысль: формат помогает ответить на вопросы «как файл будет загружен», «откуда берутся зависимости», «какие есть подсказки по функциям и модулям».

    Триаж: быстрый старт без погружения в тысячи функций

    Сильный RE начинается с того, что вы не открываете дизассемблер первым шагом.

    Быстрый триаж должен дать вам:

  • архитектуру и разрядность (x86, x64, ARM);
  • тип (исполняемый файл, библиотека, драйвер, скриптовая обёртка);
  • зависимости (какие библиотеки нужны, какие API используются);
  • наличие символов/отладочной информации;
  • признаки упаковки/обфускации.
  • На Linux типовой минимум инструментов:

  • file, readelf, objdump, strings, ldd.
  • На Windows в логике триажа вы часто смотрите:

  • какие DLL импортируются;
  • какие функции импортируются;
  • есть ли ресурсы (например, конфиги, строки, embedded-объекты).
  • Важно: на этапе триажа вы уже строите первичную гипотезу о назначении бинарника, и дальше проверяете её.

    Дизассемблирование и декомпиляция: что вы реально видите

    RE-инструменты показывают вам две разные проекции.

  • Дизассемблер показывает инструкции CPU и переходы.
  • Декомпилятор пытается восстановить псевдо-C, но может ошибаться в типах и логике.
  • Практическая дисциплина:

  • Декомпилятор ускоряет понимание, но истина всегда в инструкциях и фактах выполнения.
  • Ошибка типов в декомпиляторе часто ломает выводы про проверки длины, знаковость и границы.
  • Минимальная анатомия функции

    Почти в любом бинарнике вы будете снова и снова видеть одни и те же идеи:

  • вход в функцию и настройка стека;
  • работа с аргументами;
  • ветвления и вызовы;
  • выход из функции.
  • Это напрямую связано с первой статьёй курса про стек и соглашения вызова: без понимания стека вы не сможете уверенно отличать «локальный буфер» от «указателя на структуру».

    !Как одна и та же функция выглядит в дизассемблере и в декомпиляторе

    Статический анализ: как извлекать смысл без запуска

    Статика даёт вам карту: где входы, где критичные решения, какие протоколы и зависимости.

    Строки, ресурсы и конфиги

    Строки часто раскрывают:

  • имена файлов и путей;
  • URL и домены;
  • сообщения об ошибках, которые привязаны к веткам кода;
  • формат логов;
  • названия команд, опций, режимов.
  • Но важно помнить:

  • строк может не быть (обфускация, шифрование, упаковка);
  • строки могут быть ложными или тестовыми.
  • Импорты как «сигнатура поведения»

    Импортируемые функции помогают понять класс задач.

  • На Windows вызовы в стиле OpenProcess, AdjustTokenPrivileges, CreateService почти всегда подсказывают связь с токенами/SCM.
  • На Linux связка функций вокруг файлов, сокетов и процессов обычно сводится к syscalls через libc.
  • В терминах курса: импорты часто подсвечивают какие объекты ОС будут задействованы и какие проверки доступа станут критичными.

    Управляющий граф и точки принятия решений

    В RE часто полезно искать не «все функции», а узлы принятия решений:

  • проверки прав;
  • проверки роли/группы;
  • сравнение токена/UID;
  • ветки обработки ошибок.
  • Практический приём мышления:

  • найдите место, где приложение отвечает «можно/нельзя»;
  • разберите, какие данные участвуют в решении;
  • проверьте, откуда эти данные приходят и можно ли их подменить в вашей модели угроз.
  • Динамический анализ: как подтверждать гипотезы

    Динамика нужна, когда статика не даёт уверенности: сложные структуры, шифрование, JIT, антианализ, поведение зависит от среды.

    Наблюдаемость на Linux: syscalls как правда

    Для Linux самый практичный уровень наблюдения в начале — системные вызовы.

  • strace отвечает на вопрос: что процесс реально делает в системе.
  • Это напрямую продолжает Linux Internals часть курса про syscalls и следы.
  • Первоисточник:

  • strace(1) — Linux manual page
  • Отладчик: контроль эксперимента

    Отладчик полезен, когда вы хотите:

  • остановиться на конкретной ветке;
  • посмотреть аргументы функции и состояние памяти;
  • понять, почему ветвление пошло «не туда»;
  • локализовать источник краша.
  • На Linux базовый инструмент:

  • GDB documentation
  • На Windows в качестве базового официального источника по отладке:

  • WinDbg documentation — Microsoft Learn
  • Практическая дисциплина динамики:

  • вы запускаете только то, что понимаете на уровне гипотезы;
  • вы фиксируете окружение (версии, настройки, аргументы);
  • вы воспроизводите поведение повторяемо.
  • Паттерны, которые ускоряют понимание кода

    Ниже — набор «узнаваемых форм», которые часто встречаются в бинарниках. Цель не в том, чтобы заучить, а в том, чтобы быстрее строить гипотезы.

    Парсеры и границы данных

    Почти любой серьёзный риск начинается с парсера.

    Типовые признаки парсера в коде:

  • циклы, которые идут по байтам или токенам;
  • ветвления по типу поля или маркеру;
  • вычисление длины и смещений;
  • проверки целостности (CRC, magic bytes).
  • Как связать с exploitation-мышлением:

  • спросите себя, где есть границы и кто их контролирует;
  • проверьте, что происходит при неожиданных длинах и при ошибках.
  • Аутентификация и хранение секретов

    Признаки того, что код связан с учётными данными:

  • функции сравнения строк и хешей;
  • работа с хранилищем (реестр, файлы, keychain-подобные компоненты);
  • вызовы криптографических библиотек.
  • Практическая цель RE в Red Team здесь часто такая:

  • понять, что именно считается секретом, где он живёт и как проверяется;
  • оценить, какие ошибки в логике или конфигурации могут разрушить модель доверия.
  • Проверки прав и ролей

    На Windows типично встречается логика вокруг токена и групп.

  • вы видите проверки членства в группах;
  • вы видите ветки «admin-mode»;
  • вы видите попытки включить привилегии.
  • Это напрямую связывается с модулем Windows Internals: не «магия», а конкретные проверки доступа и контекст выполнения.

    Сетевое поведение и протоколы

    Узнаваемые признаки:

  • парсинг заголовков и команд;
  • таблицы строк команд;
  • сериализация структур;
  • частые вызовы send/recv-подобной логики.
  • Практический вывод:

  • для RE важно выделить границы сообщений, состояния протокола и места, где данные становятся «доверенными».
  • Обработка ошибок как источник истины

    Ошибки часто более честны, чем «счастливый путь»:

  • сообщения об ошибках привязаны к конкретным веткам;
  • коды ошибок помогают восстановить ожидаемый формат данных;
  • fallback-логика иногда открывает неожиданные обходные пути.
  • Обфускация, упаковка и антианализ: как не потерять время

    В реальной практике вы часто столкнётесь с тем, что бинарник трудно анализировать.

    Признаки того, что нужен другой план:

  • очень мало строк и импортов, при этом файл большой;
  • странный entry point, много переходов, «шумные» функции;
  • код «распаковывает» что-то в память перед реальной работой.
  • Практическое правило для Red Team:

  • сначала цельтесь в поведение (динамика, трассировка), и только потом углубляйтесь в статическую реконструкцию.
  • Практика: как построить лабораторную работу по RE без хаоса

    Чтобы RE давал прирост, а не превращался в бесконечное «тыкание в дизассемблер», используйте структуру.

    Выберите цель анализа

    Хорошие цели для учебной практики:

  • понять, как программа парсит вход и где принимает решение «валидно/невалидно»;
  • найти, где происходит проверка прав или режима;
  • локализовать причину краша и доказать её на уровне памяти и ветки кода.
  • Плохая цель для обучения:

  • «разобрать весь бинарник целиком».
  • Ведите артефакты анализа

    RE ценен, когда остаётся воспроизводимый результат:

  • карта ключевых функций и модулей;
  • заметки по входам и форматам;
  • список гипотез и чем они подтверждены;
  • минимальный сценарий воспроизведения интересного поведения.
  • Стандартный цикл RE

    Надёжный цикл, который хорошо сочетается с логикой всего курса:

  • Сформулировать гипотезу (на основе триажа и статических признаков).
  • Проверить гипотезу динамически (наблюдение, отладка, трассы).
  • Уточнить модель (какие данные, какие проверки, какие ограничения среды).
  • Зафиксировать выводы (функции, условия, доказательства).
  • Инструменты, которые стоит освоить

    Ниже — базовый набор, который покрывает большую часть учебных задач.

    Кроссплатформенные

  • Ghidra как бесплатная среда для дизассемблирования и декомпиляции.
  • radare2 и его документация-книга для анализа и автоматизации: radare2 book
  • Linux

  • readelf, objdump, strings как быстрый триаж.
  • GDB documentation для отладки.
  • strace(1) — Linux manual page для наблюдения syscalls.
  • Windows

  • WinDbg documentation — Microsoft Learn для анализа поведения и падений.
  • PE format — Microsoft Learn как основа понимания структуры файла.
  • Что читать по теме (из списка курса)

    Эта статья лучше всего ложится на книгу из списка курса:

  • Practical Reverse Engineering как системная база по чтению ассемблера, структурам и подходу к анализу.
  • А как справочники к реальным определениям и форматам полезнее всего первоисточники из ссылок выше: man pages для ELF-инструментов и документация Microsoft по PE.

    Итог

    Reverse engineering в Red Team — это дисциплина построения доказуемой модели поведения бинарника.

  • Начинайте с триажа: формат, архитектура, зависимости, признаки упаковки.
  • Статика даёт карту (строки, импорты, граф решений), динамика подтверждает правду (отладчик, трассы).
  • Ищите паттерны: парсеры, проверки прав, обработка ошибок, сетевые состояния.
  • Всегда связывайте выводы с контекстом ОС: Windows токены и ACL, Linux UID/capabilities и syscalls.
  • Если вы умеете из бинарника извлечь «вход → обработка → проверка → эффект» и подтвердить это наблюдением, вы готовы к следующему шагу курса: более глубокому реверсу, анализу уязвимостей на уровне машинного кода и инструментальному подходу к автоматизации.

    7. Продвинутая Windows/Kernel и tool mindset: LPE, форензика следов, свои утилиты

    Продвинутая Windows/Kernel и tool mindset: LPE, форензика следов, свои утилиты

    Зачем это нужно в Red Team

    Ранее в курсе мы построили базу: мышление exploitation, Windows security model (токены/ACL), AD (Kerberos/delegation/ACL), Linux internals, payload и reliability, reverse engineering. Этот модуль добавляет “взрослый” слой практики: как в Windows мыслить локальной эскалацией привилегий (LPE), почему без понимания ядра и драйверов многие сценарии не объяснить, как видеть свои следы и как развить tool mindset так, чтобы писать полезные утилиты под задачи Red Team.

    Ключевая идея статьи: сильный Red Team не “знает трюки”, а умеет превращать среду в набор проверяемых гипотез:

  • какой у меня текущий контекст безопасности и почему именно он такой;
  • какая граница доверия здесь важна (user mode ↔ kernel mode, низкая IL ↔ высокая IL, обычный пользователь ↔ SYSTEM);
  • какой примитив реально нужен для цели (право, токен, запись в чувствительный объект, управление сервисом, выполнение кода в другом контексте);
  • какие артефакты я оставлю и как это будет расследоваться.
  • > Всё ниже применяйте только в лаборатории, CTF и на авторизованных тестах.

    Ментальная модель LPE в Windows: не “эксплойт”, а цепочка проверок

    LPE в Windows почти всегда сводится к одному: вы заставляете систему принять решение доступа в вашу пользу, изменив контекст или объект доступа.

    Связь с предыдущими статьями:

  • из Windows Internals I вы уже знаете: токен + ACL + access check;
  • из exploitation и shellcoding вы знаете: “контроль выполнения” сам по себе ничего не даёт без нужных прав;
  • из RE вы знаете: нужно находить точки принятия решений и подтверждать их динамикой.
  • Полезная формулировка для LPE-анализа:

  • Цель: что именно означает “эскалация” в вашей задаче (например, SYSTEM, админ без UAC, конкретная привилегия в токене, доступ к защищённому объекту).
  • Текущее ограничение: что мешает (DACL, IL, отсутствие привилегии, PPL/LSASS-protection, политика EDR, отсутствие SeDebugPrivilege).
  • Поворотный объект: какой объект/компонент является “рычагом” (служба, задача планировщика, драйвер, named pipe, COM-сервер, реестр, папка).
  • Примитив: что вы реально умеете (только читать, только писать, управлять конфигом, получить handle, импёрсонировать, влиять на загрузку/поиск DLL).
  • !Ментальная модель LPE как попытка пройти access check через изменение токена или контролируемого объекта

    Windows Kernel в объёме, достаточном для LPE-мышления

    Эта часть не делает вас разработчиком драйверов, но даёт минимум терминов, чтобы понимать отчёты, реверс и причины “почему это вообще возможно”.

    User mode и kernel mode

    Windows разделяет выполнение на режимы:

  • User mode: код приложений с ограниченными возможностями.
  • Kernel mode: код ядра и драйверов с максимальными правами.
  • Практический вывод:

  • уязвимость в драйвере почти всегда потенциально критичнее, чем уязвимость в обычном приложении, потому что последствия могут затрагивать весь компьютер.
  • Справка:

  • User-Mode and Kernel-Mode (Microsoft Learn)
  • Что такое драйвер и почему он так часто в центре LPE

    Драйвер — компонент, который расширяет ядро: работает с устройствами, фильтрует операции файловой системы/сети, предоставляет интерфейсы в user mode.

    Практически важные слова:

  • I/O request (IRP): “запрос ввода-вывода” к драйверу.
  • IOCTL: управляющая команда, которой user mode может просить драйвер сделать действие.
  • LPE-идея здесь простая: если драйвер принимает данные из user mode и неправильно их проверяет, появляется шанс сломать границу доверия.

    Справка:

  • Windows Drivers (Microsoft Learn)
  • Объекты ядра, handles и безопасность

    Из Windows Internals I вы знаете про handles. На продвинутом уровне важно помнить:

  • многие критичные операции упираются в способность получить handle с нужной маской доступа;
  • многие LPE-сценарии — это не “магия”, а ошибка в том, кто имеет право открыть/изменить объект.
  • Официальная база по дескрипторам безопасности:

  • Security Descriptors (Microsoft Learn)
  • Access Control Lists (Microsoft Learn)
  • Почему важно знать про целостность (Integrity Level)

    Mandatory Integrity Control влияет на то, куда процесс может писать и что может “подменять”.

    Практический вывод:

  • многие “почему не работает” в лаборатории оказываются не отсутствием прав администратора как группы, а разницей Medium IL vs High IL.
  • Справка:

  • Mandatory Integrity Control (Microsoft Learn)
  • Типовые источники LPE: где искать “поворотный объект”

    Ниже — безопасная карта классов проблем. Цель — научиться классифицировать и задавать правильные вопросы.

    Ошибки конфигурации: DACL и “записываемость” там, где нельзя

    Частый реальный LPE в корпоративных средах — это не 0-day, а конфиг.

    Типовые зоны:

  • службы: права на изменение конфигурации службы или путь к бинарнику;
  • задачи планировщика: права на изменение task definition или исполняемого файла;
  • каталоги с исполняемыми файлами: возможность записи в место, откуда запускается код с высокими правами;
  • реестр: права на чувствительные ключи, влияющие на автозапуск/конфигурацию системных компонентов.
  • Инструменты для легального аудита прав:

  • AccessChk (Sysinternals)
  • Process Explorer (Sysinternals)
  • Логические ошибки и “небезопасное доверие”

    Иногда нет переполнений и нет “опасных прав” напрямую — но есть ошибка доверия.

    Примеры логики (на уровне мышления, без рецептов):

  • сервис принимает “идентичность” клиента по неаутентифицированному признаку;
  • компонент принимает путь/параметр без нормализации и проверок;
  • нарушена модель “кто может запускать что и от чьего имени”.
  • Уязвимости в драйверах: почему это отдельная вселенная

    Для Red Team важно понимать не детали эксплуатации, а признаки того, что драйвер может быть опасным:

  • у драйвера есть IOCTL-интерфейс из user mode;
  • драйвер выполняет операции с памятью/указателями, полученными из user mode;
  • драйвер позволяет делать “слишком мощные” действия без достаточной авторизации.
  • Для закрепления терминов и модели разработки драйверов:

  • Kernel-Mode Driver Framework (KMDF) (Microsoft Learn)
  • “Форензика следов” как часть offensive-навыка

    Сильный Red Team думает как расследователь: если завтра это будут разбирать, какие факты останутся? Это повышает качество операций и отчётов.

    Что такое артефакт и чем он отличается от “лога”

    Артефакт — любой наблюдаемый след: события, файлы, записи реестра, сетевые соединения, следы в памяти, метаданные, ETW-трейсы.

    Лог — лишь один тип артефакта.

    Основные источники видимости в Windows

    Крупными блоками (без привязки к конкретной атаке):

  • Windows Event Logs: Security, System, Application и журналы провайдеров.
  • Windows Security Auditing: политика аудита определяет, что попадает в Security log.
  • ETW: высокопроизводительная трассировка событий ядра и user mode.
  • Sysmon: расширенная телеметрия в Event Log при наличии Sysmon.
  • Память процесса/системы: то, что видно в дампе памяти и что анализируется форензикой.
  • Официальные точки входа:

  • Windows Event Log (Microsoft Learn)
  • Advanced security auditing FAQ (Microsoft Learn)
  • About Event Tracing (ETW) (Microsoft Learn)
  • Sysmon (Sysinternals)
  • Память и “следы” как мост к Memory Forensics

    Даже если на диске “всё чисто”, в памяти могут оставаться:

  • структуры процессов/потоков;
  • загруженные модули;
  • сетевые артефакты;
  • остатки строк/конфигов.
  • Для учебной практики анализа памяти (легально):

  • Volatility 3 (GitHub)
  • Практическая дисциплина для Red Team:

  • понимать, какие действия создают процессы/службы/задачи;
  • понимать, какие действия неизбежно трогают реестр и файловую систему;
  • уметь объяснить, какой источник телеметрии это увидит.
  • Tool mindset: как писать свои утилиты, которые реально помогают

    Инструменты — это множитель. Но “tool mindset” — не про коллекцию тулов, а про способность быстро создавать недостающий слой между задачей и фактами.

    Принцип: инструмент фиксирует факт, а не “впечатление”

    Хороший Red Team-инструмент отвечает на проверяемый вопрос:

  • какой у процесса Integrity Level;
  • какие privileges в токене и включены ли они;
  • какие handles открыты к целевому объекту;
  • какие ACL реально применяются.
  • И он делает это повторяемо: одинаковый ввод → одинаковый вывод.

    Минимальные требования к утилите в реальной работе

    Список специально короткий и практический:

  • предсказуемый вывод: JSON/CSV или строгий текстовый формат;
  • явная модель ошибок: различать “нет прав”, “объект не существует”, “таймаут”;
  • опциональная подробность: режим кратко/подробно;
  • минимальные зависимости: меньше внешних библиотек — меньше проблем в полевых условиях;
  • тестируемость: возможность прогнать на двух версиях Windows и сравнить вывод.
  • Языки и компромиссы

    Выбор языка — инженерный компромисс:

  • C/C++: максимум контроля и доступ к WinAPI, но выше цена ошибок памяти.
  • C#: быстро писать утилиты, удобно работать с Windows API через P/Invoke и с форматами данных.
  • Python: идеален для офлайн-анализа, парсинга, автоматизации, но зависит от окружения.
  • Связь с курсом:

  • exploitation и RE помогают вам не писать “сломанный” низкоуровневый код;
  • Windows internals помогают вам корректно задавать вопросы к токенам/ACL.
  • Пример “безопасной” утилиты: вывести ключевые свойства токена процесса

    Ниже — пример, который полезен для обучения: он не делает ничего “атакующего”, но тренирует правильную работу с токенами.

    Что вы тренируете этим типом утилит:

  • корректное мышление “всё упирается в handle и access mask”;
  • чтение токена как источника истины (а не “я вроде админ”);
  • привычку строить инструменты вокруг чётких вопросов.
  • Документация API:

  • OpenProcess function (Microsoft Learn)
  • OpenProcessToken function (Microsoft Learn)
  • GetTokenInformation function (Microsoft Learn)
  • Как связывать kernel/LPE/форензику/инструменты в один рабочий цикл

    Надёжный “полевой” цикл, который стыкуется со всеми предыдущими темами курса:

  • Сформулировать цель (какой контекст нужен и зачем).
  • Снять факты инструментами (текущий токен, IL, привилегии, права на ключевые объекты).
  • Построить гипотезу LPE как “субъект → право/ошибка → объект → новый контекст”.
  • Проверить гипотезу в лаборатории с наблюдаемостью (логи, ETW/Sysmon при наличии).
  • Зафиксировать артефакты и написать объяснение: что произошло, почему это возможно, какие условия нужны.
  • Важная дисциплина: если вы не можете объяснить, какой access check был пройден и почему, значит вы пока не контролируете процесс.

    Что читать из списка курса и официальных источников

    Книги из списка курса, которые лучше всего ложатся на эту тему:

  • Windows Kernel Programming (Pavel Yosifovich) — чтобы понимать драйверы, ядро и почему LPE через kernel-код качественно отличается.
  • The Art of Memory Forensics — чтобы мыслить следами в памяти и понимать, что увидит расследование.
  • Gray Hat Python — чтобы укрепить “tool mindset”: писать утилиты под задачу.
  • Официальные источники, которые стоит держать рядом:

  • Windows Drivers (Microsoft Learn)
  • Security Descriptors (Microsoft Learn)
  • Access Control Lists (Microsoft Learn)
  • Access Tokens (Microsoft Learn)
  • About Event Tracing (ETW) (Microsoft Learn)
  • Итог

    Эта статья добавляет три “взрослых” слоя к вашему Red Team фундаменту:

  • Продвинутое LPE-мышление: эскалация — это цепочка проверок доступа вокруг токена/ACL/контекста, а не “магическая команда”.
  • Kernel awareness: драйверы и граница user/kernel объясняют, почему некоторые баги и конфиги приводят к системным последствиям.
  • Tool mindset + форензика следов: хороший оператор умеет и создать инструмент под вопрос, и объяснить артефакты, которые оставит любая цепочка действий.
  • Дальше это станет практической опорой для более глубокого Windows LPE, анализа драйверов в реверсе и построения собственных “микро-инструментов” под аудит прав, контекстов и следов.