Skip to content

Installation

Jonathan Haddock edited this page Aug 31, 2019 · 2 revisions

Warranty

Note this script contains absolutely no warranty. Improper use could result in locking yourself out of your system and require local system access to fix. If you are in any doubt, seek assistance from an IT professional.

Installation steps

Installation is reasonably simple and should take less than 30 minutes assuming you meet the requirements.

Install the .net Framework

Windows Server 2008 R2

This can is installed as a feature:

  1. Open Server Manager (Start > Administrative Tools > Server manager)
  2. From the left hand pane, click Features
  3. Click Add features
  4. Expand .NET Framework 3.5.1 Features and tick .NET Framework 3.5.1
  5. Click Next
  6. Click Install

Note: a server reboot may be required after .Net framework is installed.

Windows Server 2008

For the original release of Windows Server 2008 you'll need to download and install the .net Framework 3.5 from Microsoft's website.

Customise the script

Very few changes to the script are required although it is important to customise the script to match your environment. To change a value, edit the value after the variable (see the examples below). The default value is beneath the heading.

Security log name

$LogName = "Security"

This is the Windows log that contains details of logon and failed logon attempts. By default on a Windows system this log is called security so it is recommended to leave this at the default (above).

Logging settings

Log name and log source

$WriteLogSource = "PSLogonFailures"
$WriteLog = "Application"

These variables are used to specify what log the script will record its activity to (defaults above). Convention suggests this script should add its log entries to the Application log. You can change the source ($WriteLogSource) to something more meaningful to you if you wish but you must ensure this matches the Source you create under setup the log source.

When to log

$WriteLogStart = 1
$WriteLogEnd = 1

When set to 1, an event is written to the log at the start and end of the script respectively. You can configure this to suit your needs. For example, to only log upon script completion:

$WriteLogStart = 0
$WriteLogEnd = 1

Security events to consider

PSLogonFailures parses the Windows security log (as configured in $LogName) looking for failed login attempts. It's possible to configure the duration of logs that PSLogonFailures reviews and how many failed attempts should be permitted from an IP before blocking it.

Minutes

$minutes = 20

This is the number of minutes of logs to process - i.e. the period in which time an attacker is not permitted to reach the threshold value. This value should be set to a greater value than the repeat frequency of the scheduled task you'll create later.

Threshold value

$threshold = 20

The threshold value is the number of failed logons permitted from an IP address within the time period ($minutes) before the IP is blocked. It is recommended you set this to a value less than your computer's account lockout policy for user accounts, so if a legitimate user is trying to logon they don't lock out their account immediately.

Service configuration

The script can block access to particular services based on your configuration. If you're running Remote Desktop on a custom port you should also define this.

RDP (Remote Desktop) port

$RDPPort = 3389

As mentioned, this script was originally designed to stop attacks against Remote Desktop for which the default port is 3389. If your server listens on a different port then change this value (Note: if your firewall forwards a custom port (e.g. 90) to 3389 on your server, the port here is still 3389).

Choose which services to block

$BlockAll = 0
$BlockWeb = 0
$BlockSMTP = 0
$BlockRWW_RDP = 0

PSLogonFailures will block a number of services (HTTP, HTTPS, SMTP, port 4125 (used for Remote Web Workplace)) which can be used to further limit the attacker's chances against your server. By default, each variable is set to not block (i.e. zero).

$BlockAll = 1

Setting $BlockAll = 1 blocks inbound connections on all TCP ports from the aggressors. Unless there is a valid reason to permit an attacker to continue their access to any other service this may be your best option.

$BlockWeb = 1

Blocks all inbound connections from the agressor's IP to HTTP (port 80) and HTTPS (port 443) of the server.

$BlockSMTP = 1

Prevents inbound connections from the agressor's IP to SMTP (port 25), used by mail servers.

$BlockRWW_RDP = 1

Stops inbound access from the agressor to port 4125, used for Remote Web Workplace (on SBS servers).

Windows firewall profile

$fwprofile = "Any"

The Windows firewall is split into a number of profiles (domain, private, public) and this setting defines which firewall profile the PSLogonFailures rule is applied to. Applying to any is safest as it doesn't matter what profile is in use on the server - it is recommended this be left at Any.

Whitelisting your IPs

$whitelist = 'C:\psl\whitelist.txt'

In order to avoid locking yourself out it's necessary to create a whitelist, which should be at the path defined by this variable.

Then, in your whitelist file, enter 1 IP address per line (ranges are not supported). For example:

192.168.1.1
192.168.1.15
80.1.2.3

Blacklisting persistent attackers

$blacklist = 'C:\psl\blacklist.txt'

In a similar vein to the whitelist, PSLogonFailures allows you to specify a blacklist to persistently block IPs you specify there. Specify the full path to the blacklist text file. As before, IPs should be entered one per line in the file:

99.23.123.34
123.234.233.12

Note: The whitelist is processed before any firewall rules are created so if you accidentally put yourself in the blacklist, the whitelist takes precedence.

Setup the log source

Once the script is customised you need to create the log source on your server. If you have changed the defaults you will need to update the line below to reflect your $WriteLog and $WriteLogSource values. These commands should be typed all on one line and you'll need to be in an elevated command prompt to run these commands successfully.

New-EventLog -LogName "Application" -Source "PSLogonFailures"

If you changed $WriteLogSource to "FirewallScript" then you'd need to change this to:

New-EventLog -LogName "Application" -Source "FirewallScript"

Allow the script to run

By default, Powershell will not allow unsigned scripts to run. The PSLogonFailures script is not signed so you will need to allow these by entering the command below and following the on screen instructions. There is a risk to this so you should consider if bypassing the execution policy is a better option for your environment.

Set-ExecutionPolicy remotesigned

Create a scheduled task

This script works best when automatically run every 10 minutes although you will need to adjust the frequency to suit your environment. Instructions on how to do this were originally adapted from Techhead, although that site no longer exists.

  1. Open the Task Scheduler (Start > Administrative Tools > Task Scheduler).
  2. From the right hand pane click Create Task.
  3. On the General tab:
    • In Name type a meaningful name (e.g. PSLogonFailures Script)
    • Enter a helpful description in the Description field
    • Set the user to run this script as (the user will need to be an administrator of the server) by clicking the Change User or Group button
    • Select Run whether the user is logged on or not
    • Tick Run with highest privileges (very important).
  4. On the Triggers tab:
    • Click New
    • From the begin the task drop down menu choose At startup
    • Tick Repeat task every and choose 10 minutes (adjust to suit) and indefinitely from the drop down boxes
    • Ensure Enabled is ticked
    • Click OK
  5. Create another trigger so the task starts (and repeats) without having to restart, on the triggers tab:
    • Click New
    • From the begin the task drop down menu choose On a schedule
    • Leave the task set to One time and set it to start today in 5 minutes' time (more if you think it will take you more than 5 minutes to setup the tasks)
    • Tick Repeat task every and choose 10 minutes (adjust to suit) and indefinitely from the drop down boxes
    • Ensure Enabled is ticked
    • Click OK
  6. Move to the Actions tab and click New
    • Leave Action as Start a program
    • In Program/script type powershell.exe
    • In Add arguments type –Noninteractive –Noprofile –Command "&{<fullpath to script>}" (e.g. –Noninteractive –Noprofile –Command "&{c:\scripts\PSLogonFailures.ps1}")
    • Click OK
  7. Click OK to create your task.
  8. Press F5 to refresh the list of tasks - you should see your scheduled task present.