Frage IP-Adresse basierend auf X Anzahl fehlgeschlagener Anmeldeversuche sperren?


Ist es möglich, eine IP-Adresse nach X Anzahl fehlgeschlagener Anmeldeversuche an einen Windows Server zu verbieten? Nicht zu einem bestimmten Konto, von dem ich weiß, wie es geht, sondern zu der ganzen Maschine.

Wir werden ziemlich hart getroffen durch Brute-Force-Angriffe, die versuchen, Benutzernamen zu erraten, so dass dies wirklich helfen würde, den Server zu entlasten.


45
2018-02-09 11:21


Ursprung


* nix hat fial2ban ... nicht sicher ob es einen Windows Äquivalent / Port gibt. fail2ban.org/wiki/index.php/Main_Page - Chris Nava
Von Evan Anderson: serverfault.com/questions/43360/ ... ... scheint ein gutes Äquivalent der Funktionalität von fail2ban zu sein, aber da Ihre Frage nicht spezifisch genug ist, weiß ich nicht, ob Sie IPs verbieten wollen, die sich auf einer gehosteten Website, Ihrem Server (über SSH) oder Ihrem Server anmelden Domain. Die Klärung würde einen langen Weg zurücklegen. Zusätzlich können Sie das Limit für Ihre Firewall festlegen, dies ist jedoch implementierungsabhängig. - kce
Vielleicht möchten Sie sich das ansehen serverfault.com/questions/216995/ ... für eine vorherige Diskussion darüber, wie nützlich automatisiertes Banning basierend auf IP ist. - pehrs
Wenn Sie über Terminaldienste / Remotedesktop sprechen, sehen Sie hier nach: serverfault.com/a/335976/7200 - Evan Anderson
Ich habe einen Windows-Service auf GitHub gemacht, um genau das zu tun: github.com/jjxtra/Windows-IP-Ban-Service - jjxtra


Antworten:


Sie können dies mit Powershell und Task-Manager tun. Es ist wahrscheinlich keine perfekte Lösung, aber es funktioniert ganz gut und ich habe etwa 100 blockierte IP-Adressen in zwei Monaten. Ich habe Skript geschrieben, das aus EventLog spezifizierte Ereignisse auswählt ("audit failure"). Wenn es viele fehlgeschlagene Anmeldungen von einer IP-Adresse gibt, wird diese der Firewall-Regel (manuell erstellt) mit dem Namen "BlockAttackers" hinzugefügt, die jeglichen Datenverkehr an bestimmte IP-Adressen blockiert.

PS1-Skript:

$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

Erstellen Sie eine Task im Scheduler und setzen Sie den Trigger auf das Ereignis 4625 (Windows-Anmeldung einschließlich Terminaldienste). Aber Sie können Trigger so einstellen, dass z. zweimal pro Stunde, um unnötiges Laden des Servers zu vermeiden.

Scheduler trigger

und nach dem Trigger Run Powershell-Skript. Sie müssen auch höhere Berechtigungen festlegen, um dieses Skript auszuführen. Andernfalls wird die Sicherheitsausnahme fehlschlagen.

runing powershell script

Sie können dieses Skript auch an andere Sicherheitsereignisse binden.


27
2018-06-11 15:27



Ausgezeichnetes Skript @ Rememanda - danke! Ich habe auch eine Menge 4625s von FTP bekommen, für die das Sicherheitsprotokoll keine IP-Adressen hat, also habe ich das Skript erweitert, damit es auch das FTP-Protokoll des aktuellen Tages überprüft. Bitte beachten Sie meine Antwort unten für weitere Informationen: serverfault.com/a/571903/107701 - kevinmicke
Es gibt viele Fallstricke und Kantenfälle mit den Ereignisprotokollen, der IP-Adressenprotokollierung usw., die ich in IPBan behandelt habe - frei und Open Source bei github.com/jjxtra/Windows-IP-Ban-Service - jjxtra


