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

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

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

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

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

Категории

Все категории
Loading categories
ShellcodeFluctuation — Продвинутая техника обхода в памяти, переключающая защиту памяти шеллкода между RW/NoAccess и RX, а затем шифрующая/дешифрующая его содержимое | Kitploit
Инструменты/GitHubGitHub/mgeeky/shellcodefluctuation
Генерация полезной нагрузкиШелл-кодПост-эксплуатацияRed TeamingГенерация ШеллкодаРазработка Полезной НагрузкиСостязательная АтакаТоп в Разработка Полезной Нагрузки №16Топ в Генерация полезной нагрузки №16Топ в Шелл-код №14
1.1k163474 лет назадПроверено Kitploit
Топ в Генерация Шеллкода №16
GitHubmgeeky/shellcodefluctuation

ShellcodeFluctuation

Продвинутая техника обхода в памяти, переключающая защиту памяти шеллкода между RW/NoAccess и RX, а затем шифрующая/дешифрующая его содержимое

Репозиторий

Популярное

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

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

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

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

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

Shellcode Fluctuation PoC

PoC-реализация ещё одной техники внутрипроцессного обхода, которая циклически шифрует и расшифровывает содержимое шеллкода, заставляя его «колебаться» между правами памяти RW (или NoAccess) и RX. Когда наш шеллкод находится на страницах памяти RW или NoAccess, такие сканеры, как Moneta или pe-sieve, не смогут его отследить и выгрузить для дальнейшего анализа.

Введение

После публикации ThreadStackSpoofer я получил несколько вопросов о следующем пункте из README:

Измените защиту страниц памяти вашего Beacon на RW (с RX/RWX) и зашифруйте их содержимое перед засыпанием (это может обойти такие сканеры, как Moneta или pe-sieve)

Ранее я полагал, что сообщество уже знает, как шифровать/расшифровывать свои полезные нагрузки и менять права памяти, чтобы просто обходить сканеры памяти, ищущие аномальные исполняемые области. Вопросы показали обратное, поэтому я решил опубликовать этот «невооружённый» PoC, чтобы задокументировать ещё одну стратегию обхода и предложить сообществу пример реализации для работы.

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

Вот сравнение при колебании до RW (другой вариант — колебание до PAGE_NOACCESS — описан ниже):

  1. Beacon не зашифрован
  2. Beacon зашифрован (колеблющийся)

comparison

Эта реализация вместе с моим ThreadStackSpoofer даёт сообществу Offensive Security примеры реализаций, чтобы мы могли не отставать от предложений коммерческих C2-продуктов и быть ничуть не хуже в наших Red Team-инструментах. 💪


Как это работает?

Эта программа выполняет самоинъекцию шеллкода (примерно через классические VirtualAlloc + memcpy + CreateThread). Когда шеллкод запускается (эта реализация специально нацелена на импланты Cobalt Strike Beacon), хукается функция Windows, перехватывающая момент засыпания Beacon — kernel32!Sleep. Всякий раз, когда вызывается захученная функция MySleep, она определяет границы своего выделения памяти, меняет их защиту на RW и побайтово выполняет xor32 над всеми байтами, хранящимися там. Выждав ожидаемое количество времени, когда шеллкод вернётся к нашему обработчику MySleep, мы расшифровываем данные шеллкода и возвращаем защиту памяти обратно на RX.

