Başarısız oturum açma denemelerinin X sayısına göre IP adresi yasaklandı mı?


47

X sayısı bir Windows Sunucusuna yapılan başarısız giriş denemesinden sonra bir IP adresini yasaklamak mümkün müdür? Nasıl yapılacağını bildiğim belirli bir hesaba değil, tüm makineye.

Kullanıcı adlarını tahmin etmeye çalışan kaba kuvvet saldırılarıyla oldukça sert bir şekilde çarpılıyoruz, bu yüzden bu, sunucudan biraz yük alınmasına yardımcı olacaktır.


8
* nix, fial2ban 'a sahip ... Windows eşdeğeri / bağlantı noktası olup olmadığından emin değil. fail2ban.org/wiki/index.php/Main_Page
Chris Nava

5
Evan Anderson'dan: serverfault.com/questions/43360/… ... fail2ban'ın işlevselliğinin iyi bir eşdeğeri gibi görünüyor, ancak sorunuz yeterince net olmadığı için, giriş yapmaya çalışan IP'leri yasaklamak isteyip istemediğinizi bilmiyorum barındırılan bir web sitesine, sunucunuz (SSH üzerinden) veya etki alanınıza. Açıklama uzun bir yol giderdi. Ek olarak, güvenlik duvarınızda sınırı değerlendirebilirsiniz, ancak bu uygulamaya bağlıdır.

4
IP'ye dayalı otomatik yasaklamanın ne kadar faydalı olduğu hakkında daha önce tartışmak için serverfault.com/questions/216995/… 'e bir göz atmak isteyebilirsiniz .
pehrs

1
Terminal Hizmetleri / Uzak Masaüstü hakkında konuşuyorsanız, buradan bir göz atın: serverfault.com/a/335976/7200
Evan Anderson

3
Bunu yapmak için github'da
jjxtra

Yanıtlar:


28

Bunu powershell ve görev yöneticisi ile yapabilirsiniz. Muhtemelen mükemmel bir çözüm değildir, ancak oldukça iyi çalışıyor ve iki ay içinde yaklaşık 100 engellenmiş IP adresim var. EventLog tarafından belirtilen olaylar arasından seçilen komut dosyasını yazdım ("denetim hatası"). Herhangi bir IP adresinden çok sayıda başarısız oturum açma varsa, belirtilen ip adreslerine giden herhangi bir trafiği engelleyen "BlockAttackers" adlı güvenlik duvarı kuralına eklenir (manuel olarak oluşturulur).

PS1 Komut Dosyası:

$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

Zamanlayıcıda görev oluşturun ve tetiği olay 4625'e ayarlayın (terminal hizmetleri dahil Windows oturumu açın). Ancak sunucunun gereksiz yere yüklenmesini önlemek için tetikleyiciyi örneğin saatte iki kez çalışacak şekilde ayarlayabilirsiniz.

Zamanlayıcı tetikleyicisi

ve tetikleyici çalıştırdıktan sonra powershell betiği. Ayrıca bu betiği çalıştırmak için daha yüksek ayrıcalıklar belirlemelisiniz, aksi takdirde güvenlik istisnası ile başarısız olur.

powershell betiğini çalıştırmak

Bu betiği diğer güvenlik olaylarına da bağlayabilirsiniz.


1
Mükemmel script @remunda - teşekkürler! Güvenlik günlüğünde IP adreslerinin bulunmadığı FTP'den de 4625'lerin çoğunu alıyordum, bu yüzden betiğinizde mevcut günün FTP günlüğünü de kontrol etmesi için genişledim. Lütfen daha fazla bilgi için aşağıdaki cevabımı inceleyin: serverfault.com/a/571903/107701
kevinmicke

Serbest ve açık kaynak - Ben IPBan ele ettik olay günlükleri, ip adreslerini giriş, vb Sorunlar ve kenar vakalarının bir yeri vardır github.com/jjxtra/Windows-IP-Ban-Service
jjxtra

7

