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

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

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

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

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

Категории

Все категории
Loading categories
SilentMoonwalk — PoC Реализация полностью динамического спуфера стека вызовов | Kitploit
Инструменты/GitHubGitHub/klezvirus/silentmoonwalk
ЭксплуатацияОбратная инженерияАнализ Бинарных ФайловRed TeamingРазработка Полезной Нагрузки
GitHubklezvirus/silentmoonwalk

SilentMoonwalk

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

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

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться

SilentMoonwalk

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

TL;DR

SilentMoonwalk — это PoC-реализация полностью динамического спуфера стека вызовов, реализующая технику удаления исходного вызывающего из стека вызовов с использованием ROP для десинхронизации размотки (unwinding) от потока управления.

Авторы

Данный PoC является результатом совместного исследования по теме спуфинга стека. Авторы исследования:

  • KlezVirus
  • Waldo-IRC
  • Trickster0

Хочу подчеркнуть, что эта работа была бы невозможна без работы Waldo-IRC и Trickster0, которые оба внесли вклад в ранние стадии PoC и в исследование, лежащее в его основе.

Обзор

Этот репозиторий демонстрирует PoC-реализацию для спуфинга стека вызовов при вызове произвольных Windows API.

Эта попытка была вдохновлена этой веткой в Twitter и этой веткой в Twitter, где сэнсэй namazso показал и предложил расширить подход размотки стека с помощью ROP-цепочки для десинхронизации размотки от реального потока управления и последующего восстановления исходного стека.

Данный PoC пытается сделать нечто подобное описанному выше и использует десинхронизированный стек для полного сокрытия исходного стека вызовов, а также удаления из него базового адреса EXE-файла. При возврате вызывается ROP-гаджет для восстановления исходного стека. В коде этот процесс повторяется 10 раз в цикле, каждый раз с разными фреймами, для доказательства стабильности.

Поддерживаемые режимы

В настоящее время инструмент поддерживает 2 режима, причем один из них фактически является неправильным патчем для неработающего фрейма pop RBP, который был идентифицирован и работает путем смещения текущего RSP и добавления двух фейковых фреймов в стек вызовов. Поскольку он работает с синтетическими фреймами, я называю этот режим «SYNTHETIC».

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

Windows 10 Call Stack - Cut

Режим синтетического стека вызовов

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

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

Результат синтетического спуфинга можно увидеть на изображении ниже:

Windows 10 Call Stack - Apparently Legit, non unwoundable - getchar

Рисунок 1: Windows 10 — внешне легитимный, неразматываемый стек вызовов, в котором модуль EXE был полностью удален (вызов функции без параметров getchar)

Примечание: этот режим работы отключен по умолчанию. Чтобы включить его, измените CALLSTACK_TYPE на 1

Режим десинхронизированного стека

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

Windows 10 Call Stack - Legit, unwoundable - MessageBoxExA

Рисунок 2: Windows 10 — легитимный, разматываемый стек вызовов, в котором модуль EXE был полностью удален (вызов функции с 4 параметрами MessageBoxA)

Утилита

В репозитории вы также можете найти небольшую утилиту для инспекции runtime-функций, которая может быть полезна для анализа записей runtime-функций.

root@kitploit:~
UnwindInspector.exe -h

 Unwind Inspector v0.100000

 Mandatory args:
   -m <module>: Target DLL
   -f <function>: Target Function
   -a <function-address>: Target Function Address

Пример вывода:

root@kitploit:~
UnwindInspector.exe -m kernelbase -a 0x7FFAAE12182C
[*] Using function address 0x7ffaae12182c

  Runtime Function (0x000000000000182C, 0x00000000000019ED)
  Unwind Info Address: 0x000000000026AA88
    Version: 0
    Ver + Flags: 00000000
    SizeOfProlog: 0x1f
    CountOfCodes: 0xc
    FrameRegister: 0x0
    FrameOffset: 0x0
    UnwindCodes:
    [00h] Frame: 0x741f - 0x04  - UWOP_SAVE_NONVOL     (RDI, 0x001f)
    [01h] Frame: 0x0015 - 0x00  - UWOP_PUSH_NONVOL     (RAX, 0x0015)
    [02h] Frame: 0x641f - 0x04  - UWOP_SAVE_NONVOL     (RSI, 0x001f)
    [03h] Frame: 0x0014 - 0x00  - UWOP_PUSH_NONVOL     (RAX, 0x0014)
    [04h] Frame: 0x341f - 0x04  - UWOP_SAVE_NONVOL     (RBX, 0x001f)
    [05h] Frame: 0x0012 - 0x00  - UWOP_PUSH_NONVOL     (RAX, 0x0012)
    [06h] Frame: 0xb21f - 0x02  - UWOP_ALLOC_SMALL     (R11, 0x001f)
    [07h] Frame: 0xf018 - 0x00  - UWOP_PUSH_NONVOL     (R15, 0x0018)
    [08h] Frame: 0xe016 - 0x00  - UWOP_PUSH_NONVOL     (R14, 0x0016)
    [09h] Frame: 0xd014 - 0x00  - UWOP_PUSH_NONVOL     (R13, 0x0014)
    [0ah] Frame: 0xc012 - 0x00  - UWOP_PUSH_NONVOL     (R12, 0x0012)
    [0bh] Frame: 0x5010 - 0x00  - UWOP_PUSH_NONVOL     (RBP, 0x0010)

Сборка

Чтобы собрать PoC и наблюдать поведение, аналогичное показанному на изображении, убедитесь, что:

  • Отключена GS (/GS-)
  • Отключена оптимизация кода (/Od)
  • Отключена оптимизация всей программы (удалите /GL)
  • Отключены предпочтения по размеру и скорости (удалите /Os, /Ot)
  • Включена встроенная (intrinsic) функция, если она не включена (/Oi)

Предыдущие работы

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

  • Return Address Spoofing: Оригинальная техника и идея от Namaszo. Каждый другой PoC, о котором я знаю, был построен на её основе.
  • YouMayPasser: Эта потрясающая работа от Arash является первым правильно выполненным расширением PoC Return Address Spoofing от Namaszo.
  • VulcanRaven: Спуфер стека вызовов, который выполняет спуфинг путем синтетического создания Thread Stack, зеркалирующего другой реальный стек вызовов.
  • Unwinder: Очень хорошая PoC-реализация на Rust спуфера стека вызовов, которая работает путем анализа информации о кодах размотки для замены фреймов в стеке вызовов.

Благодарности

  • Огромное спасибо waldo-irc и trickster0, которые сотрудничали со мной в этом исследовании. Я всем им обязан.
  • Вся заслуга за идею, лежащую в основе, принадлежит namaszo, которого я лично считаю гением. Он также перепроверил этот PoC перед публикацией, так что огромное спасибо ему.

Примечания

  • [ТОЛЬКО СИНТЕТИЧЕСКИЙ СТЕК]: Из-за ограничения в способе поиска гаджетов максимальное количество аргументов на данный момент — 8 (ИЗМЕНИТЬ И ДОБАВИТЬ БОЛЬШЕ ПАРАМЕТРОВ ТРИВИАЛЬНО, но мне было лень).
  • [ТОЛЬКО ДЕСИНХРОНИЗИРОВАННЫЙ СТЕК]: Из-за ограничения в том, как я настраиваю спуфер, максимальное количество поддерживаемых аргументов на данный момент — 4.
  • Тестирование было довольно ограниченным. Возможны исключения, о которых я пока не знаю.
  • Размотка, включающая 128-битные регистры, не тестировалась.
  • Вызов функций, использующих 128-битные регистры, официально не поддерживается.
Скачать инструмент