Automatisch IP Adressen von Angreifern mit der Windows Firewall blockieren

Mit Powershell Firewallregeln dynamisch konfigurieren

Durch Zufall habe ich entdeckt, dass in einem meiner Ereignisprotokolle (“Applications and Services Logs\Microsoft\Windows\RemoteDesktopServices-RdpCoreTS\Operational”) mehrere Einträge mit der ID 140 vorhanden sind. Diese Ereignisse protokollieren die Versuche von Benutzern, sich über RDP auf meinem Server anzumelden versuchen, aber mit falschen Anmeldeinformationen. Natürlich sollte es keine Versuche geben oder vielleicht nur einen oder zwei von mir selbst. Aber in meinem Fall sind es hunderte.

Zuerst habe ich überprüft, ob mein lokales und mein Domänenadministratorkonto beide deaktiviert sind. Dies war der Fall, so dass die meisten Anmeldeversuche ebenfalls fehlschlagen, weil der jeweilige Benutzer deaktiviert ist. Ich nehme an, dass die meisten versuchen, diese Benutzer zu verwenden. Der Benutzer wird durch die Versuche nicht gesperrt, da zwischen den Wiederholungsversuchen genügend Zeit liegt.

Der Text des Anmeldeversuchs im Ereignisprotokoll lautet “A connection from the client computer with an IP address of xxx.xxx.xxx.xxx failed because the user name or password is not correct.”.

Also habe ich ein PowerShell-Skript erstellt, das diese Meldungen ausliest, die IP daraus filtert und in die Blacklist der Windows Firewall aufnimmt. Voraussetzung dafür ist, dass es bereits eine Firewall-Regel mit mindestens 2 blockierten IP-Adressen gibt. Ich war einfach zu faul, dies in meinem Skript zu lösen. Um diese Regel zu erstellen, starten Sie die Windows Firewall Einstellungen und erstellen Sie eine neue Regel unter “Eingehende Regeln”.

Wählen Sie “Benutzerdefiniert” aus. Lassen Sie “Alle Programme” stehen (klicken Sie einfach auf “Weiter”). Beliebigen Protokolltyp und Port belassen (einfach “Weiter” klicken). Wählen Sie im Abschnitt “Anwendungsbereich” unter “Für welche entfernten IP-Adressen gilt diese Regel?” die Option “Diese IP-Adressen” und fügen Sie zwei Dummy-Adressen hinzu, z. B. 1.2.3.4 und 1.2.3.5. Wir brauchen mindestens zwei Adressen für das Skript. Klicken Sie auf “Weiter”. Wählen Sie “Die Verbindung blockieren”. Bei “Profil” kreuzen Sie alle Profile an. Auf der letzten Seite geben Sie einen guten Namen für Ihre Regel ein. Wir werden den Namen in unserem Skript benötigen. Nun ist Ihre Regelkonfiguration abgeschlossen.

Jetzt das Skript. Dies ist der Code, der mit den bereits genannten Voraussetzungen arbeitet. Kopieren Sie den Text in eine Datei mit der Endung .ps1.

### Variables ###
# The name of the firewall rule in Windows Firewall
$firewallRuleName = "Block RDP Attackers"

# IPs that will not be blacklisted. i.e. your home IP if you are using Dyndns or any other static IP
$whiteList = @(
[System.Net.Dns]::GetHostAddresses("myhome.dyndns.org").IPAddressToString, #Example for DNS entry
"89.20.58.68" #Example for IP
)

### Script ###
Write-Host "Running at $(Get-Date)"
$regExIp = "\d\d?\d?.\d\d?\d?.\d\d?\d?.\d\d?\d?"
$regExIp6 = "((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?"

# Get the current Eventlogs with the 140 event
$currentAttackers = @(Get-Winevent Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational | Where-Object {$_.Id -eq 140} | Select Message -ExpandProperty Message)

# If there is no response, there are no attacks
if ($currentAttackers -eq $null) {
Write-Host "No current attackers"
return
}

# Get each attackermessage and filter the IP from it using the regex above
for ($i = 0; $i -lt $currentAttackers.Count; $i++) {
if ($currentAttackers[$i] -match $regExIp -or $currentAttackers[$i] -match $regExIp6){
$currentAttackers[$i] = $Matches[0]
} 
}

# Get the already known attackers from the firewall rule
$knownAttackers = (Get-NetFirewallRule -DisplayName $firewallRuleName | Get-NetFirewallAddressFilter).RemoteAddress
if ($knownAttackers -eq $null){
$knownAttackers = @()
}
$knownAttackers = $knownAttackers | Sort-Object -Unique

# Check each logged attacker and check if it is already known
foreach($newAttacker in $currentAttackers) {
if ($knownAttackers.Contains($newAttacker)) { #If it is known, don't do anything
continue
}
elseif ($whiteList -contains $newAttacker) { #If it is whitelisted, don't do anything
Write-Host "$newAttacker is dynamically whitelisted"
continue
}
else{ #otherwise it is a new attacker and add it to the blacklist
$knownAttackers += $newAttacker
Write-Host "Added $newAttacker"
}
}

# remove dublicates (should not be there, but anyway...)
$knownAttackers = $knownAttackers | Sort-Object -Unique
Write-Host "$($knownAttackers.Count) IPs on blacklist"

# Setting Firwall rules with all known and all new attackers
Set-NetFirewallRule -DisplayName $firewallRuleName -RemoteAddress $knownAttackers
Write-Host ""

Letzte Änderungen: (23.01.2021) IPv6 hinzugefügt und ein Problem behoben, wenn nur ein Event existiert. Dank an Joachim

Wenn Sie einen anderen Namen als “Block RDP Attackers” für die Firewall-Regel haben, müssen Sie die Zeile $firewallRuleName = "Block RDP Attackers" in Ihren Regelnamen ändern.

Führen Sie das Skript “als Administrator” aus. Es wird Ihr Ereignisprotokoll durchsuchen und alle IPs ermitteln, die in den Ereignissen mit der ID 140 im entsprechenden Protokoll erwähnt werden. Diese IPs werden zu der zuvor erstellten Regel hinzugefügt und blockieren diese IPs in Zukunft.

Ich habe eine geplante Aufgabe für dieses Skript, um es regelmäßig auszuführen. In einem Zeitraum von nur wenigen Stunden sind bereits etwa 600 IP-Adressen auf meiner Blockliste. Wenn Sie die geplante Aufgabe konfigurieren, achten Sie darauf, dass das Kontrollkästchen “mit höchsten Rechten ausführen” aktiviert ist.

WICHTIG: Dieses Skript bietet keine vollständige Absicherung gegenüber potentiellen Eindringlingen. Es erschwert dies höchstens. Die Nutzung eines Reverse Desktop Gateways mit einer professionellen Firewall (z.B. OPNsense) sowie einer Multifaktor-Authentifizierung sollte generell bevorzugt werden, als diese hier beschriebene “Notlösung”.

Neuste Blogposts

Install Mattermost behind OPNsense Reverse Proxy

This article is about installing mattermost behind a OPNsense reverse proxy using Ubuntu and the official Omnibus deployment method of Mattermost.

Mattermost hinter einem OPNsense Reverse Proxy installieren

Dieser Artikel beschreibt die Installation von Mattermost hinter einem OPNsense Reverse Proxy mit Ubuntu und der offiziellen Omnibus Deployment Methode von Mattermost.

Cluster Shared Volume (CSV) has redirected access

Troubleshooting guide for cluster shared volumes (CSV). From easy to hard.