Bu sorunun eski olduğunu biliyorum ama aslında birkaç hafta önce aynı şeyi yapmaya çalışırken karşılaştığım ilk forum yazısıydı. Yalnızca kötü giriş olay günlüğü girişleri için geri 24 saat olay günlüğünü ayrıştırma, 10'dan fazla hatalı giriş yapmış olanları alma ve sonra bunları kullanarak bir ipsec filtre listesine yerleştirme çalışma komut dosyası bulmayı başardım netsh komutu. Sonra bu satırda bir toplu iş dosyası yazdım powershell .\*scriptname.ps1*ve her 24 saatte bir toplu iş dosyasını çalıştırmak için zamanlanmış bir görev oluşturdum (bir nedenden dolayı doğrudan çalıştırılmayacak).

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

Bu betiğin büyük olasılıkla verimsiz olduğunu biliyorum ama bunun üzerine çalışmaya başladığımda, powershell'de kesinlikle hiçbir tecrübem yoktu, bu yüzden komut dosyalarını optimize etme yeteneğim arzulanan bir şey bırakıyor. Ancak bu gerçeğe rağmen, bunu kullanabilecek olanlarla paylaşacağımı düşündüm.

Bana ilk fikri verdiğim için Remunda'ya teşekkür ediyorum, bu poster beni etkinlik kayıtlarını aramak için powershell kullanma fikrine yönlendiren poster.


4

Bu komut dosyası remunda'nın cevabına dayanıyor ve biraz daha ileri gidiyor https://serverfault.com/a/397637/155102 "BlockAttackers" kuralının henüz girilmiş bir IP adresi yok (bir dize olarak "*" değerini döndüren). Ayrıca, IP'ye kurala ne zaman eklendiğini bildirmek için bir günlük dosyasına yorum yazar.

İyi bir ipucu, BUT IP adreslerini engelleyen ilk adresleri engelleyen "BlockAttackers" kuralını oluşturmaktır. Ardından, bu betiği bir kez manuel olarak çalıştırın, "RemoteAddresses" alanını, engellenmesi gereken gerçek IP adresleriyle doldurabilir. Önemli bir şey eklenmemiş olduğundan emin olmak için bu IP adreslerine bakın ve ardından güvenlik duvarı kuralını etkinleştirin. Bu kuralı, güvenlik duvarınıza remunda açıklandığı şekilde ekleyin.

Bu komut dosyası için git

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


2

Güvenlik duvarı kurallarınızı başkalarının denetlemesine izin vermek genellikle iyi bir fikir değildir. Temelde burada ne istiyorsun.


1
+1, bu hizmet reddi saldırısı için kendinizi hazırlamanın mükemmel bir yoludur. Ve hız sınırlayıcı kullanıyorsanız, çoğu otomatik kaba kuvvet aracı, yakalanmamak için giriş girişimlerini yeterince uzağa yerleştirir.

12
Belirli sayıda başarısız oturum açma işleminden sonra IP'lerin otomatik olarak yasaklanması çok yaygın bir uygulamadır. FTP şifrelerini tahmin etmeye çalıştıktan sonra ana bilgisayarların saatlik olarak yasaklandığını görüyorum. Bunun bir DoS saldırısı olmasının tek yolu, birinin
IP'nizi aldatmasını başarması

18
Üzgünüm, ama iyi bir fikir olup olmadığını sormadım.
HeavyWave

1
Elbette, bir veya daha fazla belirli IP adresi için DoS endişesini ortadan kaldıracak hiçbir istisna belirlenemeyen bir sebep yoktur.
John Gardeniers

2

Bu eski bir iplik. 2014-2015 yıllarında kevinmicke tarafından sağlanan senaryoyu kullanıyordum. Sonra sadece çalışmayı bıraktı. Bu nedenle, IP adreslerini güvenlik günlüğünde bırakmayan Windows Ağ Güvenliği kimlik doğrulamasına adapte olmak için biraz düzenlemek zorunda kaldım. Ayrıca, düzenli çalışan FTP'ye sahip olmadığımdan bu bölümü hatalara neden olduğu için kaldırdım çünkü herhangi bir günlük klasörü yoktu. Ana değişiklik, RDP olaylarının kaynağındadır.

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

Yukarıdaki komut Windows 2012'de çalışacaktır. Windows 2008'de hala Uzak Masaüstü'nü ağ erişim seviyesi kimlik doğrulaması ile kullanıyorsanız, aşağıdaki numarayı yapmanız gerekebilir. Windows 2008, güvenlik günlüğünde IP adreslerine sahip değildir ve Microsoft-Windows-RemoteDesktopServices-RdpCoreTS günlüğünde de görünmüyor. Bu yüzden aslında 2 günlük kullanmak zorunda kaldım - güvenlik günlüğündeki olayları güvenlik duvarı günlüğündeki 3389 numaralı bağlantı noktasına başarılı erişim girişimlerine kadar eşleştirin. Bu bir tahmin işi, ancak şifre saldırılarını tespit ediyor gibi görünüyor. IP'leri ihlal edenleri toplayan kısım:

    $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

