They’re coming outta the walls. They’re coming outta the goddamn walls!

SSH Server on Windows… so no fail2ban… how could i block all brute-forced attacks without installing crapware?
Answer: Powershell Script to the rescue!

  • Analyze sshd log file
  • Search for “failed” string records
  • Extract Source IP
  • Create a Windows Firewall Rule to block access to Source IP
  • Find some info about Source IP with ip-api.com webservice
  • Log all actions made to file

That’s all ! Script below
❤️👌

$file = "C:\ProgramData\ssh\logs\sshd.log"
$records_log = "300"
$stringa = "Failed password for invalid user"
$log = "C:\utils\blocked_ip_ssh.log"
$failed_access_count = "5"


$failed_access = get-content $file -Tail $records_log | select-string $stringa

$failed_access_list = @()

foreach ($line in $failed_access) { #$line = $failed_access | select -first 1

    $obj = New-Object -TypeName PSObject
    $obj | Add-Member -Type NoteProperty -Name DataOra -Value $(get-date (($line.line).split(" ")[1] + " " + ($line.line).split(" ")[2]))
    $obj | Add-Member -Type NoteProperty -Name User -Value ($line.line).split(" ")[8]
    $obj | Add-Member -Type NoteProperty -Name IP -Value ($line.line).split(" ")[10]
    $obj | Add-Member -Type NoteProperty -Name Porta -Value ($line.line).split(" ")[12]
            
    $failed_access_list += $obj
 
}


$existing_rules = (get-netfirewallrule | where displayname -match "Block_ip_").displayname 

foreach ( $record in  ($failed_access_list | Group-Object -Property IP | where count -gt $failed_access_count) ) {

    $datetime = $(get-date).tostring("yyyyMMddHHmmss")
    $rulename = Block_ip_$($record.name)

    if ($null -eq ($existing_rules | where {$_ -match $rulename}) ) {

        New-NetFirewallRule -DisplayName $($rulename + "_" + $datetime) -Profile Public –RemoteAddress $record.name -Direction Inbound -Action Block
 
        $rule = get-netfirewallrule -DisplayName Block_ip_$($record.name)_$datetime

        if ($null -ne $rule) {

             $api_geolocation = Invoke-WebRequest "http://ip-api.com/json/$($record.name)?fields=status,message,continent,continentCode,country,countryCode,region,regionName,city,district,zip,lat,lon,timezone,offset,currency,isp,org,as,asname,reverse,mobile,proxy,hosting,query"
    
             Start-Sleep -Seconds 2
        
            "$(get-date -format yyyyMMddHHmmss) bloccato ip $($record.name) ($(($api_geolocation.Content | convertfrom-json).country) - $(($api_geolocation.Content | convertfrom-json).regionname) - $(($api_geolocation.Content | convertfrom-json).city) - $( ($api_geolocation.Content | convertfrom-json).isp) - $( ($api_geolocation.Content | convertfrom-json).org) - $( ($api_geolocation.Content | convertfrom-json).as)) con regola firewall 'Block_ip_$($record.name)_$datetime'" | add-content $log

        }

    }
   

}