Введение
Команда 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, описывающий права доступа на просмотр данной задачи или дерева. Не связан с правами на выполнение. Имеется у всех разделов TaskCache\Tree *появился лишь в Windows 10  | 
		
| 
				 TaskCache\Tasks  | 
			
				 Используется системой для хранения данных о задачах, включая командлайн. Содержит разделы, имена которых соответствуют UUID задач.  | 
		
| 
				 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 задач. Наличие раздела означает наличие ссылки для конкретного триггера. Прямая связь с значением TaskCache\Tree\TaskPath\Index 
 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 8) все еще не обрабатывает их должным образом. А точнее, игнорирует значение 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, после которого хранится 16 байт COM-GUID вызываемого объекта. Структура завершается на еще одну пару int32 и Unicode строки, обозначающие аргументы для запуска  | 
		
В результате обработки можно получить следующие данные:
	
		
			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 становится основным хранилищем задач, но без соответствующего задаче файла по пути «C:\Windows\System32\Tasks» она не будет выполняться и отображаться в планировщике. При этом, содержимое файла не имеет значения для планировщика. Модифицированный xml-файл задачи будет восстановлен из реестра при перезагрузке службы планировщика задач  | 
		
| 
				 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/
            












