A guide on how to change the RDP port and firewall rules can be found here: http://www.iteezy.com/change-rdp-3389-port-on-windows-2008-server/qc/10098
Commercial tools for preventing RDP attacks also exists, like RdpGuard or Syspeace. Lately, a free alternative named EvlWatcher has been released.
I wanted to take a different approach. In Windows Server 2008 you can attach tasks to be executed on particular logged events. Adding an attacking IP to the Windows firewall is actually an easy task. I had Windows execute this script whenever event ID 4625 occured:
fail2ban.vbs:
- If wscript.arguments.count = 2 then
- Dim firewall, rule, rulename, ip, re, account
- 'Change this value! This rule must already exist in your inbound firewall rules
- rulename = "Fail2Ban"
- account = wscript.arguments.item(0)
- ip = wscript.arguments.item(1)
- 'MsgBox "Debug message: Invalid login with account " & account & " from IP " & ip
- Set re = new regexp
- re.Pattern = "\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b"
- If re.Test(ip) And Not IsException(account, ip) Then
- Set firewall = CreateObject("HNetCfg.FwPolicy2")
- Set rule = firewall.Rules.Item(rulename)
- If Not (rule Is Nothing) Then
- If InStr(1,rule.RemoteAddresses,ip,1) = 0 Then
- rule.RemoteAddresses = rule.RemoteAddresses & "," & ip
- End If
- End If
- Set firewall = Nothing
- Else
- 'Invalid IP or excemption from rule
- End If
- end If
- 'Handle exception cases here, you don't want to ban your own IP, for instance...Customize to your needs
- Function IsException(account, ip)
- Dim exip
- exip = "My.IP"
- IsException = False
- If ip = exip Then
- IsException = True
- End If
- End Function
For creating the script above I used this blog for inspiration.
For creating the event based task I used this blog for reference. Essential parts of the task xml configuration I changed to fit my needs:
- <Triggers>
- <EventTrigger>
- <Enabled>true</Enabled>
- <Subscription>...omitted for layout purposes...</Subscription>
- <ValueQueries>
- <Value name="AccountDomain">Event/EventData/Data[@Name='TargetDomainName']</Value>
- <Value name="AccountName">Event/EventData/Data[@Name='TargetUserName']</Value>
- <Value name="ClientAddress">Event/EventData/Data[@Name='IpAddress']</Value>
- <Value name="Computer">Event/System/Computer</Value>
- <Value name="EventID">Event/System/EventID</Value>
- </ValueQueries>
- </EventTrigger>
- </Triggers>
- ...
- <Actions Context="Author">
- <Exec>
- <Command>D:\Scripts\fail2ban.vbs</Command>
- <Arguments>"$(AccountName)" "$(ClientAddress)"</Arguments>
- </Exec>
- </Actions>
Fail2Ban.vbs:
- Dim objShell, scriptpath, args, ip, acc
- scriptpath = "D:\Scripts\fail2ban.ps1"
- acc = wscript.arguments.item(0)
- ip = wscript.arguments.item(1)
- args = chr(34) & acc & chr(34) & " " & chr(34) & ip & chr(34)
- Set objShell = CreateObject("WScript.Shell")
- 'Run powershell hidden
- objShell.Run ("powershell " & scriptpath & " " & args), 0, true
- Set objShell = Nothing
- $targetaccount = $args[0]
- $sourceip = $args[1]
- #Filter/Threshold options
- $datefilter = [DateTime]::Now.AddHours(-1) # check only last x hours
- $countfilter = 3
- $rulename ="MyRule" #Firewall rule name
- $TargetUserName = @{n='TargetUserName';e={$_.ReplacementStrings[5]}}
- $IpAddress = @{n='IpAddress';e={$_.ReplacementStrings[19]}}
- #return IP if number of failed logins for specifed IP has exceeded x tries within specified timeframe
- $IP2Ban = Get-Eventlog security -InstanceId 4625 -After $datefilter | where {$_.ReplacementStrings[19] -eq $sourceip} | select-object $IpAddress | Group-Object -Property IPAddress | where Count -gt $countfilter | Select-Object -Property Name
- if ( $IP2Ban -ne $null)
- {
- #Add IP to firewall
- #$IP2Ban.Name is same as $sourceip
- $fw = New-object –comObject HNetCfg.FwPolicy2
- $myrule = $fw.Rules | where {$_.Name -eq $rulename}
- if (-not ($myrule.RemoteAddresses -match $sourceip) -and -not ($sourceip -like "my.ip"))
- {
- $myrule.RemoteAddresses += (","+$sourceip)
- }
- $fw = $null
- }
Hi.
SvarSlettYour script is exactly what I would have needed before I created EvlWatcher. Would you mind if I link it to the EvlWatcher blog as an alternative?
You know, many admins refrain from installing third party software like EvlWatcher, because they can never be sure about what it does exactly. Those people would be extremely happy to know about this script.
Regards, Michael
I get the following error. Have you any idea what this could be?
SvarSlettWhere-Object : Cannot bind parameter 'FilterScript'. Cannot convert the "Count" value of type "System.String" to type "
System.Management.Automation.ScriptBlock".
At C:\scripts\Fail2ban.ps1:28 char:188
+ $IP2Ban = Get-Eventlog security -InstanceId 4625 -After $datefilter | where {$_.ReplacementStrings[19] -eq $sourceip}
| select-object $IpAddress | Group-Object -Property IPAddress | where <<<< Count -gt $countfilter | Select-Object -Pr
operty Name
+ CategoryInfo : InvalidArgument: (:) [Where-Object], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.WhereObjectCommand
Whis is only for ban IP. Where is Unban script ?
SvarSlett