苦于本人所管理的Windows服务器频繁被远程端口爆破,故有此文,意在找到一个高效自动化的方式将爆破端IP封禁的方式。 因为攻击方会频繁更换自己的IP地址,所以只做一次的静态封禁是无效,所以需要配置周期任务才能一劳永逸。目前的思路是通过Windows的PowerShell脚本实现读取并分析系统事件记录,然后挑选出高频请求登录的IP,最后将其加入到封禁名单中去。 ## 第一步:查询IP所属列 不同版本的Windows的事件记录格式不同,所以需要对系统事件记录进行检查,找到登录日志中记录IP的字段。通常情况下Windows2016之后的字段为[19]。 如果不知道自己系统的字段可以通过以下PowerShell脚本进行查询。 ```shell $LogName = "Security" $EventID = 4625 # 登录失败事件ID # 获取最近 1000 条事件 $FailedAttempts = Get-WinEvent -LogName $LogName -MaxEvents 3 | Where-Object { $_.Id -eq $EventID } # 列出所有属性信息 if ($FailedAttempts.Count -eq 0) { Write-Host "没有找到任何登录失败事件。" } else { Write-Host "找到以下登录失败事件:" foreach ($Attempt in $FailedAttempts) { Write-Host "事件时间: $($Attempt.TimeCreated)" # 输出所有属性 for ($i = 0; $i -lt $Attempt.Properties.Count; $i++) { Write-Host "属性[$i]: $($Attempt.Properties[$i].Value)" } Write-Host "--------------------------" } } ``` ## 第二步:编写时间记录分析PowerShell脚本 脚本中有几个变量可以根据服务器的性能自行设置,Threshold代表阈值,如果在规定时间内密码错误次数大于Threshold则对其进行封禁;LockoutDuration是封锁时常,这里是无效的,本脚本设置的是永久封禁;TimeFrame代表搜索时段,也就是TimeFrame时间内密码错误次数大于Threshold则对其进行封禁,单位是分钟。 脚本的代码如下所示。 ```shell $LogName = "Security" $EventID = 4625 # 登录失败事件ID $Threshold = 3 $LockoutDuration = 1440 # 封锁时长,单位为分钟 $TimeFrame = (Get-Date).AddMinutes(-360) # 6小时的时间框架 # 获取最近 1000 条事件,再筛选登录失败事件 $FailedAttempts = Get-WinEvent -LogName $LogName -MaxEvents 5000 | Where-Object { $_.Id -eq $EventID } # 检查是否有失败事件 if ($FailedAttempts.Count -eq 0) { Write-Host "没有找到任何登录失败事件。" } else { Write-Host "找到以下登录失败事件:" # 过滤出过去 6 小时内的失败尝试 $RecentFailures = $FailedAttempts | Where-Object { $_.TimeCreated -ge $TimeFrame } # 分组并计算每个 IP 地址的失败次数 $FailedGroups = $RecentFailures | ForEach-Object { $IpAddress = $_.Properties[19].Value # 直接提取 IP 地址 [PSCustomObject]@{IpAddress = $IpAddress; TimeCreated = $_.TimeCreated} } | Group-Object -Property IpAddress | Where-Object { $_.Count -gt $Threshold } # 处理封锁 foreach ($Group in $FailedGroups) { $IPAddress = $Group.Name # 检查 IP 地址是否已经被封锁 $ExistingRule = Get-NetFirewallRule | Where-Object { $_.DisplayName -eq "Block IP $IPAddress" } if (-not $ExistingRule) { Write-Host "封锁 IP 地址: $IPAddress,因为在过去 6 小时内失败次数超过 $Threshold 次" # 添加防火墙规则封锁 IP New-NetFirewallRule -DisplayName "Block IP $IPAddress" -Direction Inbound -Action Block -RemoteAddress $IPAddress -Enabled True } else { Write-Host "IP 地址 $IPAddress 已经被封锁,跳过封锁操作。" } } } Write-Host "完成处理所有失败的尝试。" # 等待10秒再关闭窗口 Start-Sleep -Seconds 10 ``` ## 第三步:编写时间记录分析PowerShell脚本 为了防止攻击方更换IP地址,我们需要设置脚本每隔10分钟或者30分钟运行一次。 将以下的内容存储为XML文件,然后导入到“任务计划程序”中即可,导入方式是通过搜索功能搜索“任务计划程序”,然后点击右侧边栏中的“导入任务”,然后重新选择执行者的Windows用户名即可,通常是“Administrator”(每台电脑都需要重新配置)。 本xml配置的是每30分钟执行一次,如果有需要的话可以改为每10分钟执行一次。 **如果在Windows 2022系统下,任务计划不能自动重复执行,请把无限期设置为1天。 ** ```xml 2024-10-26T03:55:00.5885764 10-7-66-89\Administrator \远程爆破检测 PT30M false 2024-10-26T03:53:30 P1D true 1 S-1-5-21-2080368302-96478165-505204645-500 InteractiveToken HighestAvailable IgnoreNew true true true false false true false true true false false false PT72H 7 powershell.exe "C:\Users\Administrator\Desktop\remote_protect.ps1" ``` ## 第四步:查询当前已经封禁的IP地址 可以通过以下PowerShell代码实现查询当前已经封禁的IP地址。 ```shell Get-NetFirewallRule | Where-Object { $_.Action -eq 'Block' } | Select-Object DisplayName, RemoteAddress ``` ## 注意事项 1. PowerShell 脚本的后缀名为*.ps1 2. 本脚本为了性能只扫描最近1000次的登录日志,如果有其他的需求可以自行修改脚本。 PS. 后续有补充我继续修改,最后更新日期:2024年10月26日 Last modification:October 26, 2024 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 1 If you think my article is useful to you, please feel free to appreciate