PunchAPGA backs Soludo’s appointment to APC presidential campaign councilThe Jerusalem PostHow do Israeli elections work? A guide to voting, Knesset seats, and coalitions - explainerCNN TürkElektrikli skuter yönetmeliği değişti: İşte yeni ceza tutarlarıESPNTransfer rumors, news: Barcelona, Real Madrid scout Erling Haaland at AnfieldInquirerPiston to hold caravan with remains of 1 of its former leaders Elmer CorderoUOLConfira os falecimentos desta terça-feira (13) em ApucaranaZDF heuteEntdecken Sie das ZDF-NachrichtenstudioPremium TimesCatholic diocese shuts schools, hospital, parish over repeated attacksDeadlineJ.K. Rowling To Be Subject Of BBC Documentary Examining Her Rise & Gender Identity ViewsThe Sydney Morning Herald'Dream Test' for Renshaw after wicketGolem.dePolizei: 16-Jährige in Köln von Roboter sexuell belästigtRMF24Zełenski: Partnerzy nie uprzedzili nas o balistycznym ataku na Kijów
The Daily Newsstand · Free, Always
Tuesday, October 13, 2026

Windows IR: системный подход. Часть 3 — задачи, автозапуск, учётные записи, журналы

Translate

Это третья часть материала, посвящённого Windows IR. Вторая часть была посвящена изоляции хоста и разбору процессов и служб. В этой части — проверяем ещё две частые точки закрепления, задачи планировщика и автозапуск через реестр, смотрим на локальные учётные записи и группы, и наконец садимся за журналы событий, чтобы связать разрозненные находки в единую хронологию. Здесь же выводы из демонстрационной лабы складываются в цельную картину атаки.

Шаг 7. Задачи планировщика

Задача в планировщике отличается от службы тем, что срабатывает по триггеру: по времени, при входе пользователя, при загрузке, по событию в журнале.

Отсеять задачи Microsoft

Get-ScheduledTask |
    Where-Object TaskPath -notlike '\Microsoft\*' |
    Format-Table TaskPath,TaskName,State,Author -AutoSize

Всё, что создано вручную, попадает в корень \. Его надо анализировать в первую очередь. Задачи Microsoft отсеиваются не с концами, к ним надлежит вернуться позднее. Но в первом приближении – откладываем их.

Отфильтровать по тому, что задача запускает

Get-ScheduledTask |
    Where-Object {
        $_.Actions.Execute -match 'powershell|cmd|wscript|cscript|mshta' -or
        $_.Actions.Arguments -match 'ProgramData|AppData|\\Temp\\'
    } |
    Format-List TaskName,TaskPath,State,Actions,Triggers,Principal

Ну вот, кандидатов на первоочередной анализ нашли. Уже видны задачи со странными именами, но нет никакой конкретики, ни Actions, ни Triggers задач. Чтобы посмотреть их, можно запустить GUI планировщика:

Или использовать Autorunsc.

Autorunsc по задачам

C:\Kit\SysinternalsSuite\Autorunsc64.exe -accepteula -a t -h

Флаг -a t ограничивает проверку задачами планировщика, -h добавляет хеши.

Задачи как файлы

Планировщик хранит задачи в виде XML в C:\Windows\System32\Tasks, и можно читать их напрямую оттуда. Здесь особенно полезен столбец LastWriteTime – задачи, созданные в окно инцидента, будут видны сразу.

Get-ChildItem C:\Windows\System32\Tasks\
Get-Content 'C:\Windows\System32\Tasks\Windows Health Telemetry'

В итоге у нас есть две вредоносные задачи, скрыто запускающие скрипты. Один из этих скриптов уже был пойман в цепкие лапы выше, а второй мы встречаем впервые. Смотрим его ближе, снимаем метаданные, хэш и содержимое:

Get-Item 'C:\Users\a.sokolova\AppData\Roaming\SecureDocumentViewer\UpdateCheck.ps1'| Format-List FullName,Length,CreationTime,LastWriteTime
Get-FileHash 'C:\Users\a.sokolova\AppData\Roaming\SecureDocumentViewer\UpdateCheck.ps1'
Get-Content 'C:\Users\a.sokolova\AppData\Roaming\SecureDocumentViewer\UpdateCheck.ps1'

Журнал планировщика

$log = 'Microsoft-Windows-TaskScheduler/Operational'
Get-WinEvent -ListLog $log | Format-List LogName,IsEnabled,RecordCount

Проверяем сначала, включен ли журнал. Если включён — оттуда можно взять факты регистрации задачи (событие 106) и её фактических запусков (129, 200, 201).

