50 votes

Interdiction d'une adresse IP sur la base d'un nombre X de tentatives de connexion infructueuses ?

Est-il possible de bannir une adresse IP après un nombre X de tentatives de connexion infructueuses à un serveur Windows ? Pas à un compte particulier, ce que je sais faire, mais à l'ensemble de la machine.

Nous subissons de plein fouet les attaques par force brute qui tentent de deviner les noms d'utilisateur, ce qui permettrait de soulager le serveur.

28voto

MobileDanceTeam Points 310

Vous pouvez le faire avec powershell et le gestionnaire de tâches. Ce n'est probablement pas la solution parfaite, mais elle fonctionne assez bien et j'ai environ 100 adresses IP bloquées en deux mois. J'ai écrit un script script qui sélectionne dans le journal des événements les événements spécifiés ("échec de l'audit"). S'il y a beaucoup d'échecs de connexion à partir d'une adresse IP, celle-ci est ajoutée à une règle de pare-feu (créée manuellement) appelée "BlockAttackers" qui bloque tout trafic vers les adresses IP spécifiées.

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

Créez une tâche dans le planificateur et définissez le déclencheur sur l'événement 4625 (connexion Windows, y compris les services de terminal). Mais vous pouvez programmer le déclencheur pour qu'il s'exécute par exemple deux fois par heure afin d'éviter de charger inutilement le serveur.

Scheduler trigger

et après le déclenchement, exécuter le script powershell script. Vous devez également définir des privilèges plus élevés pour exécuter ce script, sinon il échouera avec une exception de sécurité.

runing powershell script

Vous pouvez également lier ce script à d'autres événements de sécurité.

7voto

Declan Carroll Points 935

Je sais que cette question est ancienne mais c'est en fait le premier message du forum sur lequel je suis tombé lorsque j'ai commencé à essayer de faire exactement la même chose il y a deux semaines. J'ai réussi à mettre au point un script qui analysera les journaux d'événements 24 heures en arrière pour les entrées de journaux d'événements de mauvaise connexion, récupérera celles qui ont plus de 10 mauvaises connexions, puis les mettra dans une liste de filtres ipsec à l'aide de la commande netsh. Ensuite, j'ai écrit un fichier batch avec cette ligne powershell .\*scriptname.ps1* et créé une tâche programmée pour exécuter le fichier batch toutes les 24 heures (pour une raison quelconque, il ne s'exécutait pas directement).

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

Je sais que ce script est probablement inefficace, mais lorsque j'ai commencé à travailler sur ce projet, je n'avais absolument aucune expérience en powershell, donc ma capacité à optimiser les script laisse beaucoup à désirer. Cependant, malgré ce fait, j'ai pensé partager ceci avec tous ceux qui pourraient l'utiliser.

Je remercie Remunda de m'avoir donné l'idée initiale, c'est ce poster qui m'a donné l'idée d'utiliser powershell pour rechercher dans les journaux d'événements.

4voto

Michael Khalili Points 142

Ce script s'appuie sur la réponse de remunda et va un peu plus loin https://serverfault.com/a/397637/155102 Il tient compte du fait que la règle "BlockAttackers" n'a pas encore été saisie (ce qui renvoie un "*" sous forme de chaîne). Il écrit également un commentaire dans un fichier journal pour vous indiquer quand l'IP a été ajoutée à la règle.

Un bon conseil est de créer la règle "BlockAttackers" qui bloque les adresses IP MAIS de la désactiver au début. Ensuite, exécutez ce script une fois manuellement afin qu'il puisse remplir le champ "RemoteAddresses" avec les adresses IP réelles qui doivent être bloquées. Examinez ces adresses IP pour vous assurer que rien de critique n'a été ajouté, puis activez la règle de pare-feu. Ajoutez cette règle à votre pare-feu comme l'a décrit remunda.

Le git pour ce 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'}
}

3voto

becomingwisest Points 3258

Je ne peux pas m'attribuer le mérite de cette réponse, mais https://serverfault.com/users/7200/evan-anderson a mentionné son projet http://opensource.wellbury.com/projects/windows_sshd_block/newest-release/

2voto

Stephanie Points 146

Il n'est généralement pas judicieux de laisser quelqu'un d'autre contrôler les règles de votre pare-feu. C'est essentiellement ce que vous demandez ici.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X