Колебание до PAGE_READWRITE работает следующим образом

  1. Читаем содержимое шеллкода из файла.
  2. Хукаем kernel32!Sleep, указывая на наш callback.
  3. Внедряем и запускаем шеллкод через VirtualAlloc + memcpy + CreateThread. В отличие от того, что было в ThreadStackSpoofer, здесь мы не хукаем ничего в ntdll для запуска шеллкода, а переходим на него из собственной функции. Это позволяет избежать оставления в памяти простых IOC, указывающих на изменённую память ntdll.
  4. Как только Beacon пытается заснуть, вызывается наш callback MySleep.
  5. Выделенная память Beacon шифруется, а защита меняется на RW.
  6. Затем мы снимаем хук с оригинального kernel32!Sleep, чтобы не оставлять в памяти простой IOC, указывающий на то, что Sleep был трамплинирован (inline-хук).
  7. Вызывается оригинальный ::Sleep, чтобы дать Beacon поспать в ожидании дальнейшей коммуникации.
  8. После завершения Sleep мы расшифровываем данные шеллкода, возвращаем защиту памяти на RX и повторно хукаем kernel32!Sleep, чтобы обеспечить перехват последующих засыпаний.

Колебание до PAGE_NOACCESS работает следующим образом

  1. Читаем содержимое шеллкода из файла.
  2. Хукаем kernel32!Sleep, указывая на наш callback.
  3. Внедряем и запускаем шеллкод через VirtualAlloc + memcpy + CreateThread ...
  4. Инициализируем Vectored Exception Handler (VEH), чтобы настроить собственный обработчик, который будет перехватывать исключения Access Violation.
  5. Как только Beacon пытается заснуть, вызывается наш callback MySleep.
  6. Выделенная память Beacon шифруется, а защита меняется на PAGE_NOACCESS.
  7. Затем мы снимаем хук с оригинального kernel32!Sleep, чтобы не оставлять в памяти простой IOC, указывающий на то, что Sleep был трамплинирован (inline-хук).
  8. Вызывается оригинальный ::Sleep, чтобы дать Beacon поспать в ожидании дальнейшей коммуникации.
  9. После завершения Sleep мы повторно хукаем kernel32!Sleep, чтобы обеспечить перехват последующих засыпаний.
  10. Шеллкод затем пытается возобновить своё выполнение, что приводит к исключению Access Violation, поскольку его страницы помечены как NoAccess.
  11. Наш обработчик VEH перехватывает исключение, расшифровывает данные и возвращает защиту памяти на RX, после чего выполнение шеллкода возобновляется.

Это не новая техника

Техника не новая, и не я её придумал. Это лишь реализация, показывающая концепцию и её практическое применение, чтобы наше сообщество Offensive Security могло не отставать от предложений коммерческих C2-фреймворков.

Вообще-то, с идеей переключения защиты памяти шеллкода я познакомился пару лет назад благодаря работе Джоша Лоспинозо в его потрясающем Gargoyle.

Вот ещё немного дополнительной информации:

  • gargoyle, техника обхода сканирования памяти
  • Обход сканеров памяти с помощью Cobalt Strike и Gargoyle

Gargoyle развивает концепцию самоосознающего и самофлуктуирующего шеллкода гораздо дальше, используя ROP-последовательность с вызовом VirtualProtect. Однако, хотя техника впечатляет, её так же сложно применить к Cobalt Strike Beacon без необходимости убивать его поток и постоянно переинициализировать Beacon в памяти.

Это далеко от идеала, но поскольку мы уже действуем с позиций собственного процесса-загрузчика самоинъекции, мы можем делать с окружением, в котором работает шеллкод, всё, что захотим, и скрывать его как угодно. Эта техника (и предыдущая — ThreadStackSpoofer) показывает преимущества запуска наших шеллкодов именно таким способом.

Реализация колебания до PAGE_NOACCESS вдохновлена работой ORCA666, представленной в его https://github.com/ORCA666/0x41 инжекторе. Он показал, что:

  1. мы можем инициализировать Vectored Exception Handler (VEH),
  2. переключить страницы шеллкода в режим без доступа
  3. и затем перехватывать исключения Access Violation, которые возникнут, как только шеллкод захочет возобновить своё выполнение, после чего расшифровать его и вернуть страницам памяти права Read+Execute.

Эта реализация содержит данную идею, доступную с опцией 2 в <fluctuate>. Обязательно посмотрите и другие его проекты.


Демо

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