IIS: Instantly Ban IPs Attempting to Login to MS-FTP as Administrator

UPDATE 12/18/06: The startup script has been modified slightly (cscript.exe was changed to wscript.exe). Now, console users will no longer encounter a blank black box upon login. UPDATE 11/21/06: Now that banning at the IP level has been added to the script, offending users are completely banned before they can even attempt a second login on Windows 2003 machines. Windows 2000 machines still have a slight delay. UPDATE 1/18/07: I updated the code so that it does not throw out an "unknown" error on line 48 for Win2k users. Thanks to the commenters for figuring that out. Also, check the comments for some really great script modification and ideas posted by blog visitors. Thanks to everyone who has posted!

Recently while reviewing my Windows Events, I noticed over 2800 failed login attempts to my Microsoft FTP server. Apparently, a bot was trying to brute force the Administrator password. Thankfully, I soon determined that there were only two IPs I needed to ban. The FTP server needs to be accessed by my employer's clients so I couldn't just change the port (as I did when I found 30,000+ SSH login attempts to my Linux box). Thus, I decided to instantly ban any IPs attempting to login as Administrator. I did this using a VBScript file (saved as: C:\Scripts\Startup\banftpips.vbs) that is set to execute upon boot-up. This can be done like so.

'**************************************************************************** ' This script created by Chrissy LeMaire ([email protected]) ' Website: https://netnerds.net/ ' ' NO WARRANTIES, etc. ' ' This script instantly bans IP addresses trying to login to FTP ' using the NT account "Administrator" ' ' Run this script on the FTP server. It sits in the back and waits for an ' event viewer "push" that lets it know someone failed FTP authentication. ' ' This script has only been tested on Windows Server 2003. It assumes, as it ' should, that there are no legitimate Administrator account FTP logins. ' ' "What it does" ' 1. Sets an Async Event Sink to notify the script when someone fails MS-FTP auth ' 2. When alerted, the script parses the last day's FTP logs for all FTP sites (this ' is because the Event Viewer doesn't tell you which FTP site, if you have more than ' one, is the one getting hit) ' 3. Compiles the list of IPs to be banned and then bans them using IIS /and/ ' IP level banning (thanks Spencer @ netortech.com for the idea) '*****************************************************************************

' Push Event Viewer Alert Set objWMIService = GetObject("winmgmts:{(security)}!root/cimv2") Set eventSink = wscript.CreateObject("WbemScripting.SWbemSink", "EVSINK_") strWQL = "Select * from __InstanceCreationEvent where TargetInstance isa 'Win32_NTLogEvent' and TargetInstance.SourceName = 'MSFTPSVC' and TargetInstance.EventCode = 100" objWMIService.ExecNotificationQueryAsync eventSink,strWQL

' Keep it going forever While (True) Wscript.Sleep(1000) Wend

Sub EVSINK_OnObjectReady(objObject, objAsyncContext) If InStr(LCase(objObject.TargetInstance.Message),"administrator") > 0 Then Set objFTPSVC = GetObject("IIS://localhost/MSFTPSVC") Set WshShell = CreateObject("WScript.Shell") Set objFSO = CreateObject("Scripting.FileSystemObject") Set objLog = CreateObject("MSWC.IISLog") Set objDictionary = CreateObject("Scripting.Dictionary") Set objFTPIPSec = objFTPSVC.IPSecurity

'Get IP address of server so we can use it later to give the offending IP a bad route Set IPConfigSet = GetObject("winmgmts:\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE") for each IPConfig in IPConfigSet if Not IsNull(IPConfig.DefaultIPGateway) then serverIP = IPConfig.IPAddress(0) Next Set IPConfigSet = Nothing

'Iterate through each FTP site. See #2 up above. For Each objSITE in objFTPSVC If lcase(objSITE.class) = "iisftpserver" Then ftpLogFilePath = WshShell.ExpandEnvironmentStrings(objSITE.LogFileDirectory) & "\msftpsvc" & objSITE.Name

Set objFolder = objFSO.GetFolder(ftpLogFilePath) Set objFiles = objFolder.Files For Each fileName In objFiles lastFile = fileName Next strLogFile = lastFile Set file = Nothing Set objFolder = Nothing

'Use the IIS log file parser provided by MSFT objLog.OpenLogFile strLogFile, 1, "MSFTPSVC", 1, 0 '(FileName,IOMode,ServiceName,ServiceInstance,OutputLogFileFormat) ' 0 = NotApplicable, 1 = ForReading While NOT objLog.AtEndOfLog objLog.ReadLogRecord If LCase(objLog.URIStem) = "administrator" Then ClientIP = objLog.ClientIP If objDictionary.Exists(ClientIP) = False Then 'Kill the route to the machine then add it to the array of banned IPs. Set WshShell = WScript.CreateObject("WScript.Shell") WshShell.Run "ROUTE ADD " & clientIP & " MASK 255.255.255.255 " & serverIP, 1, True Set WshShell = Nothing objDictionary.Add ClientIP, "255.255.255.255" '255 is just there for padding. End If End If Wend objLog.CloseLogFiles 1 End If Next

'Append the newly banned IPs to the currently banned IPs If objDictionary.Count > 0 And objFTPIPSec.GrantByDefault = True Then bannedIPArray = objFTPIPSec.IPDeny For i = 0 to ubound(bannedIPArray) clientIP = Left(bannedIPArray(i),InStr(bannedIPArray(i),",")-1) If objDictionary.Exists(ClientIP) = False Then objDictionary.Add bannedIPArray(i), "255.255.255.255" End If Next

objFTPIPSec.IPDeny = objDictionary.Keys objFTPSVC.IPSecurity = objFTPIPSec objFTPSVC.SetInfo End If

Set objFTPIPSec = Nothing Set objDictionary = Nothing Set objLog = Nothing Set objFSO = Nothing Set objFTPSVC = Nothing End If End Sub Once the IP has been added to the ban list, the user will no longer be able to connect to the machine via TCP/IP as it has been given a bad route. If the server reboots, it will lose the route but the IP will still be banned in IIS. The offending user will then see the following message:

Connected to ftpserver 530 Connection refused, unknown IP address. 421 Service not available, closing control connection. Connection closed by remote host.

Note that this bans the IPs on a global FTP level. You will find the banned IPs listed under Windows 2003 @ IIS -> FTP -> Properties and under Windows 2000 @ IIS -> Hostname -> Properties -> FTP Service -> Edit -> Directory Security. This means you will not find it on the properties of the Default FTP Site. This pro-actively bans the IPs from hitting other FTP sites in an IIS setup with multiple FTP sites. In addition, with the new ban at the IP level, the machine can't even contact your server until your Windows server has been rebooted and the manual routes have thus been reset.