Get-WinEvent -FilterHashtable @{
    LogName   = $log
    StartTime = (Get-Date).Date
} | Where-Object {
    $_.Message -match 'Secure Document Viewer Update|Windows Health Telemetry'
} | Format-List TimeCreated,Id,Message

Что мы получили

Windows Health Telemetry запускает HealthCheck.ps1 — тот самый скрипт из каталога службы, который стучит на 192.168.100.11:8080. То есть есть два независимых механизма: служба и задача.

Secure Document Viewer Update запускает другой скрипт, из профиля a.sokolova. Его мы раньше не видели. Мы зафиксировали время его создания, хэш и содержимое. Он тоже шлет пакеты на обнаруженный в начале адрес.

В событии 129 журнала планировщика есть PID запущенного процесса. Это единственное место, где задача планировщика связывается с конкретным процессом, а значит — с событиями 4688 в журнале Security.

Командная строка у задач одинаковая, и в ней четыре характерных признака:

-WindowStyle Hidden — окно PowerShell не отображается;

-ExecutionPolicy Bypass — обход политики выполнения скриптов;

-NoProfile — не грузить профиль, чтобы ничего не сломало запуск;

-File с путём в каталоге, доступном на запись.

Сочетание Hidden + Bypass очень хорошая связка для корреляционного правила SIEM при создании задачи планировщика.

Шаг 8. Автозапуск

Для быстрого изучения точек автозапуска через реестр (и не только) можно использовать Autorunsc, уже применявшуюся ранее. Кстати, мы здесь используем вариант утилиты для командной строки, но есть и вариант с GUI.

