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

Перед тем как начать писать скрипт формирования и отправки уведомления вам необходимо убедиться в 2-х вещах:

  1. На целевом сервере/компьютере настроена политика аудита блокировки учетных записей, неудачного входа в учетную запись (События 4740,4771,4625 в журнале Security ) и желательно аудит NTLM трафика(Событие 8004 в журнале Microsoft-Windows-NTLM/Operational)

  2. В создали бота в ТГ при помощи https://telegram.me/BotFather, получили его токен, добавили в необходимый чат, и при помощи например https://www.t.me/username_to_id_bot узнали ID чата

Для решения 1-й задачи необходимо отредактировать политики целевого компьютера/групп компьютеров(Например контроллеров домена) следующим образом:

Для событий 4740,4771,4625: Перейти в редакторе групповой политики в раздел

Конфигурация компьютера\Политики\Конфигурация Windows\Параметры безопасности\Конфигурация расширенного аудита\

или

Computer Configuration\Policies\Windows settings\security settings\Advanced Audit Policy Configuration\

4625:
В подразделе Вход/выход или Logon/Logoff

Аудит блокировки учетных записей

Успех, отказ

Audit Account Lockout

Success, Failure

Аудит входа в систему

Успех, отказ

Audit Logon

Success, Failure

4771: В подразделе Вход учетной записи или Account Logon

Аудит службы проверки подлинности Kerberos

Успех, отказ

Audit Kerberos Authentication Service

Success, Failure

4740: В подразделе Управление учетными записями или Account Management

Аудит управления учетными записями пользователей

Успех

Audit User Account Management

Success

Для событий 8004: Перейти в редакторе групповой политики в раздел

Конфигурация компьютера\Политики\Конфигурация Windows\Параметры безопасности\Локальные политики\Параметры безопасности или Computer Configuration\Policies\Windows settings\security settings\Local Policies \Security Options

Сетевая безопасность: ограничения NTLM: исходящий трафик NTLM к удаленным серверам

Аудит всего

Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers

Audit all

Сетевая безопасность: ограничения NTLM: аудит проверки подлинности NTLM в этом домене

Включить все

Network security: Restrict NTLM: Audit NTLM authentication in this domain

Enable all

Сетевая безопасность: ограничения NTLM: аудит входящего трафика NTLM

Включить аудит для всех учетных записей

Network security: Restrict NTLM: Audit Incoming NTLM Traffic

Enable auditing for all accounts

О решении 2-й задачи в интернете и так достаточно статей(Например Эта), потому процесс описывать не стану.

Итак, подготовительный процесс пройден, следущий этап - создать скрипт, который ищет лог с идентификатором 4740(Блокировка учетной записи) забирает из него необходимые данные, далее с этими данными ищет подходящие логи с событиями 4625 или 4771(События входа) и 8004(NTLM Аутентификация).

Напишем такой скрипт, назовем его, например send_tg_event_userblock.ps1

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$tg_token="Ваш Токен TG"
$tg_chat_id="Ваш ID Чата"

$event= Get-WinEvent -MaxEvents 1 -FilterHashtable @{
    LogName = 'Security'
    ID = 4740
}



