
Сканер стека вызовов, который идентифицирует IOCs распакованных или внедренных C2-агентов путем анализа поведения бездействующего потока, неподтвержденной памяти, затирания модулей, APC, таймеров и подмены обратного адреса.
Этот проект (в основном) сканер стека вызовов, который пытается выявить IOC, указывающие на распакованного или внедрённого C2-агента.
Все проверки основаны на наблюдении, что C2-агенты ожидают между обратными вызовами, вызывая простой потока бекон-агента, и этот инструмент направлен на анализ того, что потенциально вызвало простой потока.
Сюда входят традиционные IOC, такие как незарезервированная память (unbacked memory) или изменённые модули (stomped modules), а также попытки обнаружить различные реализации слипмасков с использованием APC или таймеров. Последнее выполняется как анализом стека вызовов, так и перебором таймеров и их точных callback-функций из пользовательского режима.
(Почти) ни один из этих IOC нельзя считать 100% истинным положительным срабатыванием; например, обнаружение изменённых модулей очень подвержено ложным срабатываниям. Тем не менее, результаты могут вызвать подозрения относительно поведения процесса.
DotNet- и 32-битные двоичные файлы игнорируются.

Приватная страница с правами r(w)x в стеке вызовов может указывать на бекон-агент, который был распакован или внедрён во время выполнения.
Многие слипмаски меняют права доступа к странице бекон-агента на неисполняемые. Это приводит к появлению подозрительной неисполняемой страницы в стеке вызовов.
Часто бекон-агенты избегают приватных страниц памяти, загружая и перезаписывая легитимный модуль с диска.
Благодаря механизму «копирование при записи» (copy on write) изменённые образы можно идентифицировать, проверив поле VirtualAttributes.SharedOriginal структуры MEMORY_WORKING_SET_EX_INFORMATION. Если какая-либо страница в стеке вызовов не является приватной и SharedOriginal == 0, это считается IOC.
Вероятно, это обнаружение наиболее подвержено ложным срабатываниям. :'(
В ряде реализаций слипмасков ставится очередь APC к Ntdll!NtContinue, один из которых инициирует выполнение Ntdll!WaitForSingleObject. Таким образом, если в стеке вызовов к блокирующей функции обнаружен Ntdll!KiUserApcDispatcher, инструмент считает это IOC.
Аналогично подозрительному использованию APC, этот инструмент также проверяет наличие ntdll!RtlpTpTimerCallback в стеке вызовов к блокирующей функции для обнаружения слипмасков на основе таймеров.
Насколько я понимаю, таймеры реализованы поверх пулов потоков. Как продемонстрировал Alon Leviev, их можно перечислить с помощью NtQueryInformationWorkerFactory с параметром WorkerFactoryBasicInformation.
Структура WORKER_FACTORY_BASIC_INFORMATION содержит FULL_TP_POOL, который, в свою очередь, ссылается на двусвязный список TimerQueue. Обход этого списка PFULL_TP_TIMER позволяет получить доступ к каждому зарегистрированному callback-у. Если какой-либо callback указывает на набор подозрительных вызовов API, например ntdll!ntcontinue, это можно считать сильным IOC.

Изначально проксирование модулей было предложено как метод обхода подозрительных стеков вызовов. Хотя обход работает, он вводит ещё один сильный IOC, так как NTAPI используется для вызова WINAPI. Это необычно, поскольку WINAPI является абстракцией над NTAPI. Таким образом, если наблюдается стек вызовов, в котором последовательность ntdll.dll->kernel32.dll->ntdll.dll заканчивается вызовом блокирующей функции, это можно считать IOC.
Большинство известных мне реализаций спуфинга адреса возврата используют технику, при которой вызываемая функция возвращается к gadget jmp [Nonvolatile-Register]. Этот проект просто перебирает каждый адрес возврата в стеках вызовов и ищет шаблоны, указывающие на возврат к jmp-gadget.

_ _ _____ ______
| | | | / ___| | ___ \
| |_| | \ `--. | |_/ /
| _ | `--. \ | ___ \
| | | | /\__/ / | |_/ /
\_| |_/ \____/ \____/
Hunt-Sleeping-Beacons | @thefLinkk
-p / --pid {PID}
--dotnet | Установите, чтобы также включить dotnet-процессы. (Подвержено ложным срабатываниям)
--commandline | Включает вывод командной строки для подозрительных процессов
-h / --help | Выводит это сообщение?