Скрипт remuda , отредактированный kevinmicke (7 февраля в 21:59), не проверял канал управления FTP, который имеет собственную папку в моей системе (Windows Server 2008 R2). Также 530 11001
не были распознаны события, которые появляются, когда хакер пытается получить доступ только к каналу управления. Поэтому я добавил несколько строк в скрипт, чтобы проверить вторую папку FTP-log:
# Этот скрипт Windows Powershell автоматически блокирует IP-адреса, которые пытаются войти в систему
# и потерпеть неудачу в количестве, указанном ниже с переменной $ int_block_limit или более. Сканирует как Совет
# log, который охватывает Remote Desktop и другие попытки, а также журнал FTP текущего дня. Если $ int_block_limit
Ограничение # достигнуто в любом из этих журналов (отдельно, а не вместе), тогда IP-адрес будет добавлен к
# правило брандмауэра.
#
# Сценарий автоматически создаст правило брандмауэра с именем «BlockAttackers (Создано гггг-мм-дд ЧЧ: мм: сс UTC)», используя
# текущее время, если имя с именем «BlockAttackers» еще не существует. Потому что там трудно
# ограничение в 1000 записей (IP-адресов), которое вы можете заблокировать для каждого правила, оно также создаст правила с одинаковыми именами, как только
# предел достигнут для самого последнего.
#
# Рекомендую настроить запуск сценария как запланированной задачи, вызванной сбоем аудита входа в систему события 4625 из
# Журнал безопасности, или, в качестве альтернативы, вы можете настроить его запуск через некоторое время (т.е. каждые 10 минут).
#
# Авторы:
# Большинство сценариев написано пользователем serverfault.com kevinmicke
# Часть журнала безопасности Windows, написанная пользователем remunda serverfault.com, которая послужила отправной точкой для kevinmicke
# Проверка канала управления FTP добавлена пользователем serverfault.com Уве Мартенсом
#
# Подробности: https://serverfault.com/questions/233222/ban-ip-address-based-on-x-number-of-unsuccessful-login-attempts
# Установить количество неудачных попыток входа в систему, после чего IP-адрес будет заблокирован
$ int_block_limit = 3
# Временное окно, в течение которого проверяется журнал безопасности, который в настоящее время настроен на проверку только за последние 24 часа
$ dat_time_window = [DateTime] :: Now.AddDays (-1)
# Выберите из журнала безопасности все IP-адреса, которые имеют более чем $ int_block_limit сбоев аудита (событие 4625) в пределах $ dat_time_window
$ arr_new_bad_ips_security_log = @ ()
$ arr_new_bad_ips_security_log = Get-EventLog -LogName 'Security' -InstanceId 4625 -After $ dat_time_window |
Select-Object @ {n = 'IpAddress'; e = {$ _. ReplacementStrings [-2]}} |
Групповой объект -свойство IpAddress |
Где {$ _. Count -ge $ int_block_limit} |
Выберите имя свойства
# Получить текущее время UTC, чтобы выяснить имя файла для текущего журнала FTP
$ current_date_utc = (Get-Date) .ToUniversalTime ()
# Установить путь к текущему файлу журнала канала управления FTP
$ str_log_file_name_control_channel = "C: \ inetpub \ logs \ LogFiles \ FTPSVC \ u_ex" + $ current_date_utc.ToString ("yyMMdd") + ".log"
# Найдите в сегодняшнем файле журнала FTP Control Channel значение «530 1», чтобы найти строки, содержащие IP-адреса систем, которые не смогли войти в систему,
# получить только IP-адрес из каждой строки, сгруппировать IP-адреса по IP, чтобы подсчитать количество попыток для каждой из них, и выбрать только
# IP-адреса, которые имеют $ int_block_limit или более неудачных входов в систему сегодня
$ arr_new_bad_ips_ftp_control_channel = @ ()
$ arr_new_bad_ips_ftp_control_channel = строка выбора $ str_log_file_name_control_channel -pattern "530 1" |
ForEach-Object {$ _. Line.Substring (20,15) -replace ". *", ""} |
Группа |
Где {$ _. Count -ge $ int_block_limit} |
Выберите имя свойства
# Установить путь к текущему файлу журнала FTP
$ str_log_file_name = "C: \ inetpub \ logs \ LogFiles \ FTPSVC * \ u_ex" + $ current_date_utc.ToString ("yyMMdd") + ".log"
# Найдите в сегодняшнем файле журнала FTP «530 1», чтобы найти строки, содержащие IP-адреса систем, которые не смогли войти в систему,
# получить только IP-адрес из каждой строки, сгруппировать IP-адреса по IP, чтобы подсчитать количество попыток для каждой из них, и выбрать только
# IP-адреса, которые имеют $ int_block_limit или более неудачных входов в систему сегодня
# В FTPSVC * необходимо добавить идентификатор FTP-сервера вместо * или просто взять нужную лог-папку
$ arr_new_bad_ips_ftp = @ ()
$ arr_new_bad_ips_ftp = Select-String $ str_log_file_name -pattern "530 1" |
ForEach-Object {$ _. Line.Substring (20,15) -replace ". *", ""} |
Группа |
Где {$ _. Count -ge $ int_block_limit} |
Выберите имя свойства
# Объединить два массива IP-адресов (один из журнала безопасности, один из журнала FTP)
$ arr_new_bad_ips_all = @ ()
# $ arr_new_bad_ips_all = @ ($ arr_new_bad_ips_security_log) + @ ($ arr_new_bad_ips_ftp_over_limit)
$ arr_new_bad_ips_all = @ ($ arr_new_bad_ips_security_log) + @ ($ arr_new_bad_ips_ftp_control_channel) + @ ($ arr_new_bad_ips_ftp)
# Сортируйте массив, выбирая только уникальные IP-адреса (если один IP-адрес отображается в журналах безопасности и FTP)
$ arr_new_bad_ips_all_sorted = @ ()
$ arr_new_bad_ips_all_sorted = $ arr_new_bad_ips_all |
Foreach-Object {[string] $ _. Name} |
Select-Object - уникальный
# Получить объект брандмауэра
$ firewall = New-Object -comobject hnetcfg.fwpolicy2
# Получить все правила брандмауэра, соответствующие "BlockAttackers *"
$ arr_firewall_rules = $ firewall.Rules | Где {$ _. Имя-как 'BlockAttackers *'}
# Если правила брандмауэра "BlockAttackers *" еще не существует, создайте его и установите для него переменную
if ($ arr_firewall_rules -eq $ null) {
$ str_new_rule_name = "BlockAttackers (Created" + $ current_date_utc.ToString ("гггг-мм-дд ЧЧ: мм: сс") + "UTC)"
netsh advfirewall firewall добавить правило dir = в действии = имя блока = $ str_new_rule_name description = "Правило создано автоматически." enable = yes remoteip = "0.0.0.0" | Из-Null
$ arr_firewall_rules = $ firewall.Rules | Где {$ _. Имя-как 'BlockAttackers *'}
}
# Разделить существующие IP-адреса из текущих правил брандмауэра "BlockAttackers *" в массив, чтобы мы могли легко найти их
$ arr_existing_bad_ips = @ ()
foreach ($ rule в $ arr_firewall_rules) {
$ arr_existing_bad_ips + = $ rule.RemoteAddresses -split (',')
}
# Очистить маски подсети от IP-адресов, которые в настоящее время заблокированы правилом брандмауэра
$ arr_existing_bad_ips_without_masks = @ ()
$ arr_existing_bad_ips_without_masks = $ arr_existing_bad_ips | ForEach-Object {$ _ -replace "/.*", ""}
# Введите IP-адрес вашего сервера (IPv4 и IPv6) в строках 115 и 116.
# Выберите IP-адреса для добавления в брандмауэр, но только те, которые ...
$ arr_new_bad_ips_for_firewall = @ ()
$ arr_new_bad_ips_for_firewall = $ arr_new_bad_ips_all_sorted | Где {
# содержат IP-адрес (т. е. не являются пустыми или тире, которые есть в журнале безопасности для систем, которые не прошли FTP-вход)
$ _. Длина -gt 6 -и
# еще не включены в правила брандмауэра
! ($ arr_existing_bad_ips_without_masks - содержит $ _) - и
# не являются локальной петлей
! ($ _. StartsWith ('127.0.0.1')) -и
# не являются частью локальной подсети
! ($ _. StartsWith ('192.168.')) -И
! ($ _. StartsWith ('0.0.')) -И
! ($ _. StartsWith ('10 .0. ')) -И
! ($ _. StartsWith ('*. *. *. *')) -И
! ($ _ StartsWith (. *: *: *: *: *: * '))
}
# Если есть блокируемые IP-адреса, сделайте следующее ...
if ($ arr_new_bad_ips_for_firewall -ne $ null) {
# Записать дату и время в лог-файл конкретного скрипта
[DateTime] :: Сейчас | Out-File -Append -Encoding utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
# Записать недавно заблокированные IP-адреса в файл журнала
$ arr_new_bad_ips_for_firewall | Out-File -Append -Encoding utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
# Boolean, чтобы убедиться, что новые IP-адреса добавляются только в одно правило
$ bln_added_to_rule = 0
# Массив для хранения плохих IP-адресов из каждого правила по одному, поэтому мы можем рассчитывать, чтобы добавление новых IP-адресов не превышало 1000 IP-адресов.
$ arr_existing_bad_ips_current_rule = @ ()
# Для каждого правила «BlockAttackers *» в брандмауэре выполните следующие действия ...
foreach ($ rule в $ arr_firewall_rules) {
if ($ bln_added_to_rule -ne 1) {
# Разделить существующие IP-адреса из текущего правила в массив, чтобы мы могли легко их посчитать
$ arr_existing_bad_ips_current_rule = $ rule.RemoteAddresses -split (',')
# Если количество добавляемых IP-адресов меньше 1000 минус текущее количество IP-адресов в правиле, добавьте их в это правило
if ($ arr_new_bad_ips_for_firewall.Count -le (1000 - $ arr_existing_bad_ips_current_rule.Count)) {
# Добавить новые IP-адреса в правило брандмауэра
$ arr_new_bad_ips_for_firewall | % {$ rule.RemoteAddresses + = ',' + $ _}
# Напишите, к какому правилу были добавлены IP-адреса в лог-файл
echo "Новые IP-адреса, добавленные выше к правилу брандмауэра Windows:" $ rule.Name | Out-File -Append -Encoding utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
# Установите логическое значение, чтобы при добавлении IP-адресов любые другие правила были пропущены.
$ bln_added_to_rule = 1
}
}
}
# Если в другом правиле брандмауэра «BlockAttackers *» не было места, создайте новое и добавьте в него IP-адреса.
if ($ bln_added_to_rule -ne 1) {
$ str_new_rule_name = "BlockAttackers (Created" + $ current_date_utc.ToString ("гггг-мм-дд ЧЧ: мм: сс") + "UTC)"
netsh advfirewall firewall добавить правило dir = в действии = имя блока = $ str_new_rule_name description = "Правило создано автоматически." enable = yes remoteip = "0.0.0.0" | Из-Null
$ new_rule = $ firewall.rules | Где {$ _. Name -eq $ str_new_rule_name}
# Добавить новые IP-адреса в правило брандмауэра
$ arr_new_bad_ips_for_firewall | % {$ new_rule.RemoteAddresses + = ',' + $ _}
# Напишите, к какому правилу были добавлены IP-адреса в лог-файл
echo "Новые IP-адреса выше добавлены во вновь созданное правило брандмауэра Windows:" $ new_rule.Name | Out-File -Append -Encoding utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
}
}
Имя папки журнала FTP FTPSVC*
на строке 54 должно быть заполнено по причине. В строке 115 и 116 необходимо ввести IP-адрес вашего сервера (IPv4 и IPv6), в противном случае IP-адрес собственных серверов может быть добавлен в правило брандмауэра сто раз. У $int_block_limit
меня на сервере установлена переменная 1, поэтому скрипт блокирует атаку хакеров, вызывая событие 4625 в течение двух секунд. Я все еще думаю о запуске сценария в дополнение к происходящим 4625 событиям за период в несколько минут. Конечно, было бы также возможно разделить сценарии и позволить одному сценарию проверять события 4625, инициированные событием 4625, а другому - журналы папок FTP, периодически проверяющие каждые 5 или 10 минут, даже с отдельным правилом межсетевого экрана. и лог-файл.