Уровень сложностиСредний
Время на прочтение14 мин
Количество просмотров16K
Привет, Хабр!
Многие передовые компании в области информационной безопасности в конце 2022 подвели итоги года по самым популярным техникам MITRE ATT&CK, используемым атакующими. Один из таких отчетов по обнаруженным угрозам был предоставлен RedCanary, а другой Лабораторией Касперского, согласно которым одной из наиболее популярных техник закрепления в системе является Scheduled Task(T1053.005) или, говоря русским языком, запланированная задача. На сегодняшний день существует много известных способов проведения данной техники: стандартная оснастка Task Scheduler от Microsoft, утилита schtasks, а также Poweshell командлеты, которые в свою очередь опираются на RPC-функции и др.
В данной статье хочу рассказать вам о нестандартном способе проведения техники Scheduled Task с помощью удаленного реестра (Remote Registry). После чего я представлю возможный вариант детектирования данного способа и попытаюсь раскрыть все сложности, с которыми придется столкнуться в процессе.
Предлагаю начать и сперва ознакомиться с тем, что собой представляет Scheduled Task.
Что такое Scheduled Task
Task Scheduler или Планировщик задач — служба в Windows, которая позволяет автоматизировано выполнять запланированные задачи на устройстве по заранее заданному триггеру (время, наступление определенного события и т.п.). Это одна из самых «древних» служб в Windows: впервые данный компонент появился в Windows 95, а в текущем виде он представлен в Windows Vista. Таким образом, за десятки лет активного использования Scheduled Task появилось достаточное количество способов и инструментов для работы с запланированными задачами.
Данная техника привлекает злоумышленников тем, что запланированные задачи являются легитимными в операционной системе Windows. Это позволяет замаскировать вредоносные действия, а сам функционал планировщика задач не будет отключен администраторами, так как на нем строится работа всей системы. Так, например, запланированные задачи повышают надежность системы, обеспечивая ее бесперебойную работу за счет выполнения обслуживающих задач, таких как, очистка диска, дефрагментация, проверка на ошибки. Также Scheduled Task позволяет повысить производительность системы путем выполнения задач по типу резервного копирования или обновлений в наиболее оптимальное время, которое соответствует определенному триггеру. Еще один плюс — снижение человеческого фактора и рабочей нагрузки на администраторов системы.
Теперь давайте разберемся, где и как запланированные задачи хранятся в памяти системы.
Представление запланированных задач в памяти
При планировании задачи стандартными утилитами (schtasks, оснастка Task Scheduler, командлеты Powershell) создание определенных ключей реестра и xml файла на диске можно отследить с помощью Process Monitor или Sysmon (примеры Sysmon событий будут дальше в статье).
Рассмотрим подробнее какие ключи реестра при этом задействованы:
-
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks
— содержит список подразделов, представляющих запланированную задачу. Каждая задача имеет уникальный идентификатор GUID, который выступает в качестве имени ключа в реестре; -
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree
— представляет собой структуру планировщика заданий Windows. Здесь хранятся метаданные для регистрации задачи в системе; -
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{GUID}
— содержит все настройки задачи; -
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\{Plain\Logon\Boot}\{GUID}
— ветка реестра, которая выбирается в зависимости от того, по какому триггеру будет запускаться задача:-
Plain — по заранее заданному расписанию;
-
Logon — при входе пользователя;
-
Boot — при загрузке системы.
-
На рисунке 2 и 3 представлен пример хранения параметров задачи в ключах реестра перечисленных выше.
Также при создании задачи формируется файл в формате xml с параметрами запланированной задачи по пути C:\Windows\System32\Tasks
.
Само содержимое xml-файла с параметрами задачи вы можете увидеть под спойлером.
XML с параметрами задачи
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2023-02-27T13:08:20</Date>
<Author>USER</Author>
<URI>\spawn</URI>
</RegistrationInfo>
<Triggers>
<TimeTrigger>
<StartBoundary>2023-02-27T20:10:00</StartBoundary>
<Enabled>true</Enabled>
</TimeTrigger>
</Triggers>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\windows\system32\cmd.exe</Command>
</Exec>
</Actions>
<Principals>
<Principal id="Author">
<UserId>USER</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
</Task>
Перейдем к самому интересному и посмотрим как же можно создать запланированную задачу, не используя при этом специально предназначенные для этого утилиты.
Создание задачи с помощью реестра
Для удаленного подключения к реестру можно использовать графический интерфейс regedit.exe
или из командной строки утилиту reg.exe
.
# Удаленное редактирование реестра с помощью reg.exe
REG ADD \\<REMOTE_COMPUTER>\HKLM\...
Для того чтобы изменять требуемые ветки реестра, нам необходима учетная запись SYSTEM, по крайней мере по умолчанию только она обладает нужными правами. Но удаленно подключиться под SYSTEM не получится.
Тогда возникает вопрос как удаленно из-под SYSTEM редактировать реестр, если подключиться под ней нельзя? Тут можно предложить несколько вариантов. Первый — ,заполучив SYSTEM, добавить права на редактирование другой учетной записи и уже все действия осуществлять от ее имени. Второй вариант — использовать psexec
из пакета от Sysinternals или от Impacket, также можно использовать smbexec
и подобные ей. Еще один из способов повысить привилегии до SYSTEM это использование различных «картошек» (например, RoguePotato, JuicyPotatoNG, RasmanPotato и др.). Либо прибегнуть к атаке Silver Ticket для создания TGS билета с SYSTEM в PAC, но для этого нужен NTLM-хеш учетной записи устройства.
Предположим, что тем или иным способом мы получили возможность удаленно редактировать реестр. Тогда, чтобы не испытывать сложности при создании требуемых веток в реестре и заполнении ключей, мы можем создать задачу локально, а далее перенести ее на удаленную машину.
Пример экспортированной задачи приведен ниже под спойлером.
Пример экспортированной задачи
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\remoteregistry1053]
"SD"=hex:01,00,04,80,88,00,00,00,98,00,00,00,00,00,00,00,14,00,00,00,02,00,74,\
00,04,00,00,00,00,10,18,00,9f,01,1f,00,01,02,00,00,00,00,00,05,20,00,00,00,\
20,02,00,00,00,10,14,00,9f,01,1f,00,01,01,00,00,00,00,00,05,12,00,00,00,00,\
10,18,00,ff,01,1f,00,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,00,00,00,\
24,00,89,00,12,00,01,05,00,00,00,00,00,05,15,00,00,00,fb,65,0e,da,0c,ec,58,\
4f,d2,95,df,b7,3a,38,00,00,35,00,7d,00,01,02,00,00,00,00,00,05,20,00,00,00,\
20,02,00,00,01,05,00,00,00,00,00,05,15,00,00,00,fb,65,0e,da,0c,ec,58,4f,d2,\
95,df,b7,01,02,00,00
"Id"="{B24EFFF8-2161-46E8-917D-1FF04C433EBE}"
"Index"=dword:00000003
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{B24EFFF8-2161-46E8-917D-1FF04C433EBE}]
"Path"="\\remoteregistry1053"
"Hash"=hex:9b,ea,c8,ba,7a,d1,d4,6c,6f,66,2c,07,83,ff,e9,35,2c,7c,ef,0b,cf,48,\
22,de,4d,65,02,c3,3f,dc,e0,6f
"Schema"=dword:00010002
"Date"="2022-11-04T21:33:12.6610933"
"Author"="DOMAIN\USER"
"URI"="\\remoteregistry1053"
"Triggers"=hex:17,00,00,00,00,00,00,00,01,07,0b,00,00,00,04,00,80,13,62,a9,95,\
f0,d8,01,01,e7,d4,7b,7a,01,00,00,80,d3,cb,d3,5e,f1,d8,01,38,21,41,42,48,48,\
48,48,88,f6,c6,53,48,48,48,48,0e,00,00,00,48,48,48,48,41,00,75,00,74,00,68,\
00,6f,00,72,00,00,00,48,48,00,00,00,00,48,48,48,48,00,48,48,48,48,48,48,48,\
00,48,48,48,48,48,48,48,01,00,00,00,48,48,48,48,1c,00,00,00,48,48,48,48,01,\
05,00,00,00,00,00,05,15,00,00,00,fb,65,0e,da,0c,ec,58,4f,d2,95,df,b7,3a,38,\
00,00,48,48,48,48,1e,00,00,00,48,48,48,48,53,00,45,00,41,00,5c,00,64,00,6b,\
00,6f,00,7a,00,68,00,75,00,73,00,68,00,6f,00,6b,00,00,00,48,48,2c,00,00,00,\
48,48,48,48,00,00,00,00,ff,ff,ff,ff,80,f4,03,00,ff,ff,ff,ff,07,00,00,00,00,\
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,48,48,\
48,48,dd,dd,00,00,00,00,00,00,01,07,0b,00,00,00,04,00,80,13,62,a9,95,f0,d8,\
01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
00,00,00,00,00,00,00,00,2c,01,00,00,80,51,01,00,ff,ff,ff,ff,00,00,00,00,00,\
00,00,00,00,00,00,00,00,01,4a,7c,01,00,00,00,00,00,00,00,d1,61,00,00,00,00,\
00,00,48,48,48,48
"Actions"=hex:03,00,0c,00,00,00,41,00,75,00,74,00,68,00,6f,00,72,00,66,66,00,\
00,00,00,0e,00,00,00,63,00,6d,00,64,00,2e,00,65,00,78,00,65,00,00,00,00,00,\
00,00,00,00,00,00
"DynamicInfo"=hex:03,00,00,00,59,22,57,e5,7b,f0,d8,01,00,00,00,00,00,00,00,00,\
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Plain\{B24EFFF8-2161-46E8-917D-1FF04C433EBE}]
Посмотрим на алгоритм действий при экспортировании:
-
Создать задачи с требуемыми параметрами на локальной машине;
-
Произвести экспорт следующих веток реестра:
-
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\{NAMETASK}
-
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{Id TASK}
-
`Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Plain{Id TASK}
-
-
Произвести импорт этих веток реестра на удаленную машину;
-
Далее появится созданная задача в списке задач, но при запуске будет ошибка.
Для исправления данной ошибки существует два способа:
-
Перезапустить службы
Schedule
. Таким образом задача подгрузится в память соответствующего процессаsvchost
. Для перезапуска службы требуются права SYSTEM, либо можно попросту перезагрузить ПК; -
Произвести Update задачи из графического интерфейса, schtasks или других подобных инструментов. Согласно документации Microsoft обновлять задачу могут пользователи, создавшие ее, а также члены группы администраторов и учетная запись SYSTEM.
Чтобы не создавать «лишний шум» в журнале событий, связанный с появлением новых ключей в реестре, атакующий вместо создания новой задачи может редактировать отдельные, уже существующие ключи в реестре. Он также имеет возможность осуществлять это как вручную, так и через импорт-экспорт определенных ключей, как было показано выше. В то же время такие задачи требуется активировать с новыми параметрами.
При импорте веток реестра на удаленную машину регистрируются события изменения реестра от имени процесса C:\Windows\system32\svchost.exe -k localService -p -s RemoteRegistry
. Данные события можно проследить в журнале Sysmon EventId 12 (RegistryEvent Object create or delete) и 13(RegistryEvent Value Set).
Сразу после импорта ключей реестра задача появится в графическом интерфейсе планировщика задач, но каких-либо событий по созданию задачи в журналах нет, в том числе и события 4698(A scheduled task was created). На следующем этапе данную задачу нужно активировать.
Если в качестве активации выбран Update задачи, то регистрируется событие в Sysmon с EventId 11(FileCreate). То есть происходит создание xml файла в C:\Windows\System32\Tasks
с описанием задачи от имени svchost.exe
, связанного со службой Schedule. Пример данного события представлен выше на Рисунке 4.
Также в журнале Security регистрируется событие с EventId 4702(A scheduled task was updated), свидетельствующее об обновлении задачи. Как и в событии 4698 данное событие содержит xml с описанием задачи.
При перезапуске службы Schedule
не происходит создание xml файла с описанием задачи и нет каких-либо событий, свидетельствующих о подгрузке задачи в память процесса svchost.exe
связанный со службой (т.е. отсутствуют события 4698 и 4702).
Чтобы удаленно редактировать реестр потребуется включить службу Remote Registry.
Настройка службы удаленного реестра:
Запустить Remote Registry можно с помощью учетной записи, обладающей правами локального администратора или SYSTEM.
Для этого потребуется выполнить несколько шагов:
Перейти в оснастку "Services.msc"
Открыть свойства "Remote Registry service"
Во вкладке General выбрать тип запуска Automatic
Применить изменения
Если атакующий захочет как можно дальше спрятать свои действия и тем самым еще больше усложнить жизнь специалистам по мониторингу и расследованиям инцидентов, то он сможет это сделать за счет «трюка», позволяющего скрыть запланированную задачу.
В чем же заключается этот трюк мы разберем дальше.
Скрытие задачи в планировщике задач
На этот раз скрытие происходит из оснастки Task Scheduler и других утилит (schtasks, Powershell Get-ScheduledTask) по работе с запланированными задачами. Трюк заключается в том, чтобы удалить определенные ключи в реестре, связанные с задачей.
Давайте посмотрим, что это за ключи и попробуем объединить два метода: создание задачи с помощью реестра (как описано в предыдущем разделе) и скрытие за счет отсутствие определенных ключей. Таким образом, задача будет создана уже без требуемых ключей. В таком случае для активации задачи не представляется возможным использовать Update, а единственным возможным из мне известных вариантов является перезапуск службы Schedule
(если вы знаете альтернативные методы, то пишите о них в комментариях к статье). Если же производить манипуляцию с ключами, перечисленными ниже у уже активированной задачи, то дополнительно перезапускать службы или что-то обновлять не требуется. Тогда задача мгновенно пропадает из рассматриваемых утилит после изменений в реестре.
Первый ключ в реестре, который позволяет скрыть задачу, называется Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\{NAMETASK}\SD
. SD отвечает за дескриптор безопасности. Если создать задачу без этого ключа, то она не будет отображаться в планировщике задач.
Второй ключ, который можно попробовать не указывать при создании задачи, является Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\{NAMETASK}\Index
. Однако в текущей ситуации в оснастке Task Scheduler перестают отображаться вообще какие-либо задачи, а при открытии планировщика появляется ошибка «An internal server error occurred», при этом сами задачи работают по-прежнему.
Также можно попробовать не удалять полностью ключ Index
, а изменить его. Таким образом, значение данного поля зависит от того по какому триггеру будет выполняться задача и, соответственно, она связана с веткой HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\{Plain\Logon\Boot}\{GUID}
(при Boot Index
=0x1, при Logon Index
=0x2, при Plain Index
=0x3). Если Index
установить равным 0x0, то задача будет скрыта в планировщике, но при этом ее работа не нарушится. Установка Index
равным 0x4 и более, не повлияет на скрытие задачи.
Вишенкой на торте является то, что если совершить Update задачу (schtasks /change /TN TASKNAME /TR PROGRAM
), производя манипуляции с ключом Index
, то она удалится без какого-либо события в журнале Security, в том числе и не будет события 4699 (A scheduled task was deleted).
Изучив особенности проведения техники Scheduled Task с помощью Remote Registry, перейдем к возможным способам ее детектирования.
Детектирование
Выше было рассказано как можно создать запланированную задачу максимально скрытым способом, а теперь мы поговорим, как защитникам детектировать данные случаи. Думаю очевидно, что стандартным способом за счет событий, связанных с задачами (4698, 4699, 4702), детектировать не получиться, так как они попросту будут отсутствовать в журнале.
Первое на что хотелось бы обратить внимание, так это на то, что везде происходило редактирование реестра. При стандартных способах создания запланированных задач по требуемым веткам вносятся изменения от имени C:\\Windows\\system32\\svchost.exe -k netsvcs -p -s Schedule
(т.е. службой Schedule
). В нашем же случае все изменения происходили от имени C:\Windows\system32\svchost.exe -k localService -p -s RemoteRegistry
. В случае использования psexec и подобных, родительским процессом будет используемая утилита по редактированию реестра, например, ею может выступать reg.exe
. То, что редактирование определенных веток реестра происходит с помощью процесса отличающегося от службы Schedule
, может как раз и служить одним из маркеров. При этом определить какая именно служба производит изменения в реестре возможно с помощью события Sysmon 1 (Process Creation). Сопоставлять 1, 12 и 13 события можно по полю ProcessGuid (если родительским процессом выступает утилита) или ParentProcessGuid (если родительским процессом выступает служба). Ниже, на основе этого анализа, мною будет представлено-псевдо правило для детекта.
Таким образом, псевдо-правило для детекта выглядит так:
SELECT *
FROM (EventCode=1)
WHERE (ParentProcessGuid OR ProcessGuid) IN
(
SELECT ProcessGuid
FROM (EventCode=12 OR EventCode=13)
WHERE TargetObject="HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\TaskCache\\Tree\\*"
)
AND ParentCommandLine!="C:\\Windows\\system32\\svchost.exe -k netsvcs -p -s Schedule"
Также следует отметить, что при активации задачи с помощью Update
формируется событие 4702. Данное событие содержит описание задачи, поэтому с помощью ML (Machine Learning) может быть проверено на аномалии. В качестве другой аномалии может выступать тот факт, что были созданы новые ветки реестра, но за этим не последовало события 4698, говорящего о создании задачи.
В совокупности с вышесказанным, но не по отдельности, мы имеем возможность отслеживать перезапуск службы Scheduler с помощью ETW TaskScheduler\Operational
события 402 (Service shutting down) и 400 (Service started) или через Process Creation (4688). Почему не стоит полагаться на данные события, как на самостоятельные? Только потому, что данные события происходят при каждом включении ПК, что будет приводить к ложно-положительным сработкам. В свою очередь связать перезапуск службы с перезапуском устройства можно с помощью события 1074 (System has been shutdown by a process/user) в журнале System.
TaskScheduler\Operational
, говорящее об остановке службы Schedule
TaskScheduler\Operational
, говорящее старте службы Schedule
Schedule
Также не следует забывать о ситуации, когда задача была создана стандартным способом, а после были удалены ключи в реестре для ее сокрытия. Для этого следует следить за удалением/изменением отдельных ключей реестра (SD и Index).
При удаленном способе редактирования веток реестра применяется протокол WINREG. Внутри пакетов трафик зашифрован. Поэтому использовать информацию внутри трафика для детекта нельзя. Но можно зайти с другой стороны и задаться вопросом, а как часто и для каких целей может использоваться протокол WINREG в корпоративной среде? Ответ на этот вопрос зависит от конкретной организации и выстроенных в ней IT-процессов. Так, если в компании администраторы не применяют инструменты для удаленного редактирования реестра или ПО, в основе которого лежит WINREG, то появление событий в трафике с использованием данного протокола, должны выглядеть подозрительно, что будет служить аномалией.
Заключение
В этой статье мы рассмотрели интересный метод создания запланированной задачи в Windows системе, а также возможный способ сокрытия задачи в планировщике задач. В результате чего стало понятно, что стандартные способы детектирования техники по созданию запланированных задач на основе событий из Security журнала 4698, 4699, 4702 не подходят в конкретном случае. Также мною были предложены маркеры, на основе которых можно построить детект. Основная идея заключается в мониторинге изменения определенных веток реестра от имени процесса отличного от Schedule
. Для наиболее точного распознавания таких случаев были представлены другие дополнительные маркеры детектирования, но рассматривать их стоит в совокупности, а не каждый по отдельности.
Надеюсь данная статья оказалась для вас полезной! Если у вас появились вопросы, пишите в комментариях!
Автор: Кожушок Диана( @wildresearcher), аналитик-исследователь киберугроз в компании R-Vision
Все способы:
- Способ 1: Консоль «PowerShell»
- Способ 2: Скрипт VBS
- Способ 3: Планировщик заданий
- Способ 4: Сторонние утилиты
- Вопросы и ответы: 0
Способ 1: Консоль «PowerShell»
Для запуска программ и процессов в скрытом режиме, без использования графического интерфейса, в Windows 10 предусмотрен специальный командлет «PowerShell».
- Запустите консоль «PowerShell» из контекстного меню кнопки «Пуск».
- Сформируйте и выполните команду вида
Start-Process -WindowStyle hidden "Path"
, заменив Path на полный путь к исполняемому файлу запускаемой в скрытом режиме программы.
Способ 2: Скрипт VBS
Скрыть явную работу приложения можно также с помощью простого скрипта на языке VBS, в котором после исполняемого файла приложения указывается специальный аргумент.
- Создайте «Блокнотом» или любым другим простым текстовым редактором новый текстовый файл.
- Вставьте в документ следующий код, заменив cmd.exe названием исполняемого файла программы, которую нужно запустить в скрытом режиме. Если файл располагается в системных каталогах, можно ограничиться лишь именем файла. В противном случае в двойных кавычках необходимо прописать полный к нему путь.
Dim WShell
Set WShell = CreateObject("WScript.Shell")
WShell.Run "cmd.exe", 0
Set WShell = Nothing
- Сохраните файл с произвольным названием, но обязательно с расширением VBS.
Готово, запустите созданный скрипт двойным по нему кликом.
Способ 3: Планировщик заданий
Эффективный, но не слишком удобный способ запуска приложений в скрытом режиме. Реализуется он с помощью встроенного в Windows 10 «Планировщика заданий».
- Откройте штатный «Планировщик заданий» командой
taskschd.msc
, выполненной в диалоговом окошке быстрого запуска (Win + R). - Нажмите в правой колонке «Создать задачу».
- В поле «Имя» введите произвольное название создаваемой задачи, активируйте радиокнопку «Выполнять для всех пользователей». Установите флажок в чекбоксе «Скрытая задача», а из выпадающего списка «Настроить для» выберите «Windows 10».
- Переключитесь на вкладку «Действие» и нажмите «Создать».
- Нажав кнопку «Обзор», укажите путь к исполняемому файлу программы, которую хотите запустить в скрытом режиме. Нажмите «ОК».
- Сохраните задание, нажав «ОК».
Теперь, чтобы запустить программу без использования графического интерфейса, в правой колонке «Планировщика заданий» нажмите «Выполнить».
Как вариант, можно создать на задание отдельный ярлык, прописав в поле расположения объекта команду C:\Windows\System32\schtasks.exe /run /tn "TaskName"
, где TaskName – название созданной в планировщике задачи.
Способ 4: Сторонние утилиты
Для запуска классических десктопных приложений с графическим интерфейсом можно использовать специальные утилиты, например инструмент PsExec.
Скачать Sysinternals PsExec с официального сайта
- Скачайте архив с утилитами Sysinternals с сайта Microsoft и распакуйте.
- Найдите среди извлеченных файлов «psexec.exe» и скопируйте его в системный каталог
C:/Windows/System32
. - Для запуска нужной программы в скрытом режиме откройте от имени администратора «PowerShell» и выполните команду
.\psexec -i 0 -d program.exe
, где program.exe – название программы.Если запускаемое в фоновом режиме приложение находится не в системных, а в пользовательских каталогах, вместо только одного имени указывайте полный к ней путь. Если путь содержит пробелы, его нужно будет взять в двойные прямые кавычки.
Вместо «PowerShell» можно использовать классическую «Командную строку». В этом случае точку со слешем перед «psexec» добавлять не нужно.
Наша группа в TelegramПолезные советы и помощь
Вы тут: Главная → Windows → Нюансы настройки запланированного задания или как запустить невидимое приложение
Недавно в чат пришел человек с вопросом по статье Как выполнять задачи с полными правами обычным пользователем без ввода пароля администратора. У него не отображалось окно приложения, которое пользователь запускал на сервере изложенным в материале способом. Как правило, я очень внимательно отношусь к сообщениям о том, что мои инструкции не работают. Но на сей раз я не стал особо вникать, потому что автор вопроса старательно создавал дыру в безопасности сервера.
Я сослался на предупреждение жирным шрифтом в статье не использовать этот метод для интерактивных приложений и перевернул страницу. Тем более проблема участника была в другом. Там местного разработчика нужно было побольнее пнуть, чтобы его поделка не требовала прав администратора без нужды. Как-никак уже прошло 16 лет с выхода Vista и дебюта UAC, пора уже освоить грамотные подходы.
[+] Сегодня в программе
Невидимое приложение и Session 0
Об этом случае я вспомнил на днях, когда столкнулся с аналогичной проблемой, решая совсем другую задачу. Права администратора у меня были, но запуск приложения из планировщика не отрабатывал. Присмотревшись к списку процессов, я увидел там заветное приложение. Пусть это будет cmd для демонстрации.
Обратите внимание на столбец SI. Это Session ID — идентификатор сеанса. Вошедшие в систему интерактивные пользователи получают ИД сеанса 1, 2, 3 и т.д. А Session 0 – специальный изолированный сеанс для процессов, которыми владеет система и службы Windows. Он появился в Windows Vista с целью укрепления безопасности ОС.
Работающие в пользовательском сеансе процессы не могут взаимодействовать с процессами из Session 0. Это предотвращает атаки на более привилегированные процессы. Читайте про Session 0 Isolation, например, у Руссиновича: Windows Internals, Fifth Edition, Chapter 4.
В этом случае процесс запустился фактически как служба, хотя и от имени моего пользователя, что можно увидеть с параметром -IncludeUserName.
Одновременно с изоляцией сеанса 0 в Windows Vista добавили службу Interactive Services Detection (UI0Detect) для поддержки обратной совместимости в старых программах, пытающихся взаимодействовать с пользователем из нулевого сеанса. Но ее выпилили в Windows 10 за ненадобностью.
Кстати, планировщик — не единственный способ запуска процесса в сеансе 0. Можно воспользоваться psexec Руссиновича:
psexec -i 0 -d notepad
Теперь понятно, почему окно не отображается. Но почему у нас с читателем приложения запускались из планировщика в сеансе 0?
Настройки выполнения запланированного задания
Мы одинаково задали один параметр наших заданий, хотя и преследовали разные цели.
Запланированные задания были настроены запускаться для всех пользователей!
Действительно, читатель просто следовал моей инструкции. Но там все так и было задумано. Ведь по условиям задачи нужно было реализовать работу задания в планировщике вне зависимости от того, выполнен ли вход с административной учетной записью.
У меня же была своя причина. Недавно я показывал в канале такой подход к настройке запланированного задания, чтобы не мигало консольное окно. И вообще не подумал о том, что скроется окно интерактивного приложения.
Нет, конечно, я тестировал. Но у меня такие задачи не подразумевают взаимодействия с программами. Скрипт запустился, отработал — финиш. А тут я добавил к скрипту обслуживания еще и запуск приложения и… наступил на свои же грабли
Заключение
В периоды взрывного роста курса биткойн в чате несколько раз всплывал вопрос запуска приложения незаметно для неопытного пользователя — окна нет и ладно, майним потихоньку. Теперь вы знаете способ
Возвращаясь же к вопросу читателя, я лишь порадовался, что он, не вняв моим предупреждениям, уперся в настоящую границу защищенной зоны Windows (security boundary). Иначе бы у него на сервере сейчас простые пользователи гоняли приложения с правами администратора.
Оглавление
- Введение
- Существенные изменения планировщика задач в Windows 8
- Новые (не)удобные фичи и их последствия
- Структура Actions
- Плагин «4RAYS TaskCache» для Registry Explorer
- Выводы
Введение
Команда Solar 4RAYS изучила множество материалов, посвященных DFIR в операционных системах Windows, и мы заметили,
что сообщество информационной безопасности игнорирует важное изменение в работе планировщика задач, которому уже
исполнилось 12 лет. Об обнаруженных нами проблемах писали в том или ином виде, но данная информация не освещается
широко и разбросана по разным статьям без общего вывода о критичности. А проблемы связаны с тем, что при анализе
систем начиная с Windows 8 вы можете не видеть часть задач, которые выполняет планировщик.
Представьте, что вы являетесь начинающим специалистом-форензиком и вам требуется изучить «Windows Persistence». Что
вы будете читать? Чем пользоваться? Курсы или книги могут отличаться, однако с высокой вероятностью вы все равно
столкнетесь с проблемой, когда ваше обучение дойдет до «Scheduled Task/Job T1053.005».
Для начала давайте ответим на вопрос:
Вам предоставили на анализ систему Windows 10, где атакующие точно закрепились с использованием планировщика
задач, и система даже включена! Увы, все журналы были очищены. Где вы будете искать командлайн вредоносной
задачи?
Ответ:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache
Так как иные артефакты могут содержать недействительные данные о задачах, а некоторые задачи могут быть скрыты
из
вывода популярных утилит и WinAPI, но продолжать работать
Если на данный вопрос вы ответили иначе, то добро пожаловать! Мы собрали в одном месте всё, что вы могли не знать о
планировщике задач в Windows.
Существенные изменения планировщика задач в Windows 8
В Windows 8 были внесены существенные изменения в расположение хранилища задач: хоть xml-файлы и продолжают
создаваться по пути «C:\Windows\System32\Tasks», на самом деле планировщик задач загружает данные из реестра, а
именно – из ключа TaskCache, который появился еще во времена Windows 7:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache
В ключе TaskCache имеется несколько разделов, и в актуальных версиях Windows образует следующую структуру:
В младших версиях Windows некоторые значения отсутствуют, однако сама структура не изменяется.
Далее остановимся на разделах и значениях, интересных с точки зрения DFIR:
Раздел\Значение |
Описание |
---|---|
TaskCache\Tree |
Используется системой для отображения задач при запросе их списка или дерева. Содержит разделы, |
TaskCache\Tree\TaskPath\Task\Index |
Тип триггера задачи. Имеет значение от 1 до 4: 1 – Boot 2 – Logon 3 – Plain
4 – Maintenance |
TaskCache\Tree\TaskPath\Task\Id |
UUID задачи |
TaskCache\Tree\SD TaskCache\Tree\TaskPath\SD TaskCache\Tree\TaskPath\Task\SD |
Security Descriptor, описывающий права доступа на просмотр данной задачи или дерева. Не связан с *появился лишь в Windows 10 |
TaskCache\Tasks |
Используется системой для хранения данных о задачах, включая командлайн. Содержит разделы, имена |
TaskCache\Tasks\{Id}\Actions |
Действия, которые должны выполниться после выполнения условий триггера |
TaskCache\Tasks\{Id}\Author |
Может содержать УЗ, с помощью которой была создана задача, но чаще всего содержит ссылку на dll |
TaskCache\Tasks\{Id}\DynamicInfo |
Содержит временные метки создания, последнего запуска и последнего завершения выполнения задачи |
TaskCache\Tasks\{Id}\Hash |
CRC32 или SHA256 хэш xml-файла задачи (C:\Windows\System32\Tasks\) |
TaskCache\Tasks\{Id}\Path |
Содержит относительный путь до объекта в дереве или xml-файла в директории Tasks |
TaskCache\Tasks\{Id}\SecurityDescriptor |
Права, определяющие кому и что разрешено делать с задачей |
TaskCache\Tasks\{Id}\Triggers |
Триггеры, запускающие задачу |
TaskCache\Boot TaskCache\Logon TaskCache\Maintenance TaskCache\Plain |
Содержит разделы, имена которых соответствуют UUID задач. Наличие раздела означает наличие ссылки Boot – содержит ссылки на задачи, которые требуется выполнить при загрузке системы Logon – при входе в систему Maintenance – при автоматическом обслуживании системы Plain – иные задачи |
В Windows 10 перенос задач в реестр был завершен окончательно, и xml-файлы остались лишь легаси-фичей, с помощью
которой можно быстро экспортировать и импортировать задачи через интерфейс планировщика.
Чтобы убедиться в этом, достаточно создать новую задачу в Windows 10 и удалить ее файл из директории
«C:\Windows\System32\Tasks» – планировщик продолжит корректно отображать и запускать «удаленную» задачу даже после
перезагрузки, а файл восстановится лишь в случае модификации задачи непосредственно через WinAPI.
В Windows 7 аналогичные действия приведут к полному удалению задачи из системы.
При этом в Windows 8 существование xml-файла задачи является обязательным для ее запуска и отображения в интерфейсе
планировщика, но содержимое данного файла никак не влияет на параметры задачи – файл может быть модифицирован или
даже очищен, а задача продолжит выполняться корректно, так как данные берутся из реестра. Однако при перезагрузке
службы планировщика задач файл будет восстановлен до исходного состояния.
Описанные далее выявленные проблемы в работе планировщика задач применимы ко всем версиям Windows с 8 по 11, включая
их серверные версии.
Новые (не)удобные фичи и их последствия
Новая логика работы планировщика принесла с собой несколько новых функций, которые обернулись неприятными
последствиями.
Легаси
Как уже было написано выше, xml-файл задачи по стандартному пути продолжает появляться при создании или модификации
задачи через интерфейс планировщика или утилиту командной строки schtasks. Однако он никак не влияет на работу
задачи, поэтому начиная с Windows 8 пользователь может модифицировать (а в Windows 10-11 даже удалить) xml-файл, не
изменив параметры задачи и не нарушив работу системы.
Содержимое xml-файлов в «C:\Windows\System32\Tasks\» начиная с Windows 8 не является достоверным источником
информации о задачах, которые работают в системе, так как целостность файла существующей задачи может быть нарушена
без влияния на систему
❗ Если ваша BlueTeam в выключенной системе смотрит лишь xml-файлы, вредоносные задачи с поддельным или удаленным
xml-файлом могут быть пропущены.
Начиная с Windows 8 удаление задач требуется выполнять лишь через интерфейс планировщика или утилиту schtasks. В
крайнем случае требуется удалить соответствующие задаче 3 раздела реестра.
❗ Если ваши системные администраторы продолжают удалять лишь xml-файлы задач в надежде удалить задачу из
планировщика, как это было в Windows 7 и частично подходит для Windows 8, то начиная с Windows 10 задача остается
активной.
Скрытие задач из вывода WinAPI и основанных на нем утилит
Техники, о которых писали давно, но не получившие широкого распространения. Они связаны с значениями Index и SD
раздела реестра в TaskCache\Tree.
- В значении SD указываются права на просмотр задачи, и при установке невалидного значения задача пропадает из
вывода утилит, использующих WinAPI, кроме прямого просмотра содержимого реестра; - В значении Index указывается тип триггера задачи (в диапазоне от 1 до 4), но если установить значение 0, то
задача также скроется от WinAPI.
Баг это или фича – неизвестно, но одними из первых об этом написали
сами же Microsoft в 2022 году в своем блоге, посвященном безопасности. Однако в указанной статье нет упоминания про
значение Index, о котором далее напишут коллеги из R-Vision в своей статье на
Habr. Реализацию техники с изменением Index со стороны атакующих мы также упомянули в статье «Reign of King: тактики и инструментарий группировки Obstinate
Mogwai».
При исследовании данной техники выяснилось, что она работает лишь начиная с Windows 10. В Windows 8 еще не было
реализовано значение SD, а изменение Index не влечет за собой сокрытия задачи.
Но что такое «невалидный SD»? В обнаруженных нами материалах многие пишут про случай, когда «SD = null», то есть
значение удалено, однако это лишь часть большей проблемы с данным значением.
Для выполнения техники с сокрытием задачи, атакующий может:
1) Удалить значение SD;
2) Очистить или изменить на произвольные байты содержимое SD;
3) Удалить из структуры SD информацию о владельце или группе.
При этом данные действия могут быть выполнены не только с разделом самой задачи, но и с разделом, который является
частью пути до задачи:
Таким образом, любые задачи, которые будут размещаться по пути «\Microsoft\Windows\Evil\», будут скрыты из вывода
списка задач WinAPI, но продолжат работать.
Вывод списка задач с помощью стандартных утилит (или основанных на WinAPI) начиная с Windows 10 также не является
достоверным источником данных о задачах, так как они могут быть скрыты из этого вывода.
❗ Если ваша BlueTeam в запущенной системе Windows 10 (и старше) смотрит задачи через утилиты, которые работают лишь
с WinAPI и не берут данные из реестра, то вредоносная задача будет пропущена.
Интересный факт: если задача скрыта с помощью изменения значения Index, то хоть она и скрыта из вывода списка задач,
прямой доступ к ней можно получить через консоль, если известен путь до неё. Из-за этого мы можем не только получить
информацию о самой задаче, но и удалить её:
schtasks /query /tn "\Microsoft\Windows\Evil\Task"
schtasks /delete /tn "\Microsoft\Windows\Evil\Task"
Однако если задача скрыта с помощью установки невалидного значения SD, аналогичные действия приведут к «Внутренней
ошибке».
Также можно отметить, что в Windows 10 и 11 атакующие могут удалить значение Index – без него задачи продолжат
выполняться, но тогда «Внутренняя ошибка» будет возникать каждый раз при открытии планировщика задач, и из системы
уже скроются абсолютно все задачи.
Обход логирования планировщика и изменение метадаты
Импорт, изменение или удаление значения в реестре системы, не является триггером для генерации событий планировщика
задач.
Для выполнения данной техники атакующим требуется создать файл с значениями для импорта.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Plain\{00000000-0000-0000-0000-000000000001}]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Evil]
"SD"=hex:01,00,04,80,88,00,00,00,98,00,00,00,00,00,00,00,14,00,00,00,02,00,74,\
00,04,00,00,00,00,10,18,00,9f,01,1f,00,01,02,00,00,00,00,00,05,20,00,00,00,\
20,02,00,00,00,10,14,00,9f,01,1f,00,01,01,00,00,00,00,00,05,12,00,00,00,00,\
10,18,00,ff,01,1f,00,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,00,00,00,\
24,00,89,00,12,00,01,05,00,00,00,00,00,05,15,00,00,00,da,29,6a,f7,90,54,53,\
10,ba,4e,d6,6f,e8,03,00,00,30,b5,26,31,01,02,00,00,00,00,00,05,20,00,00,00,\
20,02,00,00,01,05,00,00,00,00,00,05,15,00,00,00,da,29,6a,f7,90,54,53,10,ba,\
4e,d6,6f,01,02,00,00
"Id"="{00000000-0000-0000-0000-000000000001}"
"Index"=dword:00000003
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{00000000-0000-0000-0000-000000000001}]
"Path"="\\Evil"
"Triggers"=hex:17,00,00,00,00,00,00,00,00,df,17,79,58,00,00,00,00,00,00,00,00,\
00,00,00,00,df,17,79,58,00,00,00,ff,ff,ff,ff,ff,ff,ff,ff,38,21,41,42,48,48,\
48,48,cc,ca,a4,6b,48,48,48,48,0e,00,00,00,48,48,48,48,41,00,75,00,74,00,68,\
00,6f,00,72,00,00,00,48,48,00,00,00,00,48,48,48,48,00,48,48,48,48,48,48,48,\
00,48,48,48,48,48,48,48,01,00,00,00,48,48,48,48,1c,00,00,00,48,48,48,48,01,\
05,00,00,00,00,00,05,15,00,00,00,da,29,6a,f7,90,54,53,10,ba,4e,d6,6f,e8,03,\
00,00,48,48,48,48,1a,00,00,00,48,48,48,48,53,00,41,00,4e,00,44,00,42,00,4f,\
00,58,00,5c,00,55,00,73,00,65,00,72,00,00,00,48,48,48,48,48,48,2c,00,00,00,\
48,48,48,48,00,00,00,00,ff,ff,ff,ff,80,f4,03,00,ff,ff,ff,ff,07,00,00,00,00,\
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,48,48,\
48,48,77,77,00,00,00,00,00,00,00,df,17,79,58,00,00,00,00,00,00,00,00,00,00,\
00,00,df,17,79,58,00,00,00,ff,ff,ff,ff,ff,ff,ff,ff,00,00,00,00,ff,ff,ff,ff,\
00,00,00,00,00,00,00,00,00,00,00,00,00,02,00,00,01,ff,ff,ff,00,00,00,00,00,\
00,00,00,00,00,00,00,00,00,00,00,48,48,48,48,08,00,00,00,00,00,00,00,01,48,\
48,48,48,48,48,48
"Actions"=hex:03,00,0c,00,00,00,41,00,75,00,74,00,68,00,6f,00,72,00,66,66,00,\
00,00,00,06,00,00,00,63,00,6d,00,64,00,44,00,00,00,2f,00,63,00,20,00,73,00,\
74,00,61,00,72,00,74,00,20,00,68,00,74,00,74,00,70,00,3a,00,2f,00,2f,00,6c,\
00,6f,00,63,00,61,00,6c,00,68,00,6f,00,73,00,74,00,2f,00,6d,00,65,00,74,00,\
61,00,64,00,61,00,74,00,61,00,00,00,00,00,00,00
"DynamicInfo"=hex:03,00,00,00,00,57,F1,FB,5D,44,D1,01,00,48,F1,AF,C5,B1,9D,01,\
00,00,00,00,00,00,00,00,00,48,F1,AF,C5,B1,9D,01
Далее, обладая правами системы, требуется выполнить импорт значений в реестр. При перезагрузке службы планировщика
задача начнет работать без генерации событий о ее создании. Таким же образом задача может быть модифицирована и
удалена. Подробнее с примерами про это писали
R-Vision в той же статье на Habr.
❗ Если ваша BlueTeam смотрит лишь события создания, модификации или удаления задач в соответствующих журналах, то
вредоносная задача может быть пропущена.
Однако при проверке данной техники выяснилось, что помимо обхода логирования, атакующие также могут вписать
произвольные данные в значения, которые являются метадатой, что логично.
Так при проверке в Windows 10 выяснилось, что содержимое следующих значений может не содержать действительной
информации, а сами значения вовсе могут быть удалены:
- TaskCache\Tasks\{Id}\Author
- TaskCache\Tasks\{Id}\Date
- TaskCache\Tasks\{Id}\DynamicInfo
- TaskCache\Tasks\{Id}\Hash
- TaskCache\Tasks\{Id}\Schema
- TaskCache\Tasks\{Id}\URI
Временные метки в значениях Date и DynamicInfo могут быть подменены атакующими. Более ценной временной меткой
является модификация разделов, соответствующих задаче:
- TaskCache\Tasks\{Id}\ – модифицируется при работе задачи из-за изменения DynamicInfo;
- TaskCache\Tree\Name\ – модифицируется лишь при создании/изменении самой задачи и, в случае подмены метки
создания в метадате, может быть наиболее близко к действительной дате создания.
Значение Hash также может содержать недействительное значение – фильтрация по нему недопустима.
❗ Если ваша BlueTeam фильтрует задачи по хэшу xml-файла или значению TaskCache\Tasks\{Id}\Hash, то вредоносная
задача может быть пропущена.
Сообщество разработчиков утилит для DFIR
Вероятно, многие действительно пропустили переезд задач в реестр или не отметили важность данного обновления.
Безусловно, самая популярная утилита для удобного просмотра реестра Registry Explorer в 2024 году (спустя 12 лет
после релиза Windows все еще не обрабатывает их должным образом. А точнее, игнорирует значение Actions, которое
содержит командлайн задачи:
Данное значение можно посмотреть вручную, но там отображается лишь бинарная структура, требующая дополнительной
обработки.
Однако Registry Explorer – единственное ПО, которое хоть каким-то образом обрабатывает значения TaskCache: колонки
Created On, Last Start и Last Stop – это результат обработки значения DynamicInfo, которое также является бинарной
структурой. Впрочем, требуется помнить, что данные значения могут быть подменены атакующими.
Ситуация с популярным нынче Velociraptor двоякая. В документации были обнаружены весьма обнадеживающие страницы:
1) Задачи уже считаются сущностью из реестра, а логика сбора артефактов не связана с xml-файлами. Но здесь нас
встречает абзац TODO, где обещано добавить данный артефакт в основной репозиторий. На момент исследования в сентябре
2024 в релизной версии всё ещё отсутствует данное обновление.
Однако при ручном добавлении данного модуля выяснилось, что значение Actions не обрабатывается и сохраняется в
base64, которое абсолютно непригодно для просмотра человеком и требует дополнительной ручной обработки или
автоматизации. Еще один недостаток – отсутствие обработки значения DynamicInfo.
2) Отдельно подготовлен модуль для поиска скрытых задач, но он опирается лишь на значение SD в разделах задач, без
учета случаев с Index и модификации SD в разделе, который является частью пути. В релизной версии данного модуля
также не обнаружено. Дополнительно отмечается, что данный модуль лишь проверяет значение SD на null, когда задача
может быть скрыта модификацией значения, а не с помощью его удаления.
Прочие популярные инструменты, такие как AutoPsy, OsForensics и X-Ways, отображают реестр так же, как и стандартный
редактор реестра Windows: значение Actions не обрабатывается и представлено в виде hex-string. Утилиты Sysinternals
Autoruns и Nirsoft TaskSchedulerView не обнаруживают скрытые задачи в Windows 10-11, так как используют WinAPI,
однако отображают задачи без xml-файла.
Популярные утилиты для DFIR всё еще не обрабатывают ключ TaskCache:
1) Type Viewer в Registry Explorer позволяет немного упростить просмотр разделов, но это потребует поочередного
ручного просмотра значений, где их может быть более сотни;
2) Velociraptor при добавлении неопубликованных модулей позволяет собирать значения Actions, но сохранение
значения в base64 требует дополнительной обработки. При использовании данной утилиты из коробки, задачи из
TaskCache никак не обрабатываются.
Структура Actions
Если ни в одной из популярных утилит не реализована обработка значения Actions, неужели это невозможно? Структура
значения не является задокументированной Microsoft, но данным вопросом уже занимались исследователи
Windows еще в 2022 году. Мы не будем дублировать весь материал, представленный в исследовании с ресурса cyber.wtf, а
рассмотрим и дополним лишь основные моменты.
Структура состоит из заголовка и от одного до множества тел Actions. Если задача выполняет 3 действия при
срабатывании триггера, то структура будет иметь 3 последовательно записанных тела.
Тело Actions разделяется на несколько типов, которое определяется Magic-строкой в начале тела:
1) 0x6666 – прямой запуск исполняемого файла с необходимыми аргументами;
2) 0x7777 – запуск COM-объектов;
3) 0x8888 – отправка Email (устаревшее);
4) 0x9999 – вывод Message Box (устаревшее).
Отмечается, что планировщик задач не позволяет создавать устаревшие типы Actions.
Рассмотрим пример. В значении Actions хранятся данные:
03000C00000041007500740068006F00720066660000000010000000630061006C0063002E006500780065000000000000000000000077770000000029B731AEFDD51E40AF42784074835AFE3E0000002D0052006500670069007300740065007200550073006500720044006500760069006300650020002D004E00650077004100630063006F0075006E007400
Структура этих данных выглядит следующим образом:
|
Типы данных |
Описание |
---|---|---|
|
int16 версия int32 длина строки Unicode string |
Заголовок структуры. Содержит версию, а также Context задачи |
|
Magic: Action-Type int32 длина строки Unicode string int32 длина строки Unicode string int32 длина строки Unicode string int32 длина строки Unicode string Флаги |
Тело структуры, которое начинается с типа Action. Для типа 6666, далее следует 4 пары int32 и Unicode строки, которые хранят в себе значения: 1) id 2) command 3) arguments 4) directory
Данный тип завешается на 2 байта флагов, которые пока нам не встречались (флаги имеются лишь с |
|
Magic: Action-Type int32 длина строки Unicode string byte COM-object int32 длина строки Unicode string |
Для типа Action 7777, далее также следует пара int и Unicode строки для хранения значения id, после |
В результате обработки можно получить следующие данные:
Version: Context: |
3 Author |
ID: Command: Arguments: Working Directory: |
null calc.exe null null |
ID: COM-object: Data: |
null {29B731AE-FDD5-1E40-AF42-784074835AFE} -RegisterUserDevice -NewAccount |
А чтобы автоматически обработать значение из примера, можно использовать следующий код на C#:
byte[] keyValue = StringToByteArray("03000C00000041007500740068006F00720066660000000010000000630" +
"061006C0063002E006500780065000000000000000000000077770000000029B731AEFDD51E40AF42784074835A" +
"FE3E0000002D0052006500670069007300740065007200550073006500720044006500760069006300650020002" +
"D004E00650077004100630063006F0075006E007400");
using Stream stream = new MemoryStream(keyValue);
using BinaryReader reader = new BinaryReader(stream);
//Header
short version = reader.ReadInt16();string context = (version >= 2) ?
Encoding.Unicode.GetString(reader.ReadBytes(reader.ReadInt32())) : string.Empty;
//ActionType 0x6666
short type_first = reader.ReadInt16();
string id_first = Encoding.Unicode.GetString(reader.ReadBytes(reader.ReadInt32()));
string path = Encoding.Unicode.GetString(reader.ReadBytes(reader.ReadInt32()));
string arguments = Encoding.Unicode.GetString(reader.ReadBytes(reader.ReadInt32()));
string workingDirectory = Encoding.Unicode.GetString(reader.ReadBytes(reader.ReadInt32()));
short flags = (version >= 3) ?
reader.ReadInt16() : (short)0;
//ActionType 0x7777
short type_second = reader.ReadInt16();
string id_second = Encoding.Unicode.GetString(reader.ReadBytes(reader.ReadInt32()));
Guid clsid = new Guid(reader.ReadBytes(16));
string data = Encoding.Unicode.GetString(reader.ReadBytes(reader.ReadInt32()));
Плагин «4RAYS TaskCache» для Registry Explorer
Мы готовы поделиться собственным плагином для Registry Explorer, который позволяет просматривать значение Actions и
помогает искать скрытые задачи:
- Key Name – GUID задачи;
- Path – путь до задачи в дереве;
- Actions – перечисление командлайнов, которые выполняет задача;
- Actions Type – перечисление типов, которые используется в задаче;
- Tree Key Last Write – временная метка модификации раздела задачи в дереве;
- Created On, Last Start, Last Stop – обработка значения DynamicInfo;
- Index – соответствующее значение из дерева;
- Tree SD – уникальные значения SD разделов, образующие путь до задачи в дереве, с подсвечиванием случаев, когда
задача может быть скрыта из планировщика.
Если значение Index будет соответствовать 0 или возникнет один из описанных случаев с значением SD, то в колонке
Alert будет отображаться значение True, по которому также можно отфильтровать таблицу.
Загрузить скомпилированный плагин, а также ознакомиться с исходным кодом можно в нашем GitHub.
Для его установки требуется поместить dll-файл в директорию «..\RegistryExplorer\Plugins», после запуска
RegistryExplorer, при открытии «View» > «Plugins» должен появиться новый плагин.
При открытии ключа TaskCache, доступного в стандартных закладках, откроется таблица:
Поддержку данного плагина пока гарантировать не можем, однако о багах вы можете сообщить нам в GitHub в разделе
Issues.
Выводы
С обновления планировщика задач прошло уже 12 лет. Вероятно, BlueTeam пора отреагировать на данное изменение:
- Усовершенствовать инструменты для просмотра и сбора задач как для работы с работающими системами, так и при
работе с артефактами; - Внести правки в обучающие материалы по DFIR;
- Говорить об этой проблеме шире: некоторые системные администраторы всё ещё по привычке удаляют xml-файл задачи,
сохраняя в системе Persistence.
Еще раз повторим, почему стоит все это сделать уже сейчас:
- При работе с Windows 8, 10, 11 (и, вероятно, в будущих релизах) достоверные данные о работающих в системе
задачах хранятся лишь в реестре в ветке TaskCache:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache
- Xml-файлы по прежним путям – это лишь легаси файлы, которые могут быть модифицированы или удалены без влияния на
значения в реестре; - Во включенной системе задачи могут быть скрыты из вывода стандартных утилит или иных утилит, основанных на
WinAPI, если в значения Index или SD будут внесены изменения атакующим; - Создание, модификация и удаление задач с помощь импорта значений в реестр не генерирует событий соответствующих
действий с задачами; - На момент написания статьи ни одна из популярных утилит для DFIR не отображает скрытые задачи, а также не
обрабатывает все значения ключа TaskCache; - На текущий момент лучшим инструментом для просмотра и поиска подобных задач, по нашему мнению, является Registry
Explorer, в котором уже давно реализован просмотр списка задач по данным из реестра (но, к сожалению, без
командлайнов), а теперь для данного инструмента мы подготовили соответствующий плагин для дополнительной обработки
значений; - Удаление задач требуется выполнять лишь с помощью планировщика (интерфейс или командлайн). В крайнем случае –
удалять задачу напрямую из реестра. - Для удаления скрытых задач:
- Если Index = 0: удалить с помощью командлайна;
- Если значение SD не является валидным требуется удалить разделы реестра:
- ..\TaskCache\Tasks\{Id}
- ..\TaskCache\Tree\Path\TaskName
- ..\TaskCache\ (Boot / Logon / Maintenance / Plain) \{Id}
Напоследок приведем памятку про скрытые задачи:
А также итоговый таймлайн изменений в планировщике задач:
Версия Windows |
Изменения |
---|---|
Windows 7 Windows Server 2008 R2 Standard |
Первое появление TaskCache. Разделы задач содержат лишь 4 значения:
В дереве задач имеются значения:
Удаление xml-файла или ключей TaskCache равносильно удалению задачи
После ручного изменения xml-файла возникает ошибка «образ задачи был поврежден», а задача перестанет |
Windows 8 Windows Server 2012 |
В разделах задач стало больше значений:
TaskCache становится основным хранилищем задач, но без соответствующего задаче файла по пути |
Windows 10 Windows Server 2016 Windows Server 2019 Windows Server 2022 |
В разделах дерева появилось новое значение:
Для выполнения задач больше не требуется наличие какого-либо файла в «C:\Windows\System32\Tasks», Появление фич (багов) со скрытием задач, при изменении SD или Index в дереве |
Windows 11 |
Без изменений. Скрытие задач всё еще возможно. |
На этом у нас все. Пользуйтесь плагином на здоровье и, как говорится, happy hunting!
Полезные источники:
https://cyber.wtf/2022/06/01/windows-registry-analysis-todays-episode-tasks/
https://habr.com/ru/companies/rvision/articles/723050/
On Windows 11 (or 10), sometimes it’s necessary to automate certain routine tasks (for example, mount a network drive, launch an app, run a batch file, show a message) and run them at specific scheduled times. Usually, you use Task Scheduler, as it’s a tool designed to execute tasks based on a wide range of criteria.
The only caveat is that while creating a task, you can check a “Hidden” option, but when the task runs, the Task Scheduler will show a command window on the desktop briefly, which is not only annoying, but it’s also a bad user experience.
If you use the Task Scheduler on Windows 11 to run tasks at a specific time or during a trigger event and a command window keeps appearing every time the task runs, it’s possible to configure the task to stop rendering a command window.
In this guide, you’ll learn the steps to configure a scheduled task to run hidden (silent) without flashing a command window every time it runs on Windows 11.
Configure schedule task to run hidden on Task Scheduler
To prevent a command window from appearing when running a scheduled task on Windows 11 (or 10), use these steps:
-
Open Start.
-
Search for Task Scheduler, and click the top result to open the app.
-
Right-click the Task Scheduler Library folder and select the Create Task option.
-
In the “General” tab, under the “Security options” section, select the “Run whether user is logged on or not” option.
Quick note: This is the option that will make the command window not appear when the task runs automatically.
-
Clear the “Do not store password” option.
Quick note: This is an optional step, but if the task isn’t working, check this option and supply the appropriate credentials to run the task.
Once you select the correct options, continue configuring the task with the command you want to run and schedule, but now every time the scheduled tasks run, users will no longer see a command window flashing.
You can always test the configuration by right-clicking the task and choosing the “Run” option.
Mauro Huculak is a
Windows How-To Expert and founder of
Pureinfotech
(est. 2010). With over 21 years as a technology writer and IT Specialist,
Mauro specializes in Windows, software, and cross-platform systems such as Linux, Android, and macOS.
Certifications:
Microsoft Certified Solutions Associate (MCSA),
Cisco Certified Network Professional (CCNP),
VMware Certified Professional (VCP),
and
CompTIA A+ and Network+.
Mauro is a recognized Microsoft MVP and has also been a long-time contributor to Windows Central.
You can follow him on
YouTube,
Threads,
BlueSky,
X (Twitter),
LinkedIn and
About.me.
Email him at [email protected].