Das von kevinmicke bearbeitete Skript von remuda (7. Februar um 21:59 Uhr) hat den Kontrollkanal des FTP nicht überprüft, der auf meinem System einen eigenen Ordner hat (Windows Server 2008 R2). Auch 530 11001
haben -Events nicht erkannt worden, was zu erscheinen scheinen , wenn nur der Hacker den Zugriff auf den Steuerkanal versucht. Deshalb habe ich einige Zeilen im Skript angehängt, um einen zweiten FTP-Log-Ordner zu überprüfen:
# Dieses Windows Powershell-Skript blockiert automatisch IP-Adressen, die versuchen, sich beim System anzumelden
# und nicht so oft wie unten mit der Variablen $ int_block_limit oder mehr angegeben. Überprüft wird sowohl die Sicherheit
# log, das Remotedesktop und andere Versuche sowie das aktuelle FTP-Protokoll des Tages abdeckt. Wenn das $ int_block_limit
Wenn in einem dieser Protokolle das # -Limit erreicht ist (separat, nicht kombiniert), wird die IP-Adresse zu dem Protokoll hinzugefügt
# Firewall-Regel.
#
# Das Skript erstellt automatisch eine Firewall-Regel mit dem Namen "BlockAttackers (Created yyyy-MM-dd HH: mm: ss UTC)"
# die aktuelle Uhrzeit, wenn noch keine mit einem Namen vorhanden ist, der "BlockAttackers" enthält. Weil es eine harte gibt
# Beschränkung auf 1000 Einträge (IP-Adressen), die Sie pro Regel blockieren können. Sobald dies der Fall ist, werden auch Regeln mit ähnlichen Namen erstellt
Das # -Limit ist für die neueste Version erreicht.
#
# Ich empfehle, das Skript so einzurichten, dass es als geplante Aufgabe ausgeführt wird, die durch Fehler bei der Anmeldeprüfung von Ereignis 4625 ausgelöst wird
# Sicherheitsprotokoll, oder Sie können festlegen, dass es nach einiger Zeit (dh alle 10 Minuten) ausgeführt wird.
#
# Autoren:
# Die Mehrheit der Skripte wurde vom serverfault.com-Benutzer kevinmicke geschrieben
# Teil des Windows-Sicherheitsprotokolls, der vom serverfault.com-Benutzer remunda geschrieben wurde und den Ausgangspunkt für kevinmicke darstellte
# Überprüfung des vom serverfault.com-Benutzer Uwe Martens hinzugefügten FTP-Kontrollkanals
#
# Details: https://serverfault.com/questions/233222/ban-ip-address-based-on-x-number-of-unsuccessful-login-attempts
# Anzahl der fehlgeschlagenen Anmeldeversuche festlegen, nach denen eine IP-Adresse gesperrt wird
$ int_block_limit = 3
# Zeitfenster, in dem das Sicherheitsprotokoll überprüft werden soll. Derzeit werden nur die letzten 24 Stunden überprüft
$ dat_time_window = [DateTime] :: Now.AddDays (-1)
# Wählen Sie im Sicherheitsprotokoll alle IP-Adressen aus, bei denen mehr als $ int_block_limit Überwachungsfehler (Ereignis 4625) innerhalb von $ dat_time_window aufgetreten sind
$ arr_new_bad_ips_security_log = @ ()
$ arr_new_bad_ips_security_log = Get-EventLog -LogName 'Security' -InstanceId 4625 -Nach $ dat_time_window |
Select-Object @ {n = 'IpAddress'; e = {$ _. ReplacementStrings [-2]}} |
Gruppenobjekt-Eigenschaft IpAddress |
Wobei {$ _. Count -ge $ int_block_limit} |
Wählen Sie -property Name
# Holen Sie sich die aktuelle UTC-Zeit, um den Dateinamen für das aktuelle FTP-Protokoll zu ermitteln
$ current_date_utc = (Get-Date) .ToUniversalTime ()
# Legen Sie den Pfad zur heutigen FTP-Kontrollkanal-Protokolldatei fest
$ str_log_file_name_control_channel = "C: \ inetpub \ logs \ LogFiles \ FTPSVC \ u_ex" + $ current_date_utc.ToString ("yyMMdd") + ".log"
# Durchsuchen Sie die Protokolldatei des heutigen FTP-Steuerkanals nach "530 1", um nach Zeilen zu suchen, die IP-Adressen von Systemen enthalten, die sich nicht anmelden konnten.
# Holen Sie sich nur die IP von jeder Zeile, gruppieren Sie die IPs nach IP, um die Versuche von jeder Zeile zu zählen, und wählen Sie nur die aus
# IPs, die heute mindestens $ int_block_limit haben
$ 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 ". *", ""} |
Gruppe |
Wobei {$ _. Count -ge $ int_block_limit} |
Wählen Sie -property Name
# Legen Sie den Pfad zur heutigen FTP-Protokolldatei fest
$ str_log_file_name = "C: \ inetpub \ logs \ LogFiles \ FTPSVC * \ u_ex" + $ current_date_utc.ToString ("yyMMdd") + ".log"
# Durchsuchen Sie die heutige FTP-Protokolldatei nach "530 1", um nach Zeilen zu suchen, die IP-Adressen von Systemen enthalten, die sich nicht anmelden konnten.
# Holen Sie sich nur die IP von jeder Zeile, gruppieren Sie die IPs nach IP, um die Versuche von jeder Zeile zu zählen, und wählen Sie nur die aus
# IPs, die heute mindestens $ int_block_limit haben
# In FTPSVC * muss anstelle von * die ID des FTP-Servers eingegeben werden, oder es muss nur der richtige Log-Ordner ausgewählt werden
$ 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 ". *", ""} |
Gruppe |
Wobei {$ _. Count -ge $ int_block_limit} |
Wählen Sie -property Name
# Verketten Sie die beiden IP-Arrays (eines aus dem Sicherheitsprotokoll, eines aus dem FTP-Protokoll)
$ 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)
# Sortieren Sie das Array und wählen Sie nur eindeutige IP-Adressen aus (falls eine IP-Adresse sowohl im Sicherheits- als auch im FTP-Protokoll angezeigt wird).
$ arr_new_bad_ips_all_sorted = @ ()
$ arr_new_bad_ips_all_sorted = $ arr_new_bad_ips_all |
Foreach-Object {[string] $ _. Name} |
Select-Object-einzigartig
# Holen Sie sich ein Firewall-Objekt
$ firewall = New-Object -comobject hnetcfg.fwpolicy2
# Alle Firewall-Regeln abrufen, die mit "BlockAttackers *" übereinstimmen
$ arr_firewall_rules = $ firewall.Rules | Where {$ _. Name-like 'BlockAttackers *'}
# Wenn noch keine Firewall-Regel "BlockAttackers *" vorhanden ist, erstellen Sie eine und setzen Sie sie auf eine Variable
if ($ arr_firewall_rules -eq $ null) {
$ str_new_rule_name = "BlockAttackers (Created" + $ current_date_utc.ToString ("JJJJ-MM-TT HH: MM: SS") + "UTC") "
netsh advfirewall Firewall Regel hinzufügen dir = in Aktion = Blockname = $ str_new_rule_name description = "Regel automatisch erstellt." enable = yes remoteip = "0.0.0.0" | Out-Null
$ arr_firewall_rules = $ firewall.Rules | Where {$ _. Name-like 'BlockAttackers *'}
}
# Teilen Sie die vorhandenen IP-Adressen der aktuellen "BlockAttackers *" - Firewall-Regeln in ein Array auf, damit wir sie problemlos durchsuchen können
$ arr_existing_bad_ips = @ ()
foreach ($ rule in $ arr_firewall_rules) {
$ arr_existing_bad_ips + = $ rule.RemoteAddresses -split (',')
}
# Entfernen Sie Subnetzmasken von IP-Adressen, die derzeit von den Firewall-Regeln blockiert werden.
$ arr_existing_bad_ips_without_masks = @ ()
$ arr_existing_bad_ips_without_masks = $ arr_existing_bad_ips | Für jedes Objekt {$ _ -replace "/.*", ""}
# Geben Sie die IP-Adresse Ihres Servers (IPv4 und IPv6) in die Zeilen 115 und 116 ein.
# Wählen Sie IP-Adressen aus, die der Firewall hinzugefügt werden sollen, aber nur solche, die ...
$ arr_new_bad_ips_for_firewall = @ ()
$ arr_new_bad_ips_for_firewall = $ arr_new_bad_ips_all_sorted | Wo {
# eine IP-Adresse enthalten (dh nicht leer oder ein Bindestrich, den das Sicherheitsprotokoll für Systeme enthält, bei denen FTP-Anmeldungen fehlgeschlagen sind)
$ _. Länge -gt 6 -und
# sind noch nicht in den Firewall-Regeln enthalten
! ($ arr_existing_bad_ips_without_masks -contains $ _) -und
# ist nicht das lokale Loopback
! ($ _. StartsWith ('127.0.0.1')) -und
# sind nicht Teil des lokalen Subnetzes
! ($ _. StartsWith ('192.168.')) -Und
! ($ _. StartsWith ('0.0.')) -Und
! ($ _. StartsWith ('10 .0. ')) -Und
! ($ _. StartsWith ('*. *. *. *')) -Und
! ($ _. StartsWith ('*: *: *: *: *: *'))
}
# Wenn IPs blockiert werden müssen, gehen Sie wie folgt vor ...
if ($ arr_new_bad_ips_for_firewall -ne $ null) {
# Schreiben Sie Datum und Uhrzeit in die skriptspezifische Protokolldatei
[DateTime] :: Now | Out-File -Append -Encoding utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
# Schreiben Sie neu blockierte IP-Adressen in die Protokolldatei
$ arr_new_bad_ips_for_firewall | Out-File -Append -Encoding utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
# Boolescher Wert, um sicherzustellen, dass die neuen IP-Adressen nur für eine Regel hinzugefügt werden
$ bln_added_to_rule = 0
# Array, das jeweils eine ungültige IP-Adresse für jede Regel enthält. Wir können also sicherstellen, dass beim Hinzufügen der neuen IP-Adresse 1000 IP-Adressen nicht überschritten werden
$ arr_existing_bad_ips_current_rule = @ ()
# Führen Sie für jede "BlockAttackers *" - Regel in der Firewall die folgenden Schritte aus ...
foreach ($ rule in $ arr_firewall_rules) {
if ($ bln_added_to_rule -ne 1) {
# Teilen Sie die vorhandenen IPs aus der aktuellen Regel in ein Array auf, damit wir sie problemlos zählen können
$ arr_existing_bad_ips_current_rule = $ rule.RemoteAddresses -split (',')
# Wenn die Anzahl der hinzuzufügenden IP-Adressen weniger als 1000 minus der aktuellen Anzahl der IP-Adressen in der Regel beträgt, fügen Sie sie dieser Regel hinzu
if ($ arr_new_bad_ips_for_firewall.Count -le (1000 - $ arr_existing_bad_ips_current_rule.Count)) {
# Fügen Sie der Firewall-Regel neue IP-Adressen hinzu
$ arr_new_bad_ips_for_firewall | % {$ rule.RemoteAddresses + = ',' + $ _}
# Schreiben Sie, zu welcher Regel die IPs zur Protokolldatei hinzugefügt wurden
echo "Neue IP-Adressen oben zur Windows Firewall-Regel hinzugefügt:" $ rule.Name | Out-File -Append -Encoding utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
# Stellen Sie den Booleschen Wert so ein, dass andere Regeln beim Hinzufügen von IPs übersprungen werden
$ bln_added_to_rule = 1
}
}
}
# Wenn in keiner anderen "BlockAttackers *" - Firewallregel Platz war, erstellen Sie eine neue und fügen Sie die IPs hinzu
if ($ bln_added_to_rule -ne 1) {
$ str_new_rule_name = "BlockAttackers (Created" + $ current_date_utc.ToString ("JJJJ-MM-TT HH: MM: SS") + "UTC") "
netsh advfirewall Firewall Regel hinzufügen dir = in Aktion = Blockname = $ str_new_rule_name description = "Regel automatisch erstellt." enable = yes remoteip = "0.0.0.0" | Out-Null
$ new_rule = $ firewall.rules | Wobei {$ _. Name -eq $ str_new_rule_name}
# Fügen Sie der Firewall-Regel neue IP-Adressen hinzu
$ arr_new_bad_ips_for_firewall | % {$ new_rule.RemoteAddresses + = ',' + $ _}
# Schreiben Sie, zu welcher Regel die IPs zur Protokolldatei hinzugefügt wurden
echo "Neue IP-Adressen wurden der neu erstellten Windows Firewall-Regel hinzugefügt:" $ new_rule.Name | Out-File -Append -Encoding utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
}
}
Der Name des FTP-Protokollordners FTPSVC*
in Zeile 54 muss aus wichtigem Grund ausgefüllt werden. In den Zeilen 115 und 116 muss die IP Ihres Servers (IPv4 und IPv6) eingegeben werden, andernfalls kann die IP des eigenen Servers hundertmal zur Firewall-Regel hinzugefügt werden. Die Variable, die $int_block_limit
ich auf meinem Server auf 1 setze, sodass das Skript einen Hackerangriff blockiert, der innerhalb von zwei Sekunden ein 4625-Ereignis verursacht. Ich denke immer noch darüber nach, das Skript zusätzlich zu 4625-Ereignissen in einem Zeitraum von wenigen Minuten auszuführen. Natürlich wäre es auch möglich, die Skripte zu trennen und ein Skript die vom 4625-Ereignis ausgelösten 4625-Ereignisse und ein anderes Skript die Protokollordner des FTP-Servers regelmäßig alle 5 oder 10 Minuten überprüfen zu lassen, selbst bei separater Firewall-Regel und Protokolldatei.