Ich weiß, dass diese Frage alt ist, aber es war tatsächlich der erste Forum-Post, über den ich gestolpert bin, als ich vor ein paar Wochen damit angefangen habe, genau dasselbe zu tun. Es ist mir gelungen, ein funktionierendes Skript zu entwickeln, das die Ereignisprotokolle 24 Stunden lang nur für schlechte Login - Ereignisprotokolleinträge analysiert, diejenigen, die mehr als 10 fehlerhafte Logins enthalten, und sie dann in eine IPsec - Filterliste einfügt Netsh-Befehl. Dann habe ich eine Batch-Datei mit dieser Zeile geschrieben powershell .\*scriptname.ps1* und erstellte eine geplante Aufgabe, um die Batchdatei alle 24 Stunden auszuführen (aus irgendeinem Grund würde sie nicht direkt ausgeführt werden).

$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}

Ich weiß, dass dieses Skript wahrscheinlich ineffizient ist, aber als ich anfing, daran zu arbeiten, hatte ich keinerlei Erfahrung mit Powershell, sodass meine Fähigkeit, Skripte zu optimieren, sehr zu wünschen übrig lässt. Trotz dieser Tatsache dachte ich, ich würde dies mit jedem teilen, der es benutzen könnte.

Ich danke Remunda dafür, dass sie mir die erste Idee gegeben hat. Dieses Poster hat mich dazu gebracht, Powershell zu verwenden, um die Ereignisprotokolle zu durchsuchen.


7
2017-12-04 22:09





Dieses Skript baut auf Remundas Antwort auf und geht ein bisschen weiter https://serverfault.com/a/397637/155102 Es berücksichtigt, dass die "BlockAttackers" -Regel noch keine IPs eingegeben hat (die ein "*" als String zurückgibt). Außerdem wird ein Kommentar in eine Protokolldatei geschrieben, um Sie darüber zu informieren, wann die IP der Regel hinzugefügt wurde.

Ein guter Tipp ist, die "BlockAttackers" -Regel zu erstellen, die die IP-Adressen blockiert, ABER sie zunächst deaktiviert macht. Führen Sie dieses Skript dann einmal manuell aus, damit das Feld "RemoteAddresses" mit tatsächlichen IP-Adressen gefüllt werden kann, die blockiert werden sollen. Sehen Sie sich diese IP-Adressen an, um sicherzustellen, dass nichts Kritisches hinzugefügt wurde, und aktivieren Sie dann die Firewall-Regel. Fügen Sie diese Regel Ihrer Firewall als Remunda beschrieben hinzu.

Der Git für dieses Skript

#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'}
}

4
2018-01-20 20:59





Ich kann nicht für diese Antwort Anerkennung finden, aber https://serverfault.com/users/7200/evan-anderson hat sein Projekt erwähnt http://opensource.wellbury.com/projects/windows_sshd_block/news-release/


3
2018-02-18 18:14





Es ist normalerweise keine gute Idee, jemand anderen die Kontrolle über Ihre Firewallregeln zu überlassen. Das ist im Grunde, was du hier verlangst.


2
2018-02-10 22:09



+1, dies ist eine ausgezeichnete Möglichkeit, sich für einen Denial-of-Service-Angriff zu entscheiden. Und wenn Sie Rate-Limiting verwenden, legen die meisten automatisierten Brute-Force-Tools ihre Anmeldeversuche weit genug auseinander, um nicht erwischt zu werden. - kce
Automatisches Verbot von IPs nach einer bestimmten Anzahl von fehlgeschlagenen Anmeldungen ist sehr üblich. Ich sehe, dass Hosts stündlich gesperrt werden, nachdem versucht wurde, FTP-Passwörter zu erraten. Das kann nur ein DoS-Angriff sein, wenn jemand Ihre IP-Adresse gefälscht hat (bei TCP-Verbindungen nicht möglich) oder wenn Sie Ihr Kennwort wiederholt falsch eingeben (in diesem Fall ist es nicht jemand, der die Firewall-Regeln kontrolliert). - devicenull
Entschuldigung, aber ich habe nicht gefragt, ob es eine gute Idee war. - HeavyWave
Natürlich gibt es keinen Grund, dass keine Ausnahmen für eine oder mehrere spezifische IP-Adressen festgelegt werden könnten, was die DoS-Bedenken weitgehend beseitigen würde. - John Gardeniers