NOT: Güvenlik duvarı günlüklerini etkinleştirmeyi unutmayın. NOT 2: Bir powershell uzmanı değilim, bu yüzden bazı guruların kodumu düzeltmesi / iyileştirmesi iyi olurdu.


1

Ts_block freeby kullanıyorum .

Temel olarak, "Windows tarafından geçersiz Terminal Hizmetleri oturum açmalarına yanıt olarak kaydedilen olayları almak için WMI olay havuzu görevi yapan VBScript programı."

Mükemmel çalışıyor gibi görünüyor ve modunu değiştirmeniz gerekirse komut dosyası basit. Girişimleri günlüğe kaydetmesine izin verebilir ve ardından izin verilen girişimlerinize göre yasaklayabilirsiniz ve / veya erişim vermek istemediğiniz giriş kodlarını yazabilirsiniz.

Yanlışlıkla aynı adı iki kez ekleyerek yakalandım ve servis her 1500ms'de yeniden başlatan sonsuz bir döngüye giriyor, ancak vbs ile sorun yaşamadığınızda düzeltmesi çok kolay.

Geçerli ayarlarım yalnızca bir deneme sürümünde ve 2 gün boyunca yasaklandınız; 'admin' 'Yönetici' 'Yönetici' 'konuk' vb. Girişler otomatik olarak yasaklandı. İp değiştirmek için basit olmalı?

İçeri girip hangi geceleri yasaklandığını görmek biraz bağımlılık yarattı ...


0

Sunucuya / etki alanına giriş yapmak mı yoksa sunucuda çalışan bir web sitesine giriş yapmak mı demek istiyorsunuz? Sunucu / etki alanında oturum açmayı kastediyorsanız cevap hayır. Windows, ip adresleri güvenlik öğeleri olmadığından başarısız oturum açma girişimlerine dayanarak ip adreslerini engelleme kavramı yoktur. Bunu yapabilen üçüncü parti araçlar olabilir, ancak hiç bakmadığım hiçbir şeyden haberdar değilim.


0

Saldırıya uğramış bir web sunucusu varsa, dinamik IP kısıtlamaları uzantısını yükleyebilirsiniz . Bu, sunucuya standart kimlik doğrulaması içinse , saldırıların alan adını etki alanına katılmış bilgisayarlarla sınırlayacak olan etki alanı ve sunucu yalıtımını uygulayabilmeniz ve yalnızca erişmeniz gereken sistemlerden yapılan denemelere izin verecek şekilde ayarlamanız gerekir. sunucu. Windows'ta kaba kuvvet saldırılarının önlenmesi, hesap kilitleme politikasını 10 dakika ve kötü bir şifre politikasını 3 deneme olarak ayarlamaktır - bu, saldırıya uğrayan hesabın 3 denemeden sonra 10 dakika süreyle kilitleneceği anlamına gelir. IP bağlantıları varsayılan olarak pencerelerde kilitlenemez. (Bir kenara, sistemi etkilemek için saniyede kaç oturum açma denemesi yapıldığını da merak ediyorum)


AWS küçük örneğimde, her 4 saniyede bir 1 deneme,% 50 CPU'yu tüketmek için yeterli. Bana sorarsan çok saçma ...
RomanSt

Vay, kullanımın neden bu kadar yüksek olduğunu merak ediyorum. VM'lerimde kaydolma denemesinin kaç tane olduğunu görmek için bazı testler yapmam gerekecek.
Jim B

Sanırım Ağ Düzeyi Kimlik Doğrulama kullanmıyorum, bu yüzden her oturum açma denemesi, uzaktaki bir masaüstü oturumu aracılığıyla saldırgana sunmak için oturum açma kullanıcı arayüzü başlatıyor. Bunun neden pahalı olabileceğini anlayabiliyorum.
RomanSt

0

http://nerderies.blogspot.co.at/2012/12/automatically-banning-ips-with-windows.html

