2018-06-27

Exchange Auth Login Failed Ban Powershell Script

Exchange 是公開對外服務
難免遭受 Try 帳號的攻擊, 除了 IPS 設備以外
窮人也可以透過查詢 Transport Role Log 的方式將驗證失敗紀錄中的來源 IP 加到 Windows Advanced Firewall 來進行阻擋
因 PowerShell 版本差異, 舊版 OS 有些 cmdlet 不能用
故根據作業系統版本分別寫了兩個不同的 Script

程式尚有許多未盡之處, 比如只查最後一個 Log File 的最後多少行
不是按照時間來查詢, 可能會有遺漏或重複的情況, 不過暫時先這樣用吧!


Windows Server 2012:


===== 程式開始 =====

# in Hours
$BlockTime = 24;
$SearchTailLines = 10000;
$LogFullPath = "C:\Program Files\Microsoft\Exchange Server\V14\TransportRoles\Logs\ProtocolLog\SmtpReceive\"
$RuleGroupName = "ExchangeAuthFailBlockIPs"

#-----------------------------------------------------------------
$RemoteAddress = @();
$NewBlockIP = @();

$LastLogFile = Get-ChildItem $LogFullPath | sort LastWriteTime | select -last 1
write-host "Working on File: $LastLogFile"
$AuthFailedLog = Get-Content -Path $LastLogFile.FullName -Tail $SearchTailLines | where-object {$_ -Like '*Inbound AUTH LOGIN failed*'}
foreach ($Item in $AuthFailedLog) {
Clear-variable -Name "RemoteAddress";
Clear-variable -Name "NewBlockIP";
$Elements = $Item.Split(",");
if (([DateTime]$Elements[0]) -gt $(Get-Date).AddHours(-$BlockTime)) {
$FirewallRuleName  = ('{0:yyyy-MM-dd HH}' -f [DateTime]$Elements[0])+':00:00';
$IPTemp = $Elements[5].Split(":");
$AddBlockIP = $IPTemp[0];
$RemoteAddress = @();
$NewBlockIP = @();

$CheckRuleExist = Get-NetFirewallRule -DisplayName $FirewallRuleName;
if ($CheckRuleExist) {
# Firewall Rule Exist
$RemoteAddress = $($CheckRuleExist | Get-NetFirewallAddressFilter).RemoteAddress;
$NewBlockIP = $RemoteAddress.Split(',');
$NewBlockIP += $AddBlockIP;
$NewBlockIP = $NewBlockIP | select -uniq;
if ($NewBlockIP -ne $RemoteAddress) {
Get-NetFirewallRule -DisplayName $FirewallRuleName | Get-NetFirewallAddressFilter | Set-NetFirewallAddressFilter -RemoteAddress $NewBlockIP
write-host "Update $FirewallRuleName"
write-host "$NewBlockIP";
};
} else {
# Firewall Rule Not Exist
New-NetFirewallRule -DisplayName $FirewallRuleName -Group "ExchangeAuthFailBlockIPs" -Direction Inbound -Action Block -RemoteAddress $AddBlockIP
write-host "Add $FirewallRuleName"
write-host "$AddBlockIP";
};
};
};

#Remove Rules Two Hours Ago
Get-NetFirewallRule -Group "ExchangeAuthFailBlockIPs" | where-object {[DateTime]$_.DisplayName -lt $(Get-Date).AddHours(-$BlockTime)} | Remove-NetFirewallRule

===== 程式結束 =====


Windows Server 2008 R2:


必須安裝 PowerShell 4.0 以上
安裝參考: Windows Management Framework 5.1

===== 程式開始 =====

# in Hours
$BlockTime = 24;
$SearchTailLines = 10000;
$LogFullPath = "C:\Program Files\Microsoft\Exchange Server\V14\TransportRoles\Logs\ProtocolLog\SmtpReceive\"
$RuleGroupName = "ExchangeAuthFailBlockIPs"

#-----------------------------------------------------------------
$RemoteAddress = @();
$NewBlockIP = @();

$FirewallObject = New-Object -ComObject HNetCfg.FwPolicy2;

$LastLogFile = Get-ChildItem $LogFullPath | sort LastWriteTime | select -last 1
write-host "Working on File: $LastLogFile"
$AuthFailedLog = Get-Content -Path $LastLogFile.FullName -Tail $SearchTailLines | where-object {$_ -Like '*Inbound AUTH LOGIN failed*'}
foreach ($Item in $AuthFailedLog) {
Clear-variable -Name "RemoteAddress";
Clear-variable -Name "NewBlockIP";
$Elements = $Item.Split(",");
if (([DateTime]$Elements[0]) -gt $(Get-Date).AddHours(-$BlockTime)) {
$FirewallRuleName  = ('{0:yyyy-MM-dd HH}' -f [DateTime]$Elements[0])+':00:00';
$IPTemp = $Elements[5].Split(":");
$AddBlockIP = $IPTemp[0];
$RemoteAddress = @();
$NewBlockIP = @();

$CheckRuleExist = $FirewallObject.rules | where {$_.Name -eq $FirewallRuleName};
if ($CheckRuleExist) {
$RemoteAddress = $($CheckRuleExist.RemoteAddresses).Replace('/255.255.255.255','');
$NewBlockIP = $RemoteAddress.Split(',');
$NewBlockIP += $AddBlockIP;
$NewBlockIP = $NewBlockIP | select -uniq;
$AddBlockIP = '';
foreach ($IP in $NewBlockIP) {
if ($AddBlockIP -ne '') {
$AddBlockIP += ',';
};
$AddBlockIP += $IP;
};
if ($AddBlockIP -ne $RemoteAddress) {
$CheckRuleExist.RemoteAddresses = $AddBlockIP;
$CheckRuleExist.update;
write-host "Update $FirewallRuleName"
write-host "$AddBlockIP";
};
} else {
$Rule = New-Object -ComObject HNetCfg.FWRule;
$Rule.Name = $FirewallRuleName;
$Rule.Enabled = $True;
$Rule.Direction = 1;
$Rule.Grouping = $RuleGroupName;
$Rule.Profiles = 7;
$Rule.Action = 0;
$Rule.EdgeTraversal = $false;
$Rule.RemoteAddresses = $AddBlockIP;
$FirewallObject.Rules.Add($Rule);
write-host "Add $FirewallRuleName"
write-host "$AddBlockIP";
};
};
};

#Delete Rules
$CheckRuleToDelete = $FirewallObject.rules | where {$_.Grouping -eq $RuleGroupName} | where-object {[DateTime]$_.Name -lt $(Get-Date).AddHours(-$BlockTime)};
foreach ($Rule in $CheckRuleToDelete) {
write-host "Delete Rule: ""$($Rule.Name)"""
netsh advfirewall firewall delete rule name=($Rule.Name)

};


===== 程式結束 =====

沒有留言:

張貼留言