Vraag IP-adres verbieden op basis van X aantal mislukte inlogpogingen?


Is het mogelijk om een ​​IP-adres te verbieden na X aantal mislukte inlogpogingen naar een Windows Server? Niet voor een bepaald account, waarvan ik weet hoe het moet, maar voor de hele machine.

We worden behoorlijk geraakt door brute force-aanvallen die proberen om gebruikersnamen te raden, dus dit zou echt helpen om wat van de server te krijgen.


45
2018-02-09 11:21


oorsprong


* nix heeft fial2ban ... niet zeker of er een Windows-equivalent / -poort is. fail2ban.org/wiki/index.php/Main_Page - Chris Nava
Van Evan Anderson: serverfault.com/questions/43360/... ... lijkt een goed equivalent te zijn van de functionaliteit van fail2ban, maar omdat uw vraag niet specifiek genoeg is, weet ik niet of u IP-adressen probeert te blokkeren die proberen in te loggen bij een gehoste website, uw server (via SSH) of uw domein. Verduidelijking zou een lange weg gaan. Bovendien kunt u de limiet voor uw firewall beoordelen, maar dat is afhankelijk van de implementatie. - kce
Misschien wil je eens kijken serverfault.com/questions/216995/... voor een eerdere discussie over hoe nuttig automatisch verbieden op basis van IP is. - pehrs
Als je het hebt over Terminal Services / Remote Desktop, kijk dan hier: serverfault.com/a/335976/7200 - Evan Anderson
Ik maakte een windows-service op github om precies dat te doen: github.com/jjxtra/Windows-IP-Ban-Service - jjxtra


antwoorden:


U kunt dit doen met powershell en task manager. Het is waarschijnlijk geen perfecte oplossing, maar het werkt vrij goed en ik heb ongeveer 100 geblokkeerde IP-adressen in twee maanden. Ik heb een script geschreven, dat een selectie maakt uit gebeurtenissen die door EventLog zijn opgegeven ("controlefout"). Als er veel mislukte aanmeldingsgegevens van een IP-adres zijn, wordt deze toegevoegd aan de firewallregel (handmatig gemaakt) met de naam "BlockAttackers" die verkeer blokkeert naar opgegeven IP-adressen.

PS1-script:

$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

Maak een taak in de scheduler en stel de trigger in op gebeurtenis 4625 (Windows-login inclusief terminaldiensten). Maar u kunt de trigger instellen om b.v. tweemaal per uur om onnodig laden van de server te voorkomen.

Scheduler trigger

en na powerhell-script met trigger run. U moet ook hogere rechten instellen om dit script uit te voeren, anders mislukt het met een beveiligingsuitzondering.

runing powershell script

U kunt dit script ook koppelen aan andere beveiligingsgebeurtenissen.


27
2018-06-11 15:27



Uitstekend script @remunda - bedankt! Ik kreeg ook heel veel 4625s van FTP, waarvoor het beveiligingslogboek geen IP-adressen heeft, dus ik heb je script uitgebreid om het het huidige FTP-logboek ook te laten controleren. Zie mijn antwoord hieronder voor meer info: serverfault.com/a/571903/107701 - kevinmicke
Er zijn veel prullen en randgevallen met de gebeurtenislogboeken, IP adresregistratie, enz. Die ik heb behandeld in IPBan - gratis en open source op github.com/jjxtra/Windows-IP-Ban-Service - jjxtra


Ik weet dat deze vraag oud is, maar het was eigenlijk de eerste forumpost die ik tegenkwam toen ik een paar weken geleden precies hetzelfde probeerde te doen. Ik heb het voor elkaar gekregen om een ​​werkend script te maken dat de gebeurtenislogboeken 24 uur terug analyseert voor slecht logboekgebeurtenislogboekvermeldingen, degenen met meer dan 10 slechte aanmeldingen pakt en ze vervolgens in een ipsec-filterlijst plaatst met behulp van de netsh commando. Toen schreef ik een batchbestand met deze regel powershell .\*scriptname.ps1* en creëerde een geplande taak om het batchbestand om de 24 uur uit te voeren (om een ​​of andere reden zou het niet direct worden uitgevoerd).

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

Ik weet dat dit script waarschijnlijk inefficiënt is, maar toen ik eraan begon te werken, had ik absoluut geen ervaring met powershell, dus mijn vermogen om scripts te optimaliseren, blijft veel te wensen over. Ondanks dit feit dacht ik dat ik dit met iedereen zou delen die het zou kunnen gebruiken.

Ik dank Remunda dat hij me het eerste idee heeft gegeven, namelijk dat die poster me in de gelegenheid stelde Powershell te gebruiken om de logboeken van de gebeurtenissen te doorzoeken.


7
2017-12-04 22:09





Dit script bouwt voort op het antwoord van remunda en gaat iets verder https://serverfault.com/a/397637/155102 Het is verantwoordelijk voor de regel "BlockAttackers", maar er zijn nog geen IP's ingevoerd (die een "*" retourneert als een tekenreeks). Het schrijft ook een opmerking in een logbestand om u te laten weten wanneer het IP aan de regel is toegevoegd.