İstediğiniz kutu çözümünün dışındaysa (Install & done) burada ücretsiz bir araç bulabilirsiniz ve muhtemelen şu şekilde okumaya devam etmelisiniz:

Mevcut Sürüm: 1.2 (.NET Framework 4.0 Müşteri Profili) -> EvlWatcher'ın mevcut sürümünü indirin (kişisel ve ticari kullanım için ücretsiz)

1.2’de yeni (belgelerde daha fazla bilgi):

  • Yönetim konsolu
  • WCF Servis Deseni
  • kara listeye
  • 3 vuruştan sonra kara listeye otomatik olarak geçme (varsayılan)

Daha eski sunucular için (.NET Framework 2.0)

-> EvlWatcher'ın indirgenmiş versiyonunu indirin (kişisel ve ticari kullanım için ücretsiz)


0

Remunda'nın en iyi senaryosunu başlangıç ​​noktası olarak kullanarak , eksik olan en önemli şeyi ekledim: IP adreslerini başarısız FTP girişlerinden engelleme . Windows Server, birisi FTP üzerinden giriş yapamadığında IP adresini Güvenlik günlüğüne kaydetmez, ancak "Kaynak Ağ Adresi" ni bir tire olarak ayarlar. FTP, kaba kuvvet saldırıları için çok yaygın bir saldırı vektörüdür, bu yüzden senaryosuna birden fazla oturum açma hatası için mevcut günün FTP kayıtlarını tarama ve bu IP adreslerini engelleme özelliğini ekledim.

2014/02/07 Güncellemesi: Tüm eski FTP günlüklerimi işlemek için buna bazı değişiklikler yaptığımda, çok sayıda deneme (50.000+) yaptıklarında, oluşturdukları dizilerin çok büyük olacağını ve işlemeyi inanılmaz derecede yavaşlatacağını fark ettim. O zamandan beri FTP günlüklerini işlerken çok daha verimli hale getirmek için yeniden yazdım.

Ayrıca, bir Windows Güvenlik Duvarı kuralında kaç tane IP olabileceğine dair keyfi bir 1000 zor sınır olduğunu da öğrendim. Bu sınır nedeniyle, en yenisi dolduğunda otomatik olarak yeni bir kural oluşturması gerekiyordu. Bunu şimdi yapar ve ayrıca ilk güvenlik duvarı kuralını (kendi kurallarınızı oluşturmazsanız) oluşturur, böylece yapılacak tek kurulum bunu bir olay 4625 olduğunda çalışacak şekilde Zamanlayıcı'ya eklemek olacaktır.

İşte hem Windows Server 2008 R2'de hem de Windows 7'de test edilen kod:

# This Windows Powershell script will automatically block IP addresses that attempt to login to the system
# and fail the number of times set below with the $int_block_limit variable or more. Is scans both the Security
# log, which covers Remote Desktop and other attempts, as well as the current day's FTP log. If the $int_block_limit
# limit is hit on either of those logs (separately, not combined), then the IP address will be added to the
# firewall rule.
#
# The script will automatically create a firewall rule named "BlockAttackers (Created yyyy-MM-dd HH:mm:ss UTC)" using
# the current time if one with a name that includes "BlockAttackers" doesn't already exist. Because there's a hard
# limit of 1000 entries (IP addresses) you can block per rule, it will also create similarly-named rules once that
# limit is reached for the latest one.
#
# I recommend setting the script to run as a scheduled task triggered by event 4625 login audit failures from the
# Security log, or alternatively you could set it to run after some amount of time (i.e. every 10 minutes).
#
# Authors:
# Majority of script written by serverfault.com user kevinmicke
# Windows Security Log portion written by serverfault.com user remunda, which provided the starting point for kevinmicke
#
# Details: https://serverfault.com/questions/233222/ban-ip-address-based-on-x-number-of-unsuccessful-login-attempts


# 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)

# Select from the Security log all IP addresses that have more than $int_block_limit audit failures (event 4625) within $dat_time_window
$arr_new_bad_ips_security_log = @()
$arr_new_bad_ips_security_log = Get-EventLog -LogName 'Security' -InstanceId 4625 -After $dat_time_window |
    Select-Object @{n='IpAddress';e={$_.ReplacementStrings[-2]}} |
    Group-Object -property IpAddress |
    Where {$_.Count -ge $int_block_limit} |
    Select -property Name