Dies ist ein alter Thread. Ich habe das Skript von Kevinmicke in 2014-2015 verwendet. Dann hörte es einfach auf zu arbeiten. Also musste ich es ein wenig bearbeiten, um die Windows-Netzwerksicherheitsauthentifizierung zu übernehmen, die keine IP-Adressen im Sicherheitsprotokoll hinterlässt. Da ich kein reguläres FTP-Programm habe, habe ich diesen Teil entfernt, da er Fehler verursacht hat, weil es keinen Protokollordner gab. Die Hauptänderung betrifft die Quelle der RDP-Ereignisse.

    $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 (i.e. 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
        }
    }

Das obige Skript funktioniert unter Windows 2012. Wenn Sie weiterhin Remotedesktop mit Authentifizierung auf Netzwerkzugriffsebene unter Windows 2008 verwenden, müssen Sie möglicherweise den folgenden Trick ausführen. Windows 2008 hat keine IP-Adressen im Sicherheitsprotokoll und scheint diese auch nicht im Microsoft-Windows-RemoteDesktopServices-RdpCoreTS-Protokoll zu haben. Also musste ich eigentlich 2 Logs verwenden - Treffe Ereignisse aus dem Sicherheitsprotokoll zu erfolgreichen Zugriffsversuchen auf Port 3389 im Firewall Log. Dies ist eine Vermutung Arbeit, aber es scheint zu erkennen, Passwort-Angriffe. Hier ist der Teil, der verletzende IPs sammelt:

    $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

HINWEIS: Vergessen Sie nicht, Firewall-Protokolle zu aktivieren. HINWEIS 2: Ich bin kein Powershell-Experte, daher wäre es schön, wenn einige Gurus meinen Code korrigieren / verbessern könnten.


2
2017-11-15 19:01





Ich benutze ts_block frei.

Grundsätzlich ist es ein "VBScript-Programm, das als WMI-Ereignissenke zum Empfangen dient Ereignisse, die von Windows als Reaktion auf ungültige Terminaldienste protokolliert wurden Anmeldungen. "

Scheint perfekt zu funktionieren, und das Skript ist einfach, wenn Sie es ändern müssen. Sie können entweder Versuche protokollieren lassen und dann basierend auf der Anzahl erlaubter Versuche sperren und / oder Anmelde-Namen festschreiben, denen Sie keinen Zugriff gewähren möchten.

Ich wurde erwischt, indem ich versehentlich den gleichen Namen zweimal hinzufügte, und der Dienst geht in eine Endlosschleife, die alle 1500ms neu startet, aber sehr einfach zu reparieren / Mod, wenn Sie mit Vbs in Ordnung sind.

Meine aktuellen Einstellungen sind nur eine Wiederholung und du bist für 2 Tage gesperrt, mit Logins wie 'Admin' 'Admin' 'Administrator' 'Gast' usw. automatisch gesperrt. Sollte es einfach sein, zu ip zu wechseln?

Irgendwie süchtig danach zu gehen und zu sehen, welche Kreaturen über Nacht verboten wurden ...


1
2018-05-01 06:52





Meinen Sie sich auf dem Server / der Domäne anmelden oder sich auf einer Website anmelden, die auf dem Server ausgeführt wird? Wenn Sie sich auf dem Server / der Domäne anmelden, lautet die Antwort: Nein. Windows hat kein Konzept zum Blockieren von IP-Adressen basierend auf fehlgeschlagenen Anmeldeversuchen, da IP-Adressen keine Sicherheitsentitäten sind. Es kann Tools von Drittanbietern geben, die das tun können, aber mir sind keine bekannt, da ich noch nie danach gesucht habe.


0
2018-02-09 13:17