if($event.Id -eq 4740){
    $event_host=$event.MachineName
    $banned_login=([xml]$event.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”} | %{$_."#text"}
    $from_machine=([xml]$event.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetDomainName”} | %{$_."#text"}
    $event_time=$event.TimeCreated
    $sid = ([xml]$event.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetSid”} | %{$_."#text"}
    $objSID = New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList $sid
    $banned_fullusername = $objSID.Translate([System.Security.Principal.NTAccount]).Value

    $Message = "⚠ Пользователь Windows заблокирован!`n
Код события: 4740`n
Имя пользователя: $banned_fullusername `n
Имя вызывающего компьютера: $from_machine `n
Имя компьютера на котором прочитано событие: $event_host"

    $event2=Get-WinEvent -MaxEvents 1 -FilterHashtable @{
        LogName = 'Security'
        StartTime=$event_time.AddMinutes(-1)
        data = $banned_login
        ID = 4625,4771
    }
    if($event2.Id -eq 4625 -or $event2.Id -eq 4771){
        $event2_id=$event2.Id
        $ip_adress=([xml]$event2.ToXml()).Event.EventData.Data | ? {$_.Name -eq “IpAddress”} | %{$_."#text"}
        if($event2_id -eq 4625){$Process=([xml]$event2.ToXml()).Event.EventData.Data | ? {$_.Name -eq “ProcessName”} | %{$_."#text"}}
        if($event2_id -eq 4771){$Process=([xml]$event2.ToXml()).Event.EventData.Data | ? {$_.Name -eq “ServiceName”} | %{$_."#text"}}
        $Message="$Message `n`n
Код события: $event2_id`n
IP адрес вызывающего: $ip_adress`n
Имя вызывающего процесса: $Process"
    }
        
        
    $event3= Get-WinEvent -MaxEvents 1 -FilterHashtable @{
        LogName = 'Microsoft-Windows-NTLM/Operational'
        data = $banned_login
        StartTime=$event_time.AddMinutes(-1)
        ID = 8004
    }


    if($event3.Id -eq 8004){
            
        $schanel_name=([xml]$event3.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SChannelName”} | %{$_."#text"}
        $workstation_name=([xml]$event3.ToXml()).Event.EventData.Data | ? {$_.Name -eq “WorkstationName”} | %{$_."#text"}
        $Message="$Message `n`n
Код события: 8004`n
Имя компьютера в который пытаются авторизироваться: $schanel_name`n
Имя вызывающего компьютера: $workstation_name"
    }
    $Message="$Message `n`n`n$event_time"
    #echo $Message
    $Response = Invoke-RestMethod -Uri "https://api.telegram.org/bot$($tg_token)/sendMessage?chat_id=$($tg_chat_id)&text=$($Message)"
    exit 0
}else{exit 1}

Далее нам нужно поместить данный скрипт в удобное для исполнения место.
Можно руками закинуть его на машины по нестандартному пути, или распространить файл при помощи групповой политики в разделе
Конфигурация компьютера\Настройка\Конфигурация Windows\Файлы
или
Computer Configuration\Preferences\Windows Settings\Files

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

Последним шагом будет создание задачи в планировщике заданий
Опять же создать задачу можно как руками, так и распространить при помощи групповой политики в разделе
Конфигурация компьютера\Настройка\Параметры панели управления\Назначенные задания
или
Computer Configuration\Preferences\Control panel settings\Scheduled tasks

Я расскажу как распространить задачу при помощи групповой политики, вручную настройки такие же

Переходим в редактор групповых политик в раздел указанный выше и нажминаем создать>запланированное задание или create>scheduled task

Вкладка ОбщиеВыберете пользователя System и запуск с наивысшими правами
Вкладка Общие
Выберете пользователя System и запуск с наивысшими правами
Вкладка создания триггераНужно выбрать триггер по событиюНастраеваемый триггер > Изменить фильтр событий...
Вкладка создания триггера
Нужно выбрать триггер по событию
Настраеваемый триггер > Изменить фильтр событий...
<QueryList><Query Id="0" Path="Security"><Select Path="Security">*[System[ EventID=4740]]</Select></Query></QueryList>
Вкладка ДействияСоздать...Запуск программы > powershell.exe  -executionpolicy bypass -File "<Путь до скрипта>"
Вкладка Действия
Создать...
Запуск программы > powershell.exe -executionpolicy bypass -File "<Путь до скрипта>"
Вкладка Условия
Вкладка Условия
Вкладка Параметры
Вкладка Параметры

Все готово для тестрирования, можете проверить отправку при помощи WinRM,RDP,RPC,runas и т.д.

Комментарии (5)


  1. lioncub
    21.11.2024 06:11

    Следующий этап: собираем логи в loki, смотрим в grafana и настраиваем alertmanager.


  1. zKeeper
    21.11.2024 06:11

    Вероятно, стоит разрешить выполнять не подписанные скрипты: Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy Bypass –Force


    1. Cond3nz Автор
      21.11.2024 06:11

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


  1. bazanovv
    21.11.2024 06:11

    Как вариант, если компьютеры доверяют друг другу (домен), можно настроить отправку всех, или только нужных событий по фильтру на сервер-сборщик в отдельный лог, называется это Windows Event Forwarding. И уже на нём запускать скрипт, отправляющий уведомления. Минус - единая точка отказа, плюс - удобство и доступ в интернет нужен только на этом коллекторе.


    1. Cond3nz Автор
      21.11.2024 06:11

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