Привет, Хабр! Сегодня мы продолжим знакомить вас с инструментами, используемыми атакующими для горизонтального перемещения, а также способами детектирования их эксплуатации. В прошлом материале нами был рассмотрен достаточно известный инструмент PsExec, а сегодня мы поговорим о SMBExec и AtExec - других не слишком сложных, если говорить об исполнении атаки, но достаточно распространенных среди злоумышленников инструментах.
В этой статье мы подробно изучим принципы работы SMBExec и AtExec, проведем анализ возможных источников событий, а после чего представим возможный вариант обнаружения их использования как в теории, так и на практике.
SMBExec
SMBExec - один из скриптов набора Impacket, работа которого, также как и в PSExec, основывается на удалённом создании сервиса и его последующем запуске.
Как известно, сервис запускает тот исполняемый файл, что указан в его конфигурации, вместе с различными параметрами. При использовании SMBExec с каждой запускаемой командой создаётся новый сервис, в конфигурацию которого выставляется путь до, например, cmd.exe и параметры к нему (например, whoami).
Пример запуска SMBExec
$ python3 smbexec.py Domain/Username:password@10.150.x.16
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[!] Launching semi-interactive shell - Careful what you execute
C:\Windows\system32>ipconfig
Windows IP Configuration
Ethernet adapter Ethernet0:
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 10.150.x.16
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 10.150.x.1
C:\Windows\system32>whoami
nt authority\system
Можно выделить два фундаментальных этапа работы SMBExec:
Запрос к RPC интерфейсу svcctl, ответственному за удалённое управление сервисами;
Создание самого сервиса, который ответственен за непосредственный запуск команды.
Теперь посмотрим, как именно можно отследить его эксплуатацию.
В поисках артефактов
Составить единое и качественное правило детектирования, которое бы покрывало все случаи использования SMBExec только на основе логов создания сервиса, проблематично, так как суть атаки заключается в возможности запуска исполняемых файлов с аргументами. А это выливается в однострочные реверс-шеллы и команды. Если же строить детектирование на основе логов, содержащих запуск cmd.exe или powershell.exe, то неизбежной будет проблема "игры в крота", где начнут появляться другие возможности для запуска зловредной команды (список LOLBAS тому подтверждение).
Поэтому при детектировании SMBExec стоит учитывать не только события создания сервиса, но и события доступа к RPC (запрос Named Pipe svcctl и попытку вызова RPC), которые показывают, что сервис был запущен удалённо, а не локально. Эти события представленны ниже:
EventID 4697 - A service was installed in the system;
EventID 5145 - Detailed File Share;
EventID 5712 - A Remote Procedure Call (RPC) was attempted.
В событии создания сервиса EventID 4697 необходимо определить какой по типу сервис сейчас создаётся - "родной" для Windows или от третьей стороны. Это можно сделать, посмотрев на поле Service Type. В таблице ниже под спойлером показаны возможные значения типов сервисов:
Список значений типов сервисов
Документация Microsoft говорит о следующем:
Value |
Service Type |
Description |
0x1 |
Kernel Driver |
A Kernel device driver such as a hard disk or other low-level hardware device driver. |
0x2 |
File System Driver |
A file system driver, which is also a Kernel device driver. |
0x8 |
Recognizer Driver |
A file system driver used during startup to determine the file systems present on the system. |
0x10 |
Win32 Own Process |
A Win32 program that can be started by the Service Controller and that obeys the service control protocol. This type of Win32 service runs in a process by itself (this is the most common). |
0x20 |
Win32 Share Process |
A Win32 service that can share a process with other Win32 services. |
0x110 |
Interactive Own Process |
A service that should be run as a standalone process and can communicate with the desktop. |
0x120 |
Interactive Share Process |
A service that can share address space with other services of the same type and can communicate with the desktop. |
Определенный вид сервисов, а именно per-user сервисы (для каждого пользователя), имеют специфические типы, не отраженные в основной таблице. Например:
Per-user сервисы запускаются в контексте пользователя как часть пользовательского сеанса в фоновом режиме, когда он входит в систему.
Для создания экземпляров per-user сервисов система использует шаблоны. Если шаблон именуется, к примеру, UnistoreSvc, то к названию экземпляра будет добавляться еще и некоторое рандомное значение, например, UnistoreSvc_bd00d6ea.
У шаблонов, как и у экземпляров есть свои собственные типы:
для шаблонов - 0x50 (individual process) и 0x60 (shared process);
для экземпляров - 0xD0 (individual process) и 0xE0 (shared process).
Опираясь на вышеперечисленные типы, в контексте детекта нас будут интересовать сервисы с типом 0x10 и 0x110.
Так мы можем отделить все встроенные в Windows сервисы и смотреть только на пришедшие "извне". Теперь наша задача состоит в разделении сервисов, которые созданы как легитимным софтом, так и атакующими. Здесь как раз и возникает проблема ложных срабатываний. Чаще всего легитимный софт не использует параметры к собственным сервисам, и таким образом можно избежать части ложных срабатываний. Также их можно избежать, если применить корреляцию по полю Username между событиями использования RPC и событием создания сервиса в тот же момент.
Другой возможный вариант, когда в созданных сервисах могут быть изменены команды, что не будет зафиксировано в событии EventID 4697. Об этом свидетельствует документация Microsoft:
Выдержка из MSDN:
Note that this is the path to the file when the service is created. If the path is changed afterwards, the change is not logged. This would have to be tracked via Process Create events.
Эта возможность рождает другой метод Lateral Movement, который мы рассмотрим чуть позже.
Создание и возможное изменение сервисов отслеживается по ветке реестра HKLM\System\CurrentControlSet\Services, в которой содержится информация обо всех сервисах машины. Каждая подветка - это определённый сервис, где находится ключ ImagePath, содержащий в себе полную команду для сервиса.
Детектировать такое поведение можно как с помощью Sysmon, так и с помощью выставленного заранеe SACL и событий из журналов EventLog. Мы приведем сразу оба варианта. Пример лога от Sysmon c EventID 13 - Registry value set показан на рисунке 3:
При настройке SACL в журнале Security изменения значения ветки реестра можно отследить по событию 4657 - A registry value was modified (рисунок 4):
Таким образом у нас есть возможность детектировать не только изменения в сервисах, но и создание новых. Данные события можно также использовать как альтернативу событиям EventID 4697.
Мы разобрались с тем, как можно фиксировать создание и изменение сервисов, но только в контексте их локального создания, а что будет, если создать сервис удаленно? Рассмотрим это дальше.
Удалённое создание сервисов
Как и в случае с PsExec, чтобы отследить факт удаленного создания сервиса, нужно обратить внимание на событие с EventID 5145 (Detailed File Share).Это событие доступа к именованному каналу с именем svcctl - интерфейсу , который позволяет управлять сервисами на удаленном устройстве. Однако оно имеет свой недостаток, так как формируется только в случае подключения к Named Pipe через SMB посредством IPC$. Тогда как подключение напрямую по RPC совершенно игнорирует. Подробнее об этой проблеме можно прочесть в статье RPC и способы его мониторинга.
Данный недостаток можно исправить с помощью механизма RPC Filtering , после настройки которого появившиеся события скажут нам о подключении к менеджеру сервисов как с помощью RPC, так и с помощью SMB.
Настройка RPC Filtering
Для генерации логов нужно сделать отдельное правило для аудита svcctl интерфейса (UUID == 367abb81-9844-35f1-ad32-98f038001003), которое выглядит так:
rpc filter
add rule layer=um actiontype=permit audit=enable
add condition field=if_uuid matchtype=equal data=367abb81-9844-35f1-ad32-98f038001003
add filter
После чего необходимо сохранить и применить его с помощью команды:
netsh -f rpcauditrule.txt
Следовательно, при использовании svcctl мы можем получать логи, подобные событиям с EventID 5145 (Detailed File Share), но они будут формироваться, даже если пользователь подключился по RPC напрямую - EventID 5712 (A Remote Procedure Call (RPC) was attempted).
Теперь, когда мы определились с событиями, которые будем использовать, нам нужно собрать их воедино и построить возможное правило детектирования.
Итоги по событиям и построение правила детектирования
При построении правила детектирования эксплуатации SMBExec мы воспользуемся следующими событиями:
Событие удалённого запроса к менеджеру сервисов, доступное нам благодаря RPC Filtering (EventID 5712):
Событие создания сервиса (EventID 4697):
Поле Service File Name в стандартных ситуациях должно содержать только путь до исполняемого файла и аргументы к нему. Во время атаки поле содержит команду для cmd.exe, скрывающеюся за переменной %COMSPEC%.
Для удобства мы также попробуем фильтровать типы запуска сервисов, которые будут бесполезны атакующему при Lateral Movement.
Таблица от Microsoft, покажет нам какие типы запуска сервисов можно отбросить при поиске атаки.
Типы запуска сервисов
Value |
Service Start Type |
Description |
0 |
Boot |
A device driver started by the system loader. This value is valid only for driver services. |
1 |
System |
A device driver started by the IoInitSystem() function. This value is valid only for driver services. |
2 |
Automatic |
A service started automatically by the service control manager during system startup. |
2 |
Automatic Delayed |
A service started after all auto-start services have started, plus a delay. Delayed Auto Start services are started one at a time in a serial fashion. |
3 |
Manual |
A service started by the service control manager when a process calls the StartService function. |
4 |
Disabled |
A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED. |
И мы увидим, что единственные приемлемые для атакующего типы запуска - 2 и 3.
Перейдем к детектированию эксплуатации SMBExec.
Возможное правило детектирования
Исходя из приведённых событий, ниже представлено псевдо-правило для обнаружения использования SMBExec по созданию им сервиса и подключению к svcctl удалённо:
SELECT *
FROM EventCode=5712
WHERE ((Name, LogonId)) IN
(
SELECT (Account_Name, Logon_ID)
FROM EventCode=4697
WHERE
Service_File_Name IN ("*.exe *", "*.exe\ *", "%*% *") AND
Service_Start_Type IN (2, 3) AND
Service_Type IN ("0x10", "0x110")
)
Данное правило будет учитывать только сервисы, не встроенные в Windows с автоматическим или ручным типом запуска.
А теперь давайте рассмотрим другой инструмент для горизонтального перемещения - AtExec.
AtExec
AtExec - также один из скриптов набора Impacket, чья работа основывается на создании запланированных задач (scheduled tasks). Планировщик задач может управляться удалённо, и, конечно, посредством него существует возможность создавать запланированные задачи. Они, в свою очередь, исполняют команды, которые отображены в примере под спойлером:
Пример запуска инструмента
$ python3 atexec.py DOMAIN/username:password@10.150.x.16 whoami
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[!] This will work ONLY on Windows >= Vista
[*] Creating task \WVhfEDnX
[*] Running task \WVhfEDnX
[*] Deleting task \WVhfEDnX
[*] Attempting to read ADMIN$\Temp\WVhfEDnX.tmp
[*] Attempting to read ADMIN$\Temp\WVhfEDnX.tmp
nt authority\system
Работа инструмента AtExec выглядит следующим образом:
Запрос к RPC интерфейсу atsvc, ответственному за удалённый запуск планировщика задач;
Создание запланированной задачи с произвольным именем, которая в последствии может использоваться для запуска различных команд или исполняемых файлов.
Изучив принцип работы AtExec, проанализируем особенности детектирования данного инструмента и те сложности, которые могут при этом возникнуть.
Возможные сложности
Сложность обнаружения эксплуатации данного инструмента заключается в большом шансе ложных срабатываний, ведь инструмент использует возможности Windows, применяемые легетимным ПО. Эмпирически получилось установить определённую последовательность логов, фиксирующую создание, запуск и завершение задачи, которую выполнил злоумышленник по порядку, характерному только для атаки.
К этому мы можем добавить обращение пользователя по RPC к Named Pipe с именем atsvc, отвечающее за функционал менеджера задач. Но необязательно, поскольку детектирование в любом случае основывается на логах Scheduled tasks , а создать задачу через RPC может любое легитимное ПО.
Для детектирования мы будем использовать события журнала Applications and Services Logs -> Microsoft -> Windows -> TaskScheduler.
Теперь давайте подробнее рассмотрим логи TaskScheduler и узнаем какая информация будет полезна при построении возможного правила.
Идем по следам
Для обнаружения эксплуатации инструмента AtExec нами были выбраны наиболее информативные события, а именно:
Событие EventID 106 - Task registered:
Событие EventID 100 - Task Started:
Созданная задача сразу же запускается от имени NT AUTHORITY\SYSTEM. Но мы будем учитывать тот факт, что контекст запускаемой задачи может изменяться.
EventID 110 - Task triggered by user:
EventID 102 -Task completed:
Затем задача удаляется тем же пользователем, что и создал ее. Возможно также учесть этот лог при детектировании, но злоумышленник может просто не удалять задачу и тогда правило не сработает.
EventID 141 - Task registration deleted:
Теперь, когда мы увидели, как именно в событиях отображается эксплуатация данного инструмента, попробуем составить возможный вариант детектирования инструмента AtExec.
Возможное правило детектирования
Основываясь на событиях, приведенных выше, было составлено псевдо-правило:
SELECT *
FROM EventCode = 100
WHERE (TaskName) IN
(
SELECT TaskName
FROM EventCode = 110
WHERE User = "System"
SELECT TaskName
FROM EventCode = 102
WHERE User = "NT AUTHORITY\SYSTEM"
SELECT TaskName
FROM EventCode = 106
WHERE User != "NT AUTHORITY\SYSTEM"
)
Логика детектирования здесь следующая: если ScheduledTask создается от имени обычного пользователя, а после запускается от имени системы, и, при этом, это один и тот же ScheduledTask, то срабатывает алерт.
Заключение
В данной статье мы рассказали о таких инструментах, как SMBExec и AtExec, и наглядно представили принцип работы каждого из них в контексте методов горизонтального перемещения, используемых атакующими. Также здесь мы рассмотрели теоретические аспекты обнаружения и на практике разобрали возможные источники логов для построения детектирующего псевдо-правила. И по итогу были представлены варианты псевдо-правил для обнаружения эксплуатации как SMBExec, так и AtExec.
Надеемся, что статья оказалась вам полезной! Оставляйте ваши комментарии ниже и пишите вопросы :-)
Авторы:
- Черных Кирилл (@Ruucker), аналитик-исследователь киберугроз;
- Мавлютова Валерия (@IceFlipper), младший аналитик-исследователь киберугроз.