禁止基于X次login尝试失败的IP地址?

经过多次不成功的Windows Serverlogin尝试后,是否可以禁止使用IP地址? 不是特定的帐户,我知道该怎么做,而是整个机器。

我们被暴力攻击试图猜测用户名所困扰,所以这真的有助于从服务器上获得一些负载。

    你可以用PowerShell和任务pipe理器来做到这一点。 这可能不是完美的解决scheme,但它工作得很好,我在两个月内有大约100个阻塞的IP地址。 我写了脚本,从EventLog指定事件中select(“audit failure”)。 如果来自任何IP地址的login失败次数很多,则将其添加到名为“BlockAttackers”的防火墙规则(手动创build)中,该规则阻止任何通信到指定的IP地址。

    PS1脚本:

    $DT = [DateTime]::Now.AddDays(-1) # check only last 24 hours $l = Get-EventLog -LogName 'Security' -InstanceId 4625 -After $DT | Select-Object @{n='IpAddress';e={$_.ReplacementStrings[-2]} } # select Ip addresses that has audit failure $g = $l | group-object -property IpAddress | where {$_.Count -gt 20} | Select -property Name # get ip adresses, that have more than 20 wrong logins $fw = New-Object -ComObject hnetcfg.fwpolicy2 # get firewall object $ar = $fw.rules | where {$_.name -eq 'BlockAttackers'} # get firewall rule named 'BlockAttackers' (must be created manually) $arRemote = $ar.RemoteAddresses -split(',') #split the existing IPs into an array so we can easily search for existing IPs $w = $g | where {$_.Name.Length -gt 1 -and !($arRemote -contains $_.Name + '/255.255.255.255') } # get ip addresses that are not already in firewal rule. Include the subnet mask which is automatically added to the firewall remote IP declaration. $w| %{$ar.remoteaddresses += ',' + $_.Name} # add IPs to firewall rule 

    在调度程序中创build任务并将触发器设置为事件4625(包括terminal服务的Windowslogin)。 但是您可以设置触发器,例如每小时运行两次以避免不必要的加载服务器。

    调度程序触发器

    并在触发后运行powershell脚本。 您还必须设置更高的权限才能运行此脚本,否则将失败并出现安全性exception。

    运行PowerShell脚本

    您还可以将此脚本绑定到其他安全事件。

    我知道这个问题是古老的,但实际上,这是我几周前开始尝试做同样的事情时偶然发现的第一篇论坛post。 我已经想出了一个工作脚本,它将在24小时内parsing事件日志,只logging不良的login事件日志条目,抓取具有10个以上不良login名的事件日志,然后将它们放入一个ipsecfilter列表中netsh命令。 然后,我用这行powershell .\*scriptname.ps1*写了一个batch filepowershell .\*scriptname.ps1*并创build了一个计划任务,每24小时运行一次batch file(由于某种原因,它不会直接执行)。

     $DATE = [DateTime]::Now.AddDays(-1) $EVS = Get-EventLog Security -InstanceId 529 -after $DATE $EVS | select-string -inputobject {$_.message} -pattern "Source Network Address:(.)*\.*\.*\.*" -allmatches | foreach-object {$_.Matches} | foreach-object {$_.Value} | foreach-object {$_.replace("Source Network Address:", "")} | group-object -property $_ | where-object {$_.count -gt 10} | select-object -property name | format-list | out-file c:\rdpblock.txt get-content -path c:\rdpblock.txt | foreach-object {$_.replace("Name :", "")} | out-file c:\rdpblockcleaned.txt get-content -path c:\rdpblockcleaned.txt | select-object -unique | out-file c:\rdpblocknospaces.txt $RDPIP = get-content -path c:\rdpblocknospaces.txt | select-object -skip 1 $RDPIP | foreach-object {$_.replace(" ", "")} | foreach-object {netsh ipsec static add filter filterlist=RDP_BLOCK srcaddr=$($_) dstaddr=any} 

    我知道这个脚本可能是低效率的,但是当我开始研究这个时,我完全没有使用PowerShell的经验,所以我优化脚本的能力并不理想。 然而,尽pipe这个事实,我想我会分享这个人谁可以使用它。

    我感谢Remunda给了我最初的想法,那张海报让我想起了使用PowerShellsearch事件日志的想法。

    这个脚本build立在remunda的答案,并稍微进一步https://serverfault.com/a/397637/155102它占“BlockAttackers”规则没有任何IPsinput(它返回一个“*”作为一个string)。 它还会向日志文件写入注释,通知您何时将IP添加到规则中。

    一个好的提示是创build阻止IP地址的“BlockAttackers”规则,但是首先禁用它。 然后,手动运行此脚本一次,以便可以使用应被阻止的实际IP地址填充“RemoteAddresses”字段。 看看这些IP地址,以确保没有添加关键任务,然后启用防火墙规则。 将此规则添加到您的防火墙中,如上所述。

    这个脚本的git

     #Checks for IP addresses that used incorrect password more than 10 times #within 24 hours and blocks them using a firewall rule 'BlockAttackers' #Check only last 24 hours $DT = [DateTime]::Now.AddHours(-24) #Select Ip addresses that has audit failure $l = Get-EventLog -LogName 'Security' -InstanceId 4625 -After $DT | Select-Object @{n='IpAddress';e={$_.ReplacementStrings[-2]} } #Get ip adresses, that have more than 10 wrong logins $g = $l | group-object -property IpAddress | where {$_.Count -gt 10} | Select -property Name #Get firewall object $fw = New-Object -ComObject hnetcfg.fwpolicy2 #Get firewall rule named 'BlockAttackers' (must be created manually) $ar = $fw.rules | where {$_.name -eq 'BlockAttackers'} #Split the existing IPs into an array so we can search it for existing IPs $arRemote = $ar.RemoteAddresses -split(',') #Only collect IPs that aren't already in the firewall rule $w = $g | where {$_.Name.Length -gt 1 -and !($arRemote -contains $_.Name + '/255.255.255.255') } #Add the new IPs to firewall rule $w| %{ if ($ar.RemoteAddresses -eq '*') { $ar.remoteaddresses = $_.Name }else{ $ar.remoteaddresses += ',' + $_.Name } } #Write to logfile if ($w.length -gt 1) { $w| %{(Get-Date).ToString() + ' ' + $_.Name >> '.\blocked.txt'} } 

    让其他人控制你的防火墙规则通常不是一个好主意。 这基本上是你要求在这里。

    这是一个古老的线程。 我在2014 – 2015年使用kevinmicke提供的脚本。 然后它停止工作。 所以我不得不稍微编辑一下,以便采用Windows Network Security身份validation,该身份validation不会在安全日志中保留IP地址。 另外,由于我没有正常的FTP运行,因为没有日志文件夹,导致错误,所以我删除了这个部分。 主要的变化是RDP事件的来源。

      $current_date_utc = (Get-Date).ToUniversalTime() # Set number of failed login attempts after which an IP address will be blocked $int_block_limit = 10 # Time window during which to check the Security log, which is currently set to check only the last 24 hours $dat_time_window = [DateTime]::Now.AddDays(-1) $arr_new_bad_ips_all = (get-winevent -filterhashtable @{ logname='Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational'; starttime=$dat_time_window; id=140 }).message | % { if ($_ -match "of (.+) failed") { $Matches[1] }} | Group-Object | Where {$_.Count -ge $int_block_limit} | Select -property Name # Sort the array, selecting only unique IPs (in case one IP shows up in both the Security and FTP logs) $arr_new_bad_ips_all = $arr_new_bad_ips_all | Foreach-Object { [string]$_.Name } | Select-Object -unique # Get firewall object $firewall = New-Object -comobject hnetcfg.fwpolicy2 # Get all firewall rules matching "BlockAttackers*" $arr_firewall_rules = $firewall.Rules | Where {$_.Name -like 'BlockAttackers*'} # If no "BlockAttackers*" firewall rule exists yet, create one and set it to a variable if ($arr_firewall_rules -eq $null) { $str_new_rule_name = "BlockAttackers (Created " + $current_date_utc.ToString("yyyy-MM-dd HH:mm:ss") + " UTC)" netsh advfirewall firewall add rule dir=in action=block name=$str_new_rule_name description="Rule automatically created." enable=yes remoteip="0.0.0.0" | Out-Null $arr_firewall_rules = $firewall.Rules | Where {$_.Name -like 'BlockAttackers*'} } # Split the existing IPs from current "BlockAttackers*" firewall rule(s) into an array so we can easily search them $arr_existing_bad_ips = @() foreach ($rule in $arr_firewall_rules) { $arr_existing_bad_ips += $rule.RemoteAddresses -split(',') } # Clean subnet masks off of IPs that are currently blocked by the firewall rule(s) $arr_existing_bad_ips_without_masks = $arr_existing_bad_ips | ForEach-Object {$_ -replace "/.*", ""} # Select IP addresses to add to the firewall, but only ones that... $arr_new_bad_ips_for_firewall = $arr_new_bad_ips_all | Where { # contain an IP address (ie aren't blank or a dash, which the Security log has for systems that failed FTP logins) $_.Length -gt 6 -and # aren't already in the firewall rule(s) !($arr_existing_bad_ips_without_masks -contains $_) -and # aren't the local loopback !($_.StartsWith('127.0.0.1')) -and # aren't part of the local subnet !($_.StartsWith('192.168.')) -and !($_.StartsWith('0.0.')) } # If there are IPs to block, do the following... if ($arr_new_bad_ips_for_firewall -ne $null) { # Write date and time to script-specific log file [DateTime]::Now | Out-File -Append -Encoding utf8 C:\Security\blockattackers.txt # Write newly-blocked IP addresses to log file $arr_new_bad_ips_for_firewall | Out-File -Append -Encoding utf8 C:\Security\blockattackers.txt # Boolean to make sure the new IPs are only added on one rule $bln_added_to_rule = 0 # Array to hold bad IPs from each rule one at a time, so we can count to make sure adding the new ones won't exceed 1000 IPs $arr_existing_bad_ips_current_rule = @() # For each "BlockAttackers*" rule in the firewall, do the following... foreach ($rule in $arr_firewall_rules) { if ($bln_added_to_rule -ne 1) { # Split the existing IPs from the current rule into an array so we can easily count them $arr_existing_bad_ips_current_rule = $rule.RemoteAddresses -split(',') # If the number of IPs to add is less than 1000 minus the current number of IPs in the rule, add them to this rule if ($arr_new_bad_ips_for_firewall.Count -le (1000 - $arr_existing_bad_ips_current_rule.Count)) { # Add new IPs to firewall rule $arr_new_bad_ips_for_firewall | %{$rule.RemoteAddresses += ',' + $_} # Write which rule the IPs were added to to log file echo "New IP addresses above added to Windows Firewall rule:" $rule.Name | Out-File -Append -Encoding utf8 C:\Security\blockattackers.txt # Set boolean so any other rules are skipped when adding IPs $bln_added_to_rule = 1 } } } # If there wasn't room in any other "BlockAttackers*" firewall rule, create a new one and add the IPs to it if ($bln_added_to_rule -ne 1) { $str_new_rule_name = "BlockAttackers (Created " + $current_date_utc.ToString("yyyy-MM-dd HH:mm:ss") + " UTC)" netsh advfirewall firewall add rule dir=in action=block name=$str_new_rule_name description="Rule automatically created." enable=yes remoteip="0.0.0.0" | Out-Null $new_rule = $firewall.rules | Where {$_.Name -eq $str_new_rule_name} # Add new IPs to firewall rule $arr_new_bad_ips_for_firewall | %{$new_rule.RemoteAddresses += ',' + $_} # Write which rule the IPs were added to to log file echo "New IP addresses above added to newly created Windows Firewall rule:" $new_rule.Name | Out-File -Append -Encoding utf8 C:\Security\blockattackers.txt } } 

    上述脚本将在Windows 2012上运行。如果您仍然在Windows 2008上使用具有networking访问级别身份validation的远程桌面,则可能需要执行以下操作。 Windows 2008在安全日志中没有IP地址,并且在Microsoft-Windows-RemoteDesktopServices-RdpCoreTS日志中似乎也没有。 所以我不得不实际使用2个日志 – 将安全日志中的事件与防火墙日志中端口3389的成功访问尝试进行匹配。 这是一个猜测工作,但它似乎在检测密码攻击。 这是收集侵犯知识产权的部分:

      $current_date_utc = (Get-Date).ToUniversalTime() # Set number of failed login attempts after which an IP address will be blocked $int_block_limit = 10 $dat_time_window = [DateTime]::Now.AddDays(-1) $logfn = (netsh advfirewall show allprofiles | Select-String Filename | select-object -unique | % { $_ -replace "%systemroot%",$env:systemroot }).substring(10).trimstart().trimend() $badevts = Get-EventLog -LogName 'Security' -InstanceId 4625 -After $dat_time_window | foreach-object { [datetime]$_.TimeWritten } | sort-object $fwlog = Select-String -Path $logfn -Pattern "ALLOW TCP" | % { if ($_ -match "(201.-..-..) (.+) ALLOW TCP (.+) (.+) (.+) 3389") { new-object psobject -property @{ dt = $Matches[1] + ' ' + $Matches[2] ip = $Matches[3] } } } $ipa = @() $j = 0 for ($i=0; $i -lt $fwlog.Count; $i++) { $conn = ([datetime]$fwlog[$i].dt).ticks while (($j -lt $badevts.Count) -and (($badevts[$j]).ticks -lt $conn)) { $j++ } if ($j -ge $badevts.Count) { break } if ((($badevts[$j]).ticks - $conn) -le 30000000) { $ipa += ,($fwlog[$i].ip) } } $arr_new_bad_ips_all = $ipa | Group-Object | Where {$_.Count -ge $int_block_limit} | Select -property Name 

    注意:不要忘记启用防火墙日志。 注2:我不是一个PowerShell的专家,所以如果一些大师可以纠正/改进我的代码将是很好的。

    我正在使用ts_block freeby。

    基本上,它是一个“VBScript程序,充当WMI事件接收器来接收由Windows响应无效的terminal服务login而logging的事件。

    似乎完美的工作,如果你需要修改它的脚本是简单的。 您可以让其尝试logging日志,然后根据允许的尝试次数进行禁止,并且/或者您可以硬编码您不想访问的login名。

    我被意外地加了两次相同的名字,服务进入无限循环,每1500ms重新启动一次,但是如果你使用vbs,很容易修复/ mod。

    我目前的设置只是一个重试,你被禁止2天,像“pipe理”“pipe理”“pipe理员”“客人”等login自动禁止。 应该直接更改为IP?

    有点让人上瘾,去看看哪些小动物一夜之间被禁止了…

    你的意思是login到服务器/域或login到服务器上运行的网站? 如果你的意思是login到服务器/域,那么答案是否定的。 Windows没有阻止基于login尝试失败的IP地址的概念,因为IP地址不是安全实体。 可能有第三方工具可以做到这一点,但我不知道任何,因为我从来没有看过它。

    如果有一个受到攻击的networking服务器,您可以安装dynamicIP限制扩展 。 如果这是对服务器的标准身份validation,那么您应该能够实现域和服务器隔离 ,这会将攻击的范围限制为join域的计算机,并且可以设置为仅允许您需要访问的系统服务器。 在Windows中,预防暴力攻击的方式是将帐户locking策略设置为10分钟,将错误的密码策略设置为3次 – 这意味着被攻击的帐户将在3次尝试后locking10分钟。 IP连接在Windows中默认是不可locking的。 (除此之外,我也很好奇每秒钟有多less次login尝试影响系统)

    http://nerderies.blogspot.co.at/2012/12/automatically-banning-ips-with-windows.html

    如果你想要的是一个开箱即用的解决scheme(安装&完成),你可以在这里find一个免费的工具,可能应该继续阅读:

    当前版本:1.2(.NET Framework 4.0 Client Profile) – > 下载当前版本的EvlWatcher(免费用于个人和商业用途)

    1.2中的新function(文档中有更多信息):

    • pipe理控制台
    • WCF服务模式
    • 黑名单
    • 自动移动到黑名单3次罢工后(默认)

    对于较旧的服务器(.NET Framework 2.0)

    – >下载EvlWatcher精简版(免费用于个人和商业用途)

    使用remunda伟大的脚本作为出发点,我添加了一个主要的东西丢失: 阻止失败的FTPloginIP地址 。 当有人无法通过FTPlogin时,Windows Server不会将IP地址logging到安全日志中,而是将“源networking地址”设置为破折号。 FTP是蛮力攻击的一个非常常见的攻击媒介,所以我在他的脚本中添加了扫描当天的FTP日志以进行多次login失败并阻止这些IP地址的function。

    更新2014年02月07日:当我做了一些调整,以处理所有我的旧FTP日志,我意识到,当他们有巨大的尝试次数(50,000+),它创build的arrays将是巨大的,使处理非常缓慢。 我已经重写了它,使得它在处理FTP日志时更有效率。

    我还发现,在一个Windows防火墙规则中有多less个IP可以有1000的任意硬限制。 由于这个限制,我需要它自动创build一个新的规则,当最新的一个填满。 现在这样做了,并且还创build了初始的防火墙规则(如果您不创build自己的规则),那么唯一的设置就是将其添加到计划程序中,以便在发生事件4625时运行。

    以下是在Windows Server 2008 R2和Windows 7上testing过的代码:

     # This Windows Powershell script will automatically block IP addresses that attempt to login to the system # and fail the number of times set below with the $int_block_limit variable or more. Is scans both the Security # log, which covers Remote Desktop and other attempts, as well as the current day's FTP log. If the $int_block_limit # limit is hit on either of those logs (separately, not combined), then the IP address will be added to the # firewall rule. # # The script will automatically create a firewall rule named "BlockAttackers (Created yyyy-MM-dd HH:mm:ss UTC)" using # the current time if one with a name that includes "BlockAttackers" doesn't already exist. Because there's a hard # limit of 1000 entries (IP addresses) you can block per rule, it will also create similarly-named rules once that # limit is reached for the latest one. # # I recommend setting the script to run as a scheduled task triggered by event 4625 login audit failures from the # Security log, or alternatively you could set it to run after some amount of time (ie every 10 minutes). # # Authors: # Majority of script written by serverfault.com user kevinmicke # Windows Security Log portion written by serverfault.com user remunda, which provided the starting point for kevinmicke # # Details: https://serverfault.com/questions/233222/ban-ip-address-based-on-x-number-of-unsuccessful-login-attempts # Set number of failed login attempts after which an IP address will be blocked $int_block_limit = 10 # Time window during which to check the Security log, which is currently set to check only the last 24 hours $dat_time_window = [DateTime]::Now.AddDays(-1) # Select from the Security log all IP addresses that have more than $int_block_limit audit failures (event 4625) within $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]}} | Group-Object -property IpAddress | Where {$_.Count -ge $int_block_limit} | Select -property Name # Get current time UTC to figure out filename for current FTP log $current_date_utc = (Get-Date).ToUniversalTime() # Set path to today's FTP log file $str_log_file_name = "C:\inetpub\logs\LogFiles\FTPSVC2\u_ex" + $current_date_utc.ToString("yyMMdd") + ".log" # Search today's FTP log file for "530 1326" to find lines that contain IPs of systems that failed to log in, # get just the IP from each line, group the IPs by IP to count the attempts from each one, and select only the # IPs that have $int_block_limit or more bad logins today $arr_new_bad_ips_ftp = @() $arr_new_bad_ips_ftp = Select-String $str_log_file_name -pattern "530 1326" | ForEach-Object {$_.Line.Substring(20,15) -replace " .*", ""} | Group | Where {$_.Count -ge $int_block_limit} | Select -property Name # Concatenate the two arrays of IPs (one from Security log, one from FTP log) $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) # Sort the array, selecting only unique IPs (in case one IP shows up in both the Security and FTP logs) $arr_new_bad_ips_all_sorted = @() $arr_new_bad_ips_all_sorted = $arr_new_bad_ips_all | Foreach-Object { [string]$_.Name } | Select-Object -unique # Get firewall object $firewall = New-Object -comobject hnetcfg.fwpolicy2 # Get all firewall rules matching "BlockAttackers*" $arr_firewall_rules = $firewall.Rules | Where {$_.Name -like 'BlockAttackers*'} # If no "BlockAttackers*" firewall rule exists yet, create one and set it to a variable if ($arr_firewall_rules -eq $null) { $str_new_rule_name = "BlockAttackers (Created " + $current_date_utc.ToString("yyyy-MM-dd HH:mm:ss") + " UTC)" netsh advfirewall firewall add rule dir=in action=block name=$str_new_rule_name description="Rule automatically created by BlockAttackers Powershell script written by Kevin Micke." enable=yes remoteip="0.0.0.0" | Out-Null $arr_firewall_rules = $firewall.Rules | Where {$_.Name -like 'BlockAttackers*'} } # Split the existing IPs from current "BlockAttackers*" firewall rule(s) into an array so we can easily search them $arr_existing_bad_ips = @() foreach ($rule in $arr_firewall_rules) { $arr_existing_bad_ips += $rule.RemoteAddresses -split(',') } # Clean subnet masks off of IPs that are currently blocked by the firewall rule(s) $arr_existing_bad_ips_without_masks = @() $arr_existing_bad_ips_without_masks = $arr_existing_bad_ips | ForEach-Object {$_ -replace "/.*", ""} # Select IP addresses to add to the firewall, but only ones that... $arr_new_bad_ips_for_firewall = @() $arr_new_bad_ips_for_firewall = $arr_new_bad_ips_all_sorted | Where { # contain an IP address (ie aren't blank or a dash, which the Security log has for systems that failed FTP logins) $_.Length -gt 6 -and # aren't already in the firewall rule(s) !($arr_existing_bad_ips_without_masks -contains $_) -and # aren't the local loopback !($_.StartsWith('127.0.0.1')) -and # aren't part of the local subnet !($_.StartsWith('192.168.')) -and !($_.StartsWith('10.0.')) } # If there are IPs to block, do the following... if ($arr_new_bad_ips_for_firewall -ne $null) { # Write date and time to script-specific log file [DateTime]::Now | Out-File -Append -Encoding utf8 C:\blockattackers.txt # Write newly-blocked IP addresses to log file $arr_new_bad_ips_for_firewall | Out-File -Append -Encoding utf8 C:\blockattackers.txt # Boolean to make sure the new IPs are only added on one rule $bln_added_to_rule = 0 # Array to hold bad IPs from each rule one at a time, so we can count to make sure adding the new ones won't exceed 1000 IPs $arr_existing_bad_ips_current_rule = @() # For each "BlockAttackers*" rule in the firewall, do the following... foreach ($rule in $arr_firewall_rules) { if ($bln_added_to_rule -ne 1) { # Split the existing IPs from the current rule into an array so we can easily count them $arr_existing_bad_ips_current_rule = $rule.RemoteAddresses -split(',') # If the number of IPs to add is less than 1000 minus the current number of IPs in the rule, add them to this rule if ($arr_new_bad_ips_for_firewall.Count -le (1000 - $arr_existing_bad_ips_current_rule.Count)) { # Add new IPs to firewall rule $arr_new_bad_ips_for_firewall | %{$rule.RemoteAddresses += ',' + $_} # Write which rule the IPs were added to to log file echo "New IP addresses above added to Windows Firewall rule:" $rule.Name | Out-File -Append -Encoding utf8 C:\blockattackers.txt # Set boolean so any other rules are skipped when adding IPs $bln_added_to_rule = 1 } } } # If there wasn't room in any other "BlockAttackers*" firewall rule, create a new one and add the IPs to it if ($bln_added_to_rule -ne 1) { $str_new_rule_name = "BlockAttackers (Created " + $current_date_utc.ToString("yyyy-MM-dd HH:mm:ss") + " UTC)" netsh advfirewall firewall add rule dir=in action=block name=$str_new_rule_name description="Rule automatically created by BlockAttackers Powershell script written by Kevin Micke." enable=yes remoteip="0.0.0.0" | Out-Null $new_rule = $firewall.rules | Where {$_.Name -eq $str_new_rule_name} # Add new IPs to firewall rule $arr_new_bad_ips_for_firewall | %{$new_rule.RemoteAddresses += ',' + $_} # Write which rule the IPs were added to to log file echo "New IP addresses above added to newly created Windows Firewall rule:" $new_rule.Name | Out-File -Append -Encoding utf8 C:\blockattackers.txt } } 

    kevinmicke编辑的remuda脚本(2月7日21:59)没有检查FTP控制通道,它在我的系统(Windows Server 2008 R2)上有一个自己的文件夹。 53011001事件还没有被识别出来,当黑客只是试图访问控制通道时,似乎就会出现这种情况。 所以我在脚本中添加了一些行来检查第二个FTP日志文件夹:

      #此Windows Powershell脚本将自动阻止尝试login到系统的IP地址
     #并且使用$ int_block_limitvariables或更多失败的次数。 扫描两个安全
     #日志,包括远程桌面和其他尝试,以及当天的FTP日志。 如果$ int_block_limit
    这些日志中的任何一个(分别地,没有组合)命中#限制,然后IP地址将被添加到
     #防火墙规则。
     #
     #该脚本将自动创build一个名为“BlockAttackers(Created yyyy-MM-dd HH:mm:ss UTC)”的防火墙规则
     #当前时间,如果名称包含“BlockAttackers”的人不存在。 因为有一个困难
     #限制1000个条目(IP地址),您可以根据规则阻止,它也会创build类似命名的规则
     #最新的限制。
     #
     #我build议设置脚本作为由事件4625login审计失败触发的计划任务运行
     #安全日志,或者你可以设置它运行一段时间(即每10分钟)。
     #
     #作者:
     #多数由serverfault.com用户kevinmicke编写的脚本
     #Windows安全日志部分由serverfault.com用户remunda编写,为kevinmicke提供了起点
     #检查serverfault.com用户Uwe Martens添加的FTP控制通道
     #
     #详细信息:https://serverfault.com/questions/233222/ban-ip-address-based-on-x-number-of-unsuccessful-login-attempts
    
    
     #设置一个IP地址被阻塞的失败login尝试次数
     $ int_block_limit = 3
    
     #在此期间检查安全日志的时间窗口,当前设置为仅检查最近24小时
     $ dat_time_window = [DateTime] :: Now.AddDays(-1)
    
     #从安全日志中select在$ dat_time_window中具有多个$ int_block_limit审计失败(事件4625)的所有IP地址
     $ arr_new_bad_ips_security_log = @()
     $ arr_new_bad_ips_security_log = Get-EventLog -LogName'Security'-InstanceId 4625 -A $ dat_time_window |
         Select-Object @ {n ='IpAddress'; e = {$ _。ReplacementStrings [-2]}}
         Group-Object -property IpAddress |
        其中{$ _。Count -ge $ int_block_limit} |
        select - 属性名称
    
     #获取当前时间UTC来确定当前FTP日志的文件名
     $ current_date_utc =(Get-Date).ToUniversalTime()
    
     #设置今天的FTP控制通道日志文件的path
     $ str_log_file_name_control_channel =“C:\ inetpub \ logs \ LogFiles \ FTPSVC \ u_ex”+ $ current_date_utc.ToString(“yyMMdd”)+“.log”
    
     #search今天的FTP控制通道日志文件“530 1”,查找包含无法login系统IP的行,
     #从每一行获取IP,按IP分组IP,对每个IP进行计数,只selectIP
     #今天有$ int_block_limit或更多login错误的IP地址
     $ arr_new_bad_ips_ftp_control_channel = @()
     $ arr_new_bad_ips_ftp_control_channel = Select-String $ str_log_file_name_control_channel -pattern“530 1”|
         ForEach-Object {$ _。Line.Substring(20,15)-replace“。*”,“”} |
         Group |
        其中{$ _。Count -ge $ int_block_limit} |
        select - 属性名称
    
     #设置当前FTP日志文件的path
     $ str_log_file_name =“C:\ inetpub \ logs \ LogFiles \ FTPSVC * \ u_ex”+ $ current_date_utc.ToString(“yyMMdd”)+“.log”
    
     #search今天的FTP日志文件“530 1”,查找包含系统login失败IP的行,
     #从每一行获取IP,按IP分组IP,对每个IP进行计数,只selectIP
     #今天有$ int_block_limit或更多login错误的IP地址
     #在FTPSVC中*必须添加FTP服务器的ID而不是*,或者只需要正确的日志文件夹
     $ arr_new_bad_ips_ftp = @()
     $ arr_new_bad_ips_ftp =selectstring$ str_log_file_name  - 模式“530 1”|
         ForEach-Object {$ _。Line.Substring(20,15)-replace“。*”,“”} |
         Group |
        其中{$ _。Count -ge $ int_block_limit} |
        select - 属性名称
    
     #连接两个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)
    
     #对arrays进行sorting,只select唯一的IP(如果安全和FTP日志中都出现一个IP)
     $ arr_new_bad_ips_all_sorted = @()
     $ arr_new_bad_ips_all_sorted = $ arr_new_bad_ips_all |
         Foreach-Object {[string] $ _。Name} |
        select对象独立
    
     #获取防火墙对象
     $ firewall = New-Object -comobject hnetcfg.fwpolicy2
    
     #获取所有匹配“BlockAttackers *”的防火墙规则
     $ arr_firewall_rules = $ firewall.Rules | 在哪里{$ _。名字般的'BlockAttackers *'}
    
     #如果还没有“BlockAttackers *”防火墙规则,请创build一个并将其设置为一个variables
     if($ arr_firewall_rules -eq $ null){
         $ str_new_rule_name =“BlockAttackers(Created”+ $ current_date_utc.ToString(“yyyy-MM-dd HH:mm:ss”)+“UTC)”
        netsh advfirewall firewall add rule dir=in action=block name=$str_new_rule_name description="Rule automatically created." enable=yes remoteip="0.0.0.0" | Out-Null
        $arr_firewall_rules = $firewall.Rules | Where {$_.Name -like 'BlockAttackers*'}
     }
    
    # Split the existing IPs from current "BlockAttackers*" firewall rule(s) into an array so we can easily search them
    $arr_existing_bad_ips = @()
    foreach ($rule in $arr_firewall_rules) {
        $arr_existing_bad_ips += $rule.RemoteAddresses -split(',')
     }
    
    # Clean subnet masks off of IPs that are currently blocked by the firewall rule(s)
    $arr_existing_bad_ips_without_masks = @()
    $arr_existing_bad_ips_without_masks = $arr_existing_bad_ips | ForEach-Object {$_ -replace "/.*", ""}
    
    # Enter your server's IP (IPv4 and IPv6) in line 115 and 116.
    # Select IP addresses to add to the firewall, but only ones that...
    $arr_new_bad_ips_for_firewall = @()
    $arr_new_bad_ips_for_firewall = $arr_new_bad_ips_all_sorted | Where {
        # contain an IP address (ie aren't blank or a dash, which the Security log has for systems that failed FTP logins)
        $_.Length -gt 6 -and
        # aren't already in the firewall rule(s)
        !($arr_existing_bad_ips_without_masks -contains $_) -and
        # aren't the local loopback
        !($_.StartsWith('127.0.0.1')) -and
        # aren't part of the local subnet
        !($_.StartsWith('192.168.')) -and
        !($_.StartsWith('0.0.')) -and
        !($_.StartsWith('10.0.')) -and
        !($_.StartsWith('*.*.*.*')) -and
        !($_.StartsWith('*:*:*:*:*:*'))
     }
    
    # If there are IPs to block, do the following...
    if ($arr_new_bad_ips_for_firewall -ne $null) {
        # Write date and time to script-specific log file
        [DateTime]::Now | Out-File -Append -Encoding utf8 C:\inetpub\logs\LogFiles\blockattackers.txt
        # Write newly-blocked IP addresses to log file
        $arr_new_bad_ips_for_firewall | Out-File -Append -Encoding utf8 C:\inetpub\logs\LogFiles\blockattackers.txt
    
        # Boolean to make sure the new IPs are only added on one rule
        $bln_added_to_rule = 0
    
        # Array to hold bad IPs from each rule one at a time, so we can count to make sure adding the new ones won't exceed 1000 IPs
        $arr_existing_bad_ips_current_rule = @()
    
        # For each "BlockAttackers*" rule in the firewall, do the following...
        foreach ($rule in $arr_firewall_rules) {
            if ($bln_added_to_rule -ne 1) {
                # Split the existing IPs from the current rule into an array so we can easily count them
                $arr_existing_bad_ips_current_rule = $rule.RemoteAddresses -split(',')
    
                # If the number of IPs to add is less than 1000 minus the current number of IPs in the rule, add them to this rule
                if ($arr_new_bad_ips_for_firewall.Count -le (1000 - $arr_existing_bad_ips_current_rule.Count)) {
                    # Add new IPs to firewall rule
                    $arr_new_bad_ips_for_firewall | %{$rule.RemoteAddresses += ',' + $_}
    
                    # Write which rule the IPs were added to to log file
                    echo "New IP addresses above added to Windows Firewall rule:" $rule.Name | Out-File -Append -Encoding utf8 C:\inetpub\logs\LogFiles\blockattackers.txt
    
                    # Set boolean so any other rules are skipped when adding IPs
                    $bln_added_to_rule = 1
                 }
             }
         }
    
        # If there wasn't room in any other "BlockAttackers*" firewall rule, create a new one and add the IPs to it
        if ($bln_added_to_rule -ne 1) {
            $str_new_rule_name = "BlockAttackers (Created " + $current_date_utc.ToString("yyyy-MM-dd HH:mm:ss") + " UTC)"
            netsh advfirewall firewall add rule dir=in action=block name=$str_new_rule_name description="Rule automatically created." enable=yes remoteip="0.0.0.0" | Out-Null
            $new_rule = $firewall.rules | Where {$_.Name -eq $str_new_rule_name}
    
            # Add new IPs to firewall rule
            $arr_new_bad_ips_for_firewall | %{$new_rule.RemoteAddresses += ',' + $_}
    
            # Write which rule the IPs were added to to log file
            echo "New IP addresses above added to newly created Windows Firewall rule:" $new_rule.Name | Out-File -Append -Encoding utf8 C:\inetpub\logs\LogFiles\blockattackers.txt
         }
     }
    

    The name of the FTP's log-folder FTPSVC* on line 54 has to be completed of cause. In line 115 and 116 have to be entered your server's IP (IPv4 and IPv6), otherwise the own servers IP might be added to the firewall-rule a hundred times. The variable $int_block_limit I'm setting to 1 at my server, so the script is blocking a hackers attack causing a 4625-event within two seconds. I'm still thinking about to run the script additionally to occurring 4625-events in a time period of a few minutes. Of cause, it would also be possible, to separate the scripts and let one script check the 4625-events triggered by the 4625-event and another one the FTP's log-folders checking periodically every 5 or 10 minutes, even with separate firewall-rule and log-file.

    I have added mine for SQL

     # Select from the Application log (SQL) all IP addresss that have more than $int_block_limit logon failure within $dat_time_window $arr_new_bad_ips_SQL_log = @() $arr_new_bad_ips_SQL_log = Get-EventLog -LogName 'Application' -After $dat_time_window | Where-Object{$_.EventID -eq 18456} | Select-Object @{n='CLIENT';e={$_.ReplacementStrings[-1]}} | Group-Object -property CLIENT | Where {$_.Count -ge $int_block_limit} | Select -property Name | { $_.Name = $_.Name.Replace(" [CLIENT: ", ""); $_.Name = $_.Name.Replace("]", ""); return $_; } 

    Then you will have to add the array into ips_all

     $arr_new_bad_ips_all = @($arr_new_bad_ips_SQL_log) + @($arr_new_bad_ips_security_log) + @($arr_new_bad_ips_ftp_control_channel) + @($arr_new_bad_ips_ftp)