# Get current time UTC to figure out filename for current FTP log
$current_date_utc = (Get-Date).ToUniversalTime()

# Set path to today's FTP log file
$str_log_file_name = "C:\inetpub\logs\LogFiles\FTPSVC2\u_ex" + $current_date_utc.ToString("yyMMdd") + ".log"

# Search today's FTP log file for "530 1326" to find lines that contain IPs of systems that failed to log in,
# get just the IP from each line, group the IPs by IP to count the attempts from each one, and select only the
# IPs that have $int_block_limit or more bad logins today
$arr_new_bad_ips_ftp = @()
$arr_new_bad_ips_ftp = Select-String $str_log_file_name -pattern "530 1326" |
    ForEach-Object {$_.Line.Substring(20,15) -replace " .*", ""} |
    Group |
    Where {$_.Count -ge $int_block_limit} |
    Select -property Name

# Concatenate the two arrays of IPs (one from Security log, one from FTP log)
$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)

# 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_sorted = @()
$arr_new_bad_ips_all_sorted = $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 by BlockAttackers Powershell script written by Kevin Micke." 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_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_for_firewall = $arr_new_bad_ips_all_sorted | 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('10.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:\blockattackers.txt
    # Write newly-blocked IP addresses to log file
    $arr_new_bad_ips_for_firewall | Out-File -Append -Encoding utf8 C:\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:\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 by BlockAttackers Powershell script written by Kevin Micke." 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:\blockattackers.txt
    }
}

Bilginize: Daha önce bir sistemde bir powershell betiği çalıştırmamış olanlar için önce yeni bir powershell açmanız ve çalıştırmanız gerekir, Set-ExecutionPolicy RemoteSignedböylece yerel komut dosyalarını çalıştırabilirsiniz. Aksi takdirde bir hata alırsınız: "bu sistemde scriptlerin çalıştırılması devre dışı olduğu için blockattackers.ps1 yüklenemiyor."
kevinmicke

0

Kevinmicke (7 Şubat 21:59) tarafından düzenlenen remuda betiği, sistemimde kendi klasörü olan FTP'nin kontrol kanalını kontrol etmedi (Windows Server 2008 R2). Ayrıca -events tanınmadı, bu hacker sadece kontrol kanalına erişmeye çalıştığında ortaya çıkıyor. Bu yüzden ikinci bir FTP-log-klasörü kontrol etmek için betiğe bazı satırlar ekledim:530 11001

# Bu Windows Powershell betiği, sisteme giriş yapmaya çalışan IP adreslerini otomatik olarak engelleyecektir
# ve $ int_block_limit değişkeni veya daha fazlasıyla aşağıda belirtilen zaman sayısını alamaz. Her iki güvenliği de tarar
Uzak Masaüstü ve diğer denemelerin yanı sıra geçerli günün FTP günlüğünü kapsayan # log. $ İnt_block_limit ise
# bu kayıtlardan herhangi birine sınır konulur (ayrı ayrı, birleştirilmiş değil), ardından IP adresi
# güvenlik duvarı kuralı.
#
# Komut dosyası, otomatik olarak "BlockAttackers (Oluşturuldu yyyy-AA-GGH: mm: ss UTC)" adında bir güvenlik duvarı kuralı oluşturacak
# "BlockAttackers" içeren bir ismi olan biri mevcut değilse mevcut saat. Çünkü zor bir şey var
Her kural için engelleyebileceğiniz 1000 giriş (IP adresi) # limiti, aynı zamanda aynı şekilde adlandırılmış kurallar oluşturacaktır.
En son limit için # limitine ulaşıldı.
#
# Komut dosyasını, olaydan gelen 4625 oturum açma denetiminin başlattığı olay tarafından tetiklenen zamanlanmış bir görev olarak çalıştırmanızı öneririm.
# Güvenlik günlüğü veya alternatif olarak, belirli bir süre sonra çalışacak şekilde ayarlayabilirsiniz (örneğin, her 10 dakikada bir).
#
# Yazarlar:
# Serverfault.com kullanıcısı tarafından yazılan betiğin çoğunluğu user kevinmicke
Kevinmicke için başlangıç ​​noktası sağlayan serverfault.com user remunda tarafından yazılan Windows Güvenlik Günlüğü bölümü
# Serverfault.com kullanıcısı Uwe Martens tarafından eklenen FTP kontrol kanalının kontrolü
#
# Ayrıntılar: https://serverfault.com/questions/233222/ban-ip-address-based-on-x-number-of-unsuccessful-login-attempts


