2182102I have been administering Windows hosting servers for over 7 years now and one thing that really made me angry is the lack of BASIC security features in Microsoft’s FTP server.

Blocking the IP addresses based on the number of failed login is an ESSENTIAL feature for any FTP server, but it seems Microsoft doesn’t care about that ( until IIS 8 :) )

I swear, when I come to power, I will make that feature obligatory to every FTP server on the market, so…when it comes to that, vote for me! :D

Since I am seeing increasing numbers of brute force attacks in general ( FTP, email servers, application logins, etc… ) we had to come up with some solution that would harden our FTP servers.

I wrote a Powershell script that processes the FTP log file and if it detects over 50 failed logins from a particular IP address, it adds an “Deny” entry it in “FTP IPv4 Address and Domain Restrictions” .

I am running this script every 5 minutes using Scheduled Tasks and it has proven to be quite effective; In 8 hours, script banned over 20 IP addresses :)

ftpblocks

Script is not only Powershell based, but it uses LogParser tool from Microsoft, so in order for the script to work you will need to download the tool and save it in the same folder where your script will be located. You only need to save “LogParser.exe” and “LogParser.dll” in the same folder where your script is.

I have to admit that I am pretty amazed by the speed of the entire script. On my machine, parsing the 100 MB log file takes under 0.5 second, which, you have to admit is pretty awesome :)

 

Let me briefly explain how the script works.

1. Script starts the LogParser tool and searches for the response code “530″ which means that the login failed; Then it saves all IP addresses and the number of logins in the CSV file in the folder c:\work\temp\FTPUserAccountAttempts.csv .

2. Script parses the CSV file and extracts the IP addresses and add them to the “Deny” list in “FTP IPv4 Address and Domain Restrictions” module.

3. Exits :D

So, what do you need in order to get the script running on your machine?

1. Enter the correct pat to your FTP log files in the “$logpath” variable

2. Make sure you have “c:\work\temp” folder created or modify the script.

3. Edit the “-location” in the add-webconfiguration /system.ftpServer/security/ipSecurity -location "IIS:\Sites\FTP" -value @{ipAddress="$ipban";allowed="false"} -pspath IIS:\

My FTP site is called “FTP” . If you have some other name, enter the correct name in “IIS:\Sites\yoursite” .

Okay, we covered the basics,  so here is the code.
Function FTPBlock
{
#SETTINGS
$date = Get-date -Format yMMdd
$logpath = "C:\inetpub\logs\LogFiles\FTPSVC4\u_ex$date.log"
#END SETTINGS
Import-Module "WebAdministration" -ErrorAction Stop
$ErrorActionPreference= 'silentlycontinue'
.\logparser "select c-ip, count(sc-status) INTO c:\work\temp\FTPUserAccountAttempts.csv FROM $logpath where sc-status = '530' group by c-ip HAVING COUNT(*) > 50 order by count(sc-status),c-ip" -e:1 -i w3c -o:CSV
$testpath = Test-Path C:\work\temp\FTPUserAccountAttempts.csv
if ($testpath -eq "true")
{
$ip = Get-Content C:\work\temp\FTPUserAccountAttempts.csv | select -Skip 1
foreach ($_ in $ip)
{
$ip1 = $_.split(",")
$ipban = $ip1[0]
echo $ipban
add-webconfiguration /system.ftpServer/security/ipSecurity -location "IIS:\Sites\FTP" -value @{ipAddress="$ipban";allowed="false"} -pspath IIS:\
}
}
elseif ($testpath -eq "false")
{
exit
}
}
FTPBlock

You can also download the script from HERE.

I am working on the V1.1 version of the script that saves all entries to a SQL database. I am doing that so I can automatically add the blocked IP addresses on all of my machines and have a detailed tracking of the offending IP addresses.  Second feature is automatic cleanup, since I don’t want to hog my FTP server with a huge list of IP addresses.

Happy blocking :)