Een goede tip is om de regel "BlockAttackers" te maken die de IP-adressen blokkeert MAAR deze in eerste instantie uitschakelt. Voer vervolgens dit script één keer handmatig uit, zodat het het veld "RemoteAddresses" kan vullen met daadwerkelijke IP-adressen die moeten worden geblokkeerd. Bekijk die IP-adressen om er zeker van te zijn dat er niets kritiek is toegevoegd en schakel vervolgens de firewallregel in. Voeg deze regel toe aan uw firewall zoals beschreven in remunda.

De git voor dit script

#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





Ik kan dit antwoord niet in aanmerking nemen, maar https://serverfault.com/users/7200/evan-anderson heeft zijn project genoemd http://opensource.wellbury.com/projects/windows_sshd_block/newest-release/


3
2018-02-18 18:14





Het is over het algemeen geen goed idee om iemand anders uw firewallregels te laten beheersen. Dat is eigenlijk waar je hier om vraagt.


2
2018-02-10 22:09



+1, dit is een uitstekende manier om jezelf op te stellen voor een denial-of-service-aanval. En als u rate-limiting gebruikt, zullen de meeste geautomatiseerde brute force-tools hun inlogpogingen ver genoeg van elkaar plaatsen om te voorkomen dat ze gepakt worden. - kce
IP's automatisch blokkeren nadat een bepaald aantal mislukte aanmeldingen is heel algemene praktijk. Ik zie dat hosts per uur worden geweerd na het proberen te raden naar FTP-wachtwoorden. De enige manier waarop dit een DoS-aanval kan zijn, is als iemand erin slaagt om je IP-adres te vervalsen (onmogelijk bij TCP-verbindingen), of als je herhaaldelijk een verkeerde naam geeft aan je wachtwoord (in dit geval is het niet iemand die de firewallregels beheert, jij bent het) - devicenull
Sorry, maar ik vroeg niet of het een goed idee was. - HeavyWave
Natuurlijk kunnen er geen uitzonderingen worden gemaakt voor een of meer specifieke IP-adressen, die het DoS-probleem vrijwel zouden elimineren. - John Gardeniers


Dit is een oude draad. Ik gebruikte het script van kevinmicke in 2014-2015. Toen stopte het gewoon met werken. Dus ik moest het een beetje aanpassen om te gebruiken voor Windows Network Security-verificatie die geen IP-adressen achterlaat in het beveiligingslogboek. Omdat ik geen gewone FTP heb, verwijderde ik dat onderdeel omdat het fouten veroorzaakte omdat er geen log-map was. De belangrijkste verandering zit in de bron van RDP-gebeurtenissen.

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

Het bovenstaande script werkt in Windows 2012. Als u Remote Desktop nog steeds gebruikt met authenticatie op netwerkniveau op Windows 2008, moet u mogelijk de volgende truc doen. Windows 2008 heeft geen IP-adressen in het beveiligingslogboek en lijkt ze ook niet te hebben in het logboek Microsoft-Windows-RemoteDesktopServices-RdpCoreTS. Dus moest ik eigenlijk 2 logs gebruiken: vergelijk gebeurtenissen uit het beveiligingslogboek met succesvolle toegangspogingen tot poort 3389 in het firewalllogboek. Dit is een gokwerk, maar het lijkt wachtwoordaanvallen te detecteren. Hier is het onderdeel dat inbreukmakende IP's verzamelt:

    $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

OPMERKING: vergeet niet om firewall-logboeken in te schakelen. OPMERKING 2: Ik ben geen powershell-expert, dus het zou leuk zijn als sommige goeroes mijn code kunnen corrigeren / verbeteren.


2
2017-11-15 19:01





ik gebruik ts_block freeby.

Eigenlijk is het een "VBScript-programma dat fungeert als een WMI-event-sink om te ontvangen gebeurtenissen geregistreerd door Windows als reactie op ongeldige Terminal Services aanmeldingen."

Lijkt perfect te werken, en het script is eenvoudig als je het wilt modelleren. U kunt het pogingen laten loggen en vervolgens verbieden op basis van uw aantal toegestane pogingen en / of u kunt aanmeldingsnamen die u geen toegang wilt geven, coderen.

Ik raakte betrapt door per ongeluk twee keer dezelfde naam toe te voegen en de service gaat gewoon in een eindeloze lus die elke 1500 ms herstart, maar heel gemakkelijk te repareren / mod als je ok bent met vbs.

Mijn huidige instellingen zijn slechts één poging en je bent 2 dagen gebanned, met logins zoals 'admin' 'Admin' 'Administrator' 'guest' etc automatisch verboden. Moet het eenvoudig zijn om over te schakelen naar ip?

Nogal verslavend om binnen te gaan en te zien welke beestjes 's nachts zijn verbannen ...


1
2018-05-01 06:52





Bedoelt u zich in te loggen op de server / domein of in te loggen op een website die op de server draait? Als u bedoelt dat u zich aanmeldt bij de server / domein, dan is het antwoord nee. Windows heeft geen enkel concept om IP-adressen te blokkeren op basis van mislukte aanmeldingspogingen, aangezien ip-adressen geen beveiligingsentiteiten zijn. Er kunnen tools van derden zijn die dit kunnen doen, maar ik ben er niet van op de hoogte omdat ik er nog nooit naar heb gekeken.


0
2018-02-09 13:17