# Bir IP adresinin engelleneceği başarısız oturum açma denemelerinin sayısını ayarlayın
$ int_block_limit = 3

# Yalnızca son 24 saati kontrol etmek üzere ayarlanmış olan Güvenlik günlüğünün kontrol edileceği süre penceresi
$ dat_time_window = [DateTime] :: Now.AddDays (-1)

# $ Dat_time_window içinde $ int_block_limit denetim hatalarından (olay 4625) fazla olan tüm IP adreslerini Güvenlik günlüğünden seçin
$ arr_new_bad_ips_security_log = @ ()
$ arr_new_bad_ips_security_log = Get-EventLog -LogName 'Güvenlik' -InstanceId 4625 -Daha sonra $ dat_time_window |
    Nesne Seç @ {n = 'IpAdresi'; e = {$ _. İkameStrings [-2]}} |
    Grup-Nesne-mülkiyeti IpAdresi |
    Nerede {$ _. Count -ge $ int_block_limit} |
    -Türkiye Adı Seç

# Mevcut FTP günlüğünün dosya adını bulmak için geçerli saat UTC'sini alın
$ current_date_utc = (Başlangıç ​​Tarihi) .ToUniversalTime ()

# Bugünün FTP Kontrol Kanalı günlük dosyasının yolunu ayarlayın
$ str_log_file_name_control_channel = "C: \ inetpub \ logs \ LogFiles \ FTPSVC \ u_ex" + $ current_date_utc.ToString ("yyMMdd") + ".log"

# Giriş yapamayan sistemlerin IP'lerini içeren satırları bulmak için bugünün FTP Kontrol Kanalı günlük dosyasını "530 1" için arayın,
# her satırdan yalnızca IP'yi alın, her birinin denemelerini saymak için IP'leri IP'ye göre gruplayın ve yalnızca
Günümüzde $ int_block_limit veya daha fazla kötü giriş içeren # IP’ler
$ arr_new_bad_ips_ftp_control_channel = @ ()
$ arr_new_bad_ips_ftp_control_channel = Dize Seçin $ str_log_file_name_control_channel -pattern "530 1" |
    Her Nesne için {$ _. Line.Substring (20,15) - ". *", ""} Yerine |
    Grup |
    Nerede {$ _. Count -ge $ int_block_limit} |
    -Türkiye Adı Seç

# Bugünün FTP günlük dosyasının yolunu ayarlayın
$ str_log_file_name = "C: \ inetpub \ logs \ LogFiles \ FTPSVC * \ u_ex" + $ current_date_utc.ToString ("yyMMdd") + ".log"

# Oturum açmayan sistemlerin IP'lerini içeren satırları bulmak için bugünün FTP günlük dosyasını "530 1" olarak arayın,
# her satırdan yalnızca IP'yi alın, her birinin denemelerini saymak için IP'leri IP'ye göre gruplayın ve yalnızca
Günümüzde $ int_block_limit veya daha fazla kötü giriş içeren # IP’ler
# FTPSVC'de *, * yerine FTP sunucusunun kimliğinin eklenmesi veya doğru günlük klasörünün alınması gerekir
$ arr_new_bad_ips_ftp = @ ()
$ arr_new_bad_ips_ftp = Dize Seçin $ str_log_file_name -pattern "530 1" |
    Her Nesne için {$ _. Line.Substring (20,15) - ". *", ""} Yerine |
    Grup |
    Nerede {$ _. Count -ge $ int_block_limit} |
    -Türkiye Adı Seç

# İki IP dizisini birleştirin (biri Güvenlik günlüğü, diğeri FTP günlüğü)
$ 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_control_channel) + @ ($ arr_new_bad_ips_ftp)

# Diziyi sıralayın, yalnızca benzersiz IP'ler seçerek (hem Güvenlik hem de FTP günlüklerinde bir IP göründüğü takdirde)
$ arr_new_bad_ips_all_sorted = @ ()
$ arr_new_bad_ips_all_sorted = $ arr_new_bad_ips_all |
    Foreach-Object {[string] $ _. Ad} |
    Seçme Nesnesi-benzersiz