C:\Kit\SysinternalsSuite\Autorunsc64.exe `
    -accepteula -a * -m -h

При параметре -a * утилита проверит вообще все возможные точки автозапуска, так что в выводе может оказаться и то, что мы уже видели раньше: службы и планировщик. Параметр -m сократит вывод, отсеив по подписи все то, что относится к Microsoft, но все равно может получиться много. -h добавляет хэши к найденному.

Для перепроверки, или есть autorunsc нет, ниже проверяем вручную.

Параметры автоматического запуска программ при входе пользователя или старте системы находятся в ветках Run и RunOnce. Причем эти ветки находятся как в HKLM (для всех пользователей системы), так и в HKCU (для текущего пользователя) и в HKEY_USERS. Необходимо проверить все эти места.

Ключи автозапуска для текущего пользователя

reg.exe query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run"
reg.exe query "HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce"

Ключи автозапуска для других пользователей

Они лежат в HKEY_USERS под своими SID. Соответственно, там надо связать SID с каждым пользователем, в первую очередь с тем, кто, предположительно, запустил вредоносную нагрузку. Но с анализируемой машины это сделать нельзя, она изолирована.

Команда

(Get-ADUser a.sokolova).SID.Value

возвращает ошибку по причине того, что не может достучаться до AD – сервер в изоляции.

Поэтому можно использовать команду

Get-CimInstance Win32_UserProfile | Select-Object LocalPath,SID,Loaded

Она отработает и локально.

Далее выполняем команды с этим SID. Важно, чтобы Loaded был в статусе True — куст доступен, только когда загружен, то есть пока пользователь в системе. У нашей a.sokolova сеанс висит – то есть он существует, юзер в системе, просто в дисконнекте. Если пользователь вышел, то куст выгрузится, и придется читать NTUSER.dat с диска.

reg.exe query "HKU\S-1-5-21-3589890344-2565197468-317303098-1113\Software\Microsoft\Windows\CurrentVersion\Run"
reg.exe query "HKU\S-1-5-21-3589890344-2565197468-317303098-1113\Software\Microsoft\Windows\CurrentVersion\RunOnce"

Ключи автозапуска для всех пользователей

reg.exe query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run"
reg.exe query "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce"

В нашем случае помимо легитимных Vboxtray есть еще два механизма закрепления:

-       в Run скомпрометированного пользователя, который запускает скрипт UpdateCheck.ps1 — тот же, что и задача Secure Document Viewer. Он будет выполняться при каждом входе пользователя в систему.

-       В RunOnce HKLM, запускающий HealthCheck.ps1 – мы тоже видели его раньше.

RunOnce отличается от Run тем, что значение удаляется после срабатывания.

Ключи WOW6432Node

Эти ключи предназначены для параметров 32-битных программ, работающих в 64-битной версии Windows.

reg.exe query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run"
reg.exe query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce"

Ключи Winlogon

Еще один механизм автозапуска в Windows, срабатывающий на этапе инициализации пользовательской сессии. Необходимо проверить ключи Shell (должно быть значение explorer.exe) и Userinit (C:\Windows\system32\userinit.exe,).

reg.exe query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Shell

reg.exe query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Userinit

reg.exe query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify"
reg.exe query "HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify"

В ветке Winlogon для пользователя не должно быть подозрительных параметров.

reg.exe query "HKU\S-1-5-21-3589890344-2565197468-317303098-1113\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"

BootExecute

Должно быть значение autocheck autochk * — проверка диска, которая выполняется до старта Windows.

reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager" /v BootExecute

Папки автозагрузки

Для всех пользователей

Get-ChildItem 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup' -Force

И для конкретного. В нашем случае проверяем скомпрометированную УЗ

Get-ChildItem 'C:\Users\a.sokolova\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' -Force
И здесь же я зафиксировал артефакты в папке SecureDocumentViewer, потому что вспомнил, что не сделал этого раньше.

И здесь же я зафиксировал артефакты в папке SecureDocumentViewer, потому что вспомнил, что не сделал этого раньше.

Шаг 9. Пользователи и группы

Мы уже проверяли профили пользователей и текущие сеансы выше. Помимо этого, было бы полезно зафиксировать, не создал ли атакующий нового пользователя, не включил ли отключённую запись и не добавил ли существующую запись в привилегированную группу.

Локальные учетные записи

Get-LocalUser |
     Select-Object Name,Enabled,LastLogon,PasswordLastSet,SID

Группа локальных админов

$adminGroup = Get-LocalGroup -SID 'S-1-5-32-544'
Get-LocalGroupMember -Group $adminGroup |
    Select-Object Name,ObjectClass,PrincipalSource

В зависимости от локали имя группы может быть и на английском, поэтому надежнее обращаться по SID – он всегда одинаковый.

Пользователи удаленного рабочего стола

Поскольку это терминалка, эта группа очень важна, она определяет, кто может логиниться по RDP.

$rdpGroup = Get-LocalGroup -SID 'S-1-5-32-555'
Get-LocalGroupMember -Group $rdpGroup |
    Select-Object Name,ObjectClass,PrincipalSource

В условиях домена здесь будут доменные учетки или группы пользователей. При необходимости, их свойства проверяются с чистой админской машины.

Шаг 10. Журналы

Пришло время, наконец, вдумчиво смотреть логи. Во время расследования сразу садиться за просмотр логов непродуктивно. Первейшая задача – это сдерживание угрозы через изоляцию, затем фиксация более волатильных данных. Логи от нас (скорее всего) не убегут, и даже если локальные журналы будут очищены, события можно будет найти в SIEM. Если садиться смотреть логи сразу, то мы закопаемся в них с головой, потому что тысячи их, а в контекст мы не погружены, то есть не знаем, что искать.

Сейчас у нас уже есть представление, что искать в логах. Мы вообще знаем уже немало:

Промежуточный список находок

  • Во время начала расследования на RDS была открыта сессия a.sokolova, время входа: 25 августа 2026 00:11

  • Подтверждены обращения RDS01 на условный вредоносный адрес 192.168.100.11 8080

  • Зафиксирован процесс вредоносной службы WindowsHealthMonitor.exe с датой создания 25 августа 2026 00:21:36

  • Служба запускается с правами системы

  • Исполняемый файл службы находится по пути C:\ProgramData\WindowsHealthMonitor\

  • Цифровая подпись отсутствует, хэш и размер зафиксирован

  • Анализ строк файла WindowsHealthMonitor.exe выявил упоминании метода POST и адрес 192.168.100.11:8080/beacon

  • В той же директории C:\ProgramData\WindowsHealthMonitor\ найден скрипт HealthCheck.ps1 с той же датой создания - 25 августа 2026 00:21:36. В теле скрипта находится команда HTTP POST к 192.168.100.11 8080

  • Служба WindowsHealthMonitor создана 25 августа 2026 00:21:36 (событие 7045)

  • Найдена задача планировщика Secure Document Viewer Update, запускающая скрипт C:\Users\a.sokolova\AppData\Roaming\SecureDocumentViewer\UpdateCheck.ps1. Файл задачи создан 25 августа 0:13, запускается каждые 15 минут скрыто.

  • Скрипт C:\Users\a.sokolova\AppData\Roaming\SecureDocumentViewer\UpdateCheck.ps1 создан в 25.08.2026 0:13:04. В теле скрипта также находится команда HTTP POST к 192.168.100.11 8080.

  • Задача планировщика Secure Document Viewer Update создана 25 августа 2026 00:13:05 из-под УЗ a.sokolova.

  • Найдена задача планировщика Windows Health Telemetry, запускающая скрипт C:\ProgramData\WindowsHealthMonitor\HealthCheck.ps1. Файл задачи создан 25 августа 0:21, запускается каждые 10 минут, скрыто, от системы.

  • Найдено значение в HKU\...\Run пользователя a.sokolova, запускающее C:\Users\a.sokolova\AppData\Roaming\SecureDocumentViewer\UpdateCheck.ps1

  • Найдено значение в HKLM\...\RunOnce, запускающее C:\ProgramData\WindowsHealthMonitor\HealthCheck.ps1

Таким образом, у нас есть некий контекст произошедшего. Мы видим сеанс a.sokolova, начавшийся приблизительно в 00:11, а основные подозрительные артефакты появились между 00:13 и 00:22. Существенная их часть напрямую связана с этой учетной записью. Начнём с журналов RDP, чтобы установить продолжительность этого пользовательского сеанса.

Проверка журнала LocalSessionManager/Operational

Журнал записывает события RDP-подключений. Из вывода команды quser мы знаем, во сколько начался сеанс пользователя a.sokolova. Проверим это по журналу и установим также время отключения. Будем искать события 21 (вход) и 24 (отключение).

Вот вход:

Перекрестная проверка в журнале Security это подтверждает — и дает нам ИД входа пользователя 0xD50143 (внизу, плохо поместился).

Вот отключение сеанса:

То есть он отключился в 00:37:36. В первую очередь мы будем искать события в этом временном интервале.

Поиск событий 4688 в заданном интервале

Скрытый текст

Если вы используете Sysmon, то вы с таким же успехом можете выполнить поиск по Event Id 1 событиям.

Задаем интервал с небольшим запасом.

$from = Get-Date '2026-08-25 00:00:00'
$to   = Get-Date '2026-08-25 00:38:00'

Для начала выполним поиск по событию безопасности 4688 – создание процесса, используя фильтр по ключевым словам.

Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4688
    StartTime = $from
    EndTime   = $to
} | Where-Object {
    $_.Message -match 'powershell|cmd.exe|csc.exe|sc.exe|Document_Viewer|SecureDocumentViewer|WindowsHealthMonitor'
} | Format-List TimeCreated,Message

И сразу видим картину событий.

Запуск вредоносной нагрузки от имени a.sokolova в 00:30:05.

Запуск вредоносной нагрузки от имени a.sokolova в 00:30:05.

Запуск процесса службы WindowsHealthMonitor в 00:21:36.

Запуск процесса службы WindowsHealthMonitor в 00:21:36.

Еще один запуск вредоносной нагрузки от имени a.sokolova в 00:15:13.

Еще один запуск вредоносной нагрузки от имени a.sokolova в 00:15:13.

Событие запуска ipconfig через powershell в 00:13:02

Событие запуска ipconfig через powershell в 00:13:02

Событие запуска файла .cmd из Проводника в 00:12:54. То есть, фактически, это означает, что файл был запущен самим пользователем двойным щелчком. Причем файл находится в папке «Загрузки», что намекает на маршрут, каким он попал на сервер.

Событие запуска файла .cmd из Проводника в 00:12:54. То есть, фактически, это означает, что файл был запущен самим пользователем двойным щелчком. Причем файл находится в папке «Загрузки», что намекает на маршрут, каким он попал на сервер.

Здесь мы видим, что рядом с cmd-скриптом лежал txt-файл, который был прочитан пользователем через Блокнот в 00:12:42.

Здесь мы видим, что рядом с cmd-скриптом лежал txt-файл, который был прочитан пользователем через Блокнот в 00:12:42.

Мы дошли до самого раннего подозрительного события. В 00:12:22 пользователь распаковал архив C:\Users\a.sokolova\Downloads\SecureDocumentViewer.zip, причем родительский процесс – браузер Edge, то есть файл получен через браузер. Браузер запустил WinRAR для открытия только что скачанного архива SecureDocumentViewer.zip из Downloads — это стандартное поведение, когда пользователь в Edge нажимает «Открыть файл» после загрузки, и система вызывает ассоциированное с .zip приложение — здесь это WinRAR.

До этого события нет запусков процессов, которые выглядят подозрительными.

Проверка журналов Powershell, System, Защитник Windows

События 4688 восстановили цепочку созданных процессов и их командные строки. В принципе, в нашем сценарии мы вышли на финишную прямую, причина заражения более-менее ясна.

В случаях, когда требуется дополнительная информация, можно начать с этих журналов:

Microsoft-Windows-PowerShell/Operational

Get-WinEvent -FilterHashtable @{
    LogName   = 'Microsoft-Windows-PowerShell/Operational'
    Id        = 4103,4104
    StartTime = $from
    EndTime   = $to
} | Format-List TimeCreated,Id,Message

4103 — выполнение команд модулей PowerShell;

4104 — содержимое выполненных блоков сценария.

Информативность журнала зависит от включения Script Block Logging и Module Logging, в моменте можно проверить так:

reg.exe query "HKLM\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
reg.exe query "HKLM\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging"

Классический журнал Windows PowerShell

Get-WinEvent -FilterHashtable @{
    LogName   = 'Windows PowerShell'
    Id        = 400,403,600,800
    StartTime = $from
    EndTime   = $to
} | Format-List TimeCreated,Id,Message

400 — запуск движка (сессии) PowerShell;

403 — остановка и завершение работы движка PowerShell;

600 — инициализация и запуск системных провайдеров (FileSystem, Registry и др.);

800 — детали выполнения команд и конвейеров (Pipeline).

Пример отображения в GUI

Пример отображения в GUI

Системный журнал

Мы уже пользовались поиском по System журналу выше, с его помощью мы узнали точное время установки вредоносной службы.

Get-WinEvent -FilterHashtable @{
    LogName      = 'System'
    ProviderName = 'Service Control Manager'
    Id           = 7036,7040,7045
    StartTime    = $from
    EndTime      = $to
} | Format-List TimeCreated,Id,Message

Событие 7045 подтвердило установку службы WindowsHealthMonitor в 00:21:36, а событие 7036 — её переход в состояние «Работает» в 00:21:37. Эти данные согласуются с событиями 4688, в которых одновременно видны WindowsHealthMonitor.exe и его запуск процессом services.exe.

Журнал защитного решения

Для того, чтобы понять, как вел себя AV на системе в момент событий. Не столь важно, что именно стоит на машине, какие-то логи должны записываться. Вот команда для просмотра событий Defender:

Get-WinEvent -FilterHashtable @{
    LogName   = 'Microsoft-Windows-Windows Defender/Operational'
    StartTime = $from
    EndTime   = $to
} | Where-Object {
    $_.Id -in 1000,1001,1116,1117,1118,1119
} | Format-List TimeCreated,Id,Message

1000 — запуск сканирования (антивирусной проверки);

1001 — успешное завершение сканирования;

1116 — обнаружение угрозы (вредоносного или потенциально нежелательного ПО);

1117 — успешное выполнение действия по обработке угрозы (удаление, карантин, лечение).

1118 — сбой при попытке обработки или устранения обнаруженной угрозы;

1119 — критический сбой при попытке исправления системы после удаления вредоносного ПО.

Полезность остальных журналов будет определяться характером инцидента. Например, если исходный алерт указывает на WMI, к набору добавляется Microsoft-Windows-WMI-Activity/Operational с событиями 5857–5861.

Действия с пользователями

Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4720,4722,4723,4724,4725,4726,4728,4732,4756
} | Format-List TimeCreated,Id,Message

Команда находит и выводит информацию о создании, изменении, блокировке и удалении учетных записей пользователей, а также добавлении в группы.

Заключение третьей части

Мы разобрали, как искать закрепление там, где его чаще всего оставляют и реже всего проверяют вручную: в задачах планировщика (отсев служебных задач Microsoft, фильтр по действию, Autorunsc) и в ключах автозапуска реестра — Run, RunOnce, Winlogon, BootExecute, папки автозагрузки, — а также как проверять локальные учётные записи и группы на предмет новых или неожиданно расширенных прав. Отдельно разобрали, как журналы событий — 4688 в связке с журналом планировщика и RDP-сессий — восстанавливают точную хронологию действий по секундам, даже когда отдельные артефакты сами по себе неоднозначны. В демонстрационной лабе эта методика свела все найденные ранее следы в единую и непротиворечивую картину атаки. Осталось закрепить находки как улики: собрать артефакты для офлайн-анализа, установить источник заражения и оформить итоговый таймлайн и IOC — этим займёмся в заключительной части.

Предыдущие части: первая, вторая.

НЛО прилетело и оставило здесь промокод для читателей нашего блога:
-15% на заказ нового VDS — HABRFIRSTVDS.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.