# Güvenlik duvarı nesnesini al
$ firewall = Yeni Nesne -birlikli nesne hnetcfg.fwpolicy2

# "BlockAttackers *" ile eşleşen tüm güvenlik duvarı kurallarını alın
$ arr_firewall_rules = $ firewall.Rules | {$ _. Ad benzeri 'BlockAttackers *'}

# Henüz "BlockAttackers *" güvenlik duvarı kuralı yoksa, bir tane oluşturun ve onu bir değişkene ayarlayın
if ($ arr_firewall_rules -eq $ null) {
    $ str_new_rule_name = "BlockAttackers (Oluşturuldu" + $ current_date_utc.ToString ("yyyy-AA-ggHH: mm: ss") + "UTC)"
    netsh advfirewall firewall kural ekle dir = eylemde = blok adı = $ str_new_rule_name Description = "Kural otomatik olarak oluşturuldu." enable = evet remoteip = "0.0.0.0" | Dışında Boş
    $ arr_firewall_rules = $ firewall.Rules | {$ _. Ad benzeri 'BlockAttackers *'}
}

# Mevcut IP'leri mevcut "BlockAttackers *" güvenlik duvarı kurallarından bir diziye bölerek kolayca arayabiliriz
$ arr_existing_bad_ips = @ ()
foreach ($ arr_firewall_rules $ $ kuralı) {
    $ arr_existing_bad_ips + = $ rule.RemoteAddresses -split (',')
}

# Güvenlik duvarı kuralları tarafından şu anda engellenen IP'lerin maskelerini silin
$ arr_existing_bad_ips_without_masks = @ ()
$ arr_existing_bad_ips_without_masks = $ arr_existing_bad_ips | Her Nesne için {$ _ -replace "/.*", ""}

# Sunucunuzun IP adresini (IPv4 ve IPv6) 115 ve 116 satırlarına girin.
# Güvenlik duvarına eklemek için IP adreslerini seçin, ancak yalnızca ...
$ arr_new_bad_ips_for_firewall = @ ()
$ arr_new_bad_ips_for_firewall = $ arr_new_bad_ips_all_sorted | Nerede {
    # bir IP adresi içerir (yani, Güvenlik günlüğünün FTP oturum açma başarısız olan sistemler için sahip olduğu boş veya kısa çizgi değil)
    $ _. Uzunluk -gt 6 -ve
    # zaten güvenlik duvarı kurallarında değil
    ! ($ arr_existing_bad_ips_without_masks-$ $ içerir) -ve
    # yerel geridöngü değil
    ! ($ _. StartsWith ('127.0.0.1')) -ve
    # yerel alt ağın parçası değil
    ! ($ _. StartsWith ('192.168.')) -Ve
    ! ($ _. StartsWith ('0.0.')) -Ve
    ! ($ _. StartsWith ('10 .0. ')) -Ve
    ! ($ _. StartsWith ('*. *. *. *')) -Ve
    ! ($ _ Startswith (. '*: *: *: *: *: *'))
}

# Engellenecek IP varsa, aşağıdakileri yapın ...
if ($ arr_new_bad_ips_for_firewall -ne $ null) {
    # Komut dosyasına özgü günlük dosyasına tarih ve saat yazın
    [DateTime] :: Şimdi | Out-File -Append -En kodlama utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
    # Günlük dosyasına engellenen IP adreslerini yazın
    $ arr_new_bad_ips_for_firewall | Out-File -Append -En kodlama utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt

    # Yeni IP’lerin sadece bir kurala eklendiğinden emin olmak için Boolean
    $ bln_added_to_rule = 0

    # Her bir kuralın birer birer birer birer hatalı IP'leri tutacağım, böylece yenilerini eklemenin 1000 IP'yi geçmeyeceğinden emin olabiliriz.
    $ arr_existing_bad_ips_current_rule = @ ()

    # Güvenlik duvarındaki her "BlockAttackers *" kuralı için aşağıdakileri yapın ...
    foreach ($ arr_firewall_rules $ $ kuralı) {
        if ($ bln_added_to_rule -ne 1) {
            # Mevcut IP'leri mevcut kuraldan bir diziye bölerek kolayca sayabiliriz
            $ arr_existing_bad_ips_current_rule = $ rule.RemoteAddresses -split (',')

            # Eklenecek IP sayısı, kuraldaki geçerli IP sayısı 1000 eksi'den az ise, bu kurala ekleyin
            if ($ arr_new_bad_ips_for_firewall.Count -le (1000 - $ arr_existing_bad_ips_current_rule.Count)) {
                # Güvenlik duvarı kuralına yeni IP'ler ekleyin
                $ arr_new_bad_ips_for_firewall | % {$ rule.RemoteAddresses + = ',' + $ _}

                # Günlük dosyasına hangi IP'lerin eklendiğini yazın
                echo "Yukarıdaki Yeni IP adresleri Windows Güvenlik Duvarı kuralına eklendi:" $ rule.Name | Out-File -Append -En kodlama utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt

                # Boolean'ı ayarlayın, böylece IP eklerken diğer kuralların atlanmasını sağlayın
                $ bln_added_to_rule = 1
            }
        }
    }

    # Başka bir "BlockAttackers *" güvenlik duvarı kuralında yer yoksa, yeni bir tane oluşturun ve IP'leri ekleyin
    if ($ bln_added_to_rule -ne 1) {
        $ str_new_rule_name = "BlockAttackers (Oluşturuldu" + $ current_date_utc.ToString ("yyyy-AA-ggHH: mm: ss") + "UTC)"
        netsh advfirewall firewall kural ekle dir = eylemde = blok adı = $ str_new_rule_name Description = "Kural otomatik olarak oluşturuldu." enable = evet remoteip = "0.0.0.0" | Dışında Boş
        $ new_rule = $ firewall.rules | Burada {$ _. Name -eq $ str_new_rule_name}

        # Güvenlik duvarı kuralına yeni IP'ler ekleyin
        $ arr_new_bad_ips_for_firewall | % {$ new_rule.RemoteAddresses + = ',' + $ _}

        # Günlük dosyasına hangi IP'lerin eklendiğini yazın
        echo "Yeni IP adresleri yeni oluşturulan Windows Güvenlik Duvarı kuralına eklendi:" $ new_rule.Name | Out-File -Append -En kodlama utf8 C: \ inetpub \ logs \ LogFiles \ blockattackers.txt
    }
}

FTP'nin FTPSVC*54. satırdaki günlük klasörünün adı nedenin tamamlanması gerekiyor. 115 ve 116 satırına, sunucunuzun IP'sine (IPv4 ve IPv6) girilmesi gerekir, aksi takdirde kendi sunucuları IP, güvenlik duvarı kuralına yüzlerce kez eklenebilir. Sunucumda $int_block_limit1 değerine ayarlıyorum, bu yüzden komut dosyası iki saniye içinde 4625 olayına neden olan bir bilgisayar korsanının saldırısını engelliyor. Hala senaryoyu, birkaç dakikalık bir zaman periyodunda meydana gelen 4625 olaylara ek olarak çalıştırmayı düşünüyorum. Bunun nedeni, komut dosyalarını ayırmak ve bir komut dosyasının 4625 olayı tarafından tetiklenen 4625 olaylarını denetlemesini ve bir başkasının da ayrı bir güvenlik duvarı kuralı olsa bile, her 5 veya 10 dakikada bir düzenli aralıklarla kontrol eden FTP günlük klasörlerini kontrol etmesini sağlamak olabilir. ve günlük dosyası.


-1

SQL için benimki ekledim

# Select from the Application log (SQL) all IP addresss that have more than $int_block_limit logon failure within $dat_time_window
$arr_new_bad_ips_SQL_log = @()
$arr_new_bad_ips_SQL_log = Get-EventLog -LogName 'Application' -After $dat_time_window |
    Where-Object{$_.EventID -eq 18456} |
    Select-Object @{n='CLIENT';e={$_.ReplacementStrings[-1]}} |
    Group-Object -property CLIENT |
    Where {$_.Count -ge $int_block_limit} |
    Select -property Name |
    {
        $_.Name = $_.Name.Replace(" [CLIENT: ", "");
        $_.Name = $_.Name.Replace("]", "");
        return $_;
    }

O zaman diziyi ips_all içine eklemeniz gerekecek

$arr_new_bad_ips_all = @($arr_new_bad_ips_SQL_log) + @($arr_new_bad_ips_security_log) + @($arr_new_bad_ips_ftp_control_channel) + @($arr_new_bad_